From b45d44e7e00c1726dac9437b66c05d3d27acb3f0 Mon Sep 17 00:00:00 2001 From: Nicolas Léveillé Date: Tue, 29 Dec 2009 20:39:05 -0800 Subject: Input: xpad - allow using triggers as buttons rather than axes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Certain devices implement triggers as buttons rather than axes. In particular, arcade sticks such as the HORI Real Arcade Pro.EX do not have analog buttons. These devices are now setup to present buttons rather than axes for triggers. User-space applications often also have problems with axes-as-buttons. Activating MAP_TRIGGERS_TO_BUTTONS for a device removes the artificial difference between buttons and triggers. Signed-off-by: Nicolas Léveillé Signed-off-by: Dmitry Torokhov --- drivers/input/joystick/xpad.c | 200 +++++++++++++++++++++++++----------------- 1 file changed, 121 insertions(+), 79 deletions(-) (limited to 'drivers/input') diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c index 482cb1204e43..5483fb9bd819 100644 --- a/drivers/input/joystick/xpad.c +++ b/drivers/input/joystick/xpad.c @@ -86,9 +86,8 @@ /* xbox d-pads should map to buttons, as is required for DDR pads but we map them to axes when possible to simplify things */ -#define MAP_DPAD_TO_BUTTONS 0 -#define MAP_DPAD_TO_AXES 1 -#define MAP_DPAD_UNKNOWN 2 +#define MAP_DPAD_TO_BUTTONS (1 << 0) +#define MAP_TRIGGERS_TO_BUTTONS (1 << 1) #define XTYPE_XBOX 0 #define XTYPE_XBOX360 1 @@ -99,57 +98,61 @@ static int dpad_to_buttons; module_param(dpad_to_buttons, bool, S_IRUGO); MODULE_PARM_DESC(dpad_to_buttons, "Map D-PAD to buttons rather than axes for unknown pads"); +static int triggers_to_buttons; +module_param(triggers_to_buttons, bool, S_IRUGO); +MODULE_PARM_DESC(triggers_to_buttons, "Map triggers to buttons rather than axes for unknown pads"); + static const struct xpad_device { u16 idVendor; u16 idProduct; char *name; - u8 dpad_mapping; + u8 mapping; u8 xtype; } xpad_device[] = { - { 0x045e, 0x0202, "Microsoft X-Box pad v1 (US)", MAP_DPAD_TO_AXES, XTYPE_XBOX }, - { 0x045e, 0x0289, "Microsoft X-Box pad v2 (US)", MAP_DPAD_TO_AXES, XTYPE_XBOX }, - { 0x045e, 0x0285, "Microsoft X-Box pad (Japan)", MAP_DPAD_TO_AXES, XTYPE_XBOX }, - { 0x045e, 0x0287, "Microsoft Xbox Controller S", MAP_DPAD_TO_AXES, XTYPE_XBOX }, + { 0x045e, 0x0202, "Microsoft X-Box pad v1 (US)", 0, XTYPE_XBOX }, + { 0x045e, 0x0289, "Microsoft X-Box pad v2 (US)", 0, XTYPE_XBOX }, + { 0x045e, 0x0285, "Microsoft X-Box pad (Japan)", 0, XTYPE_XBOX }, + { 0x045e, 0x0287, "Microsoft Xbox Controller S", 0, XTYPE_XBOX }, { 0x045e, 0x0719, "Xbox 360 Wireless Receiver", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX360W }, { 0x0c12, 0x8809, "RedOctane Xbox Dance Pad", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX }, - { 0x044f, 0x0f07, "Thrustmaster, Inc. Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX }, - { 0x046d, 0xc242, "Logitech Chillstream Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX360 }, - { 0x046d, 0xca84, "Logitech Xbox Cordless Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX }, - { 0x046d, 0xca88, "Logitech Compact Controller for Xbox", MAP_DPAD_TO_AXES, XTYPE_XBOX }, - { 0x05fd, 0x1007, "Mad Catz Controller (unverified)", MAP_DPAD_TO_AXES, XTYPE_XBOX }, - { 0x05fd, 0x107a, "InterAct 'PowerPad Pro' X-Box pad (Germany)", MAP_DPAD_TO_AXES, XTYPE_XBOX }, - { 0x0738, 0x4516, "Mad Catz Control Pad", MAP_DPAD_TO_AXES, XTYPE_XBOX }, - { 0x0738, 0x4522, "Mad Catz LumiCON", MAP_DPAD_TO_AXES, XTYPE_XBOX }, - { 0x0738, 0x4526, "Mad Catz Control Pad Pro", MAP_DPAD_TO_AXES, XTYPE_XBOX }, - { 0x0738, 0x4536, "Mad Catz MicroCON", MAP_DPAD_TO_AXES, XTYPE_XBOX }, + { 0x044f, 0x0f07, "Thrustmaster, Inc. Controller", 0, XTYPE_XBOX }, + { 0x046d, 0xc242, "Logitech Chillstream Controller", 0, XTYPE_XBOX360 }, + { 0x046d, 0xca84, "Logitech Xbox Cordless Controller", 0, XTYPE_XBOX }, + { 0x046d, 0xca88, "Logitech Compact Controller for Xbox", 0, XTYPE_XBOX }, + { 0x05fd, 0x1007, "Mad Catz Controller (unverified)", 0, XTYPE_XBOX }, + { 0x05fd, 0x107a, "InterAct 'PowerPad Pro' X-Box pad (Germany)", 0, XTYPE_XBOX }, + { 0x0738, 0x4516, "Mad Catz Control Pad", 0, XTYPE_XBOX }, + { 0x0738, 0x4522, "Mad Catz LumiCON", 0, XTYPE_XBOX }, + { 0x0738, 0x4526, "Mad Catz Control Pad Pro", 0, XTYPE_XBOX }, + { 0x0738, 0x4536, "Mad Catz MicroCON", 0, XTYPE_XBOX }, { 0x0738, 0x4540, "Mad Catz Beat Pad", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX }, - { 0x0738, 0x4556, "Mad Catz Lynx Wireless Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX }, - { 0x0738, 0x4716, "Mad Catz Wired Xbox 360 Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX360 }, - { 0x0738, 0x4738, "Mad Catz Wired Xbox 360 Controller (SFIV)", MAP_DPAD_TO_AXES, XTYPE_XBOX360 }, + { 0x0738, 0x4556, "Mad Catz Lynx Wireless Controller", 0, XTYPE_XBOX }, + { 0x0738, 0x4716, "Mad Catz Wired Xbox 360 Controller", 0, XTYPE_XBOX360 }, + { 0x0738, 0x4738, "Mad Catz Wired Xbox 360 Controller (SFIV)", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX360 }, { 0x0738, 0x6040, "Mad Catz Beat Pad Pro", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX }, - { 0x0c12, 0x8802, "Zeroplus Xbox Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX }, - { 0x0c12, 0x880a, "Pelican Eclipse PL-2023", MAP_DPAD_TO_AXES, XTYPE_XBOX }, - { 0x0c12, 0x8810, "Zeroplus Xbox Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX }, - { 0x0c12, 0x9902, "HAMA VibraX - *FAULTY HARDWARE*", MAP_DPAD_TO_AXES, XTYPE_XBOX }, - { 0x0e4c, 0x1097, "Radica Gamester Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX }, - { 0x0e4c, 0x2390, "Radica Games Jtech Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX }, - { 0x0e6f, 0x0003, "Logic3 Freebird wireless Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX }, - { 0x0e6f, 0x0005, "Eclipse wireless Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX }, - { 0x0e6f, 0x0006, "Edge wireless Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX }, - { 0x0e6f, 0x0006, "Pelican 'TSZ' Wired Xbox 360 Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX360 }, - { 0x0e8f, 0x0201, "SmartJoy Frag Xpad/PS2 adaptor", MAP_DPAD_TO_AXES, XTYPE_XBOX }, - { 0x0f30, 0x0202, "Joytech Advanced Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX }, - { 0x0f30, 0x8888, "BigBen XBMiniPad Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX }, - { 0x102c, 0xff0c, "Joytech Wireless Advanced Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX }, + { 0x0c12, 0x8802, "Zeroplus Xbox Controller", 0, XTYPE_XBOX }, + { 0x0c12, 0x880a, "Pelican Eclipse PL-2023", 0, XTYPE_XBOX }, + { 0x0c12, 0x8810, "Zeroplus Xbox Controller", 0, XTYPE_XBOX }, + { 0x0c12, 0x9902, "HAMA VibraX - *FAULTY HARDWARE*", 0, XTYPE_XBOX }, + { 0x0e4c, 0x1097, "Radica Gamester Controller", 0, XTYPE_XBOX }, + { 0x0e4c, 0x2390, "Radica Games Jtech Controller", 0, XTYPE_XBOX }, + { 0x0e6f, 0x0003, "Logic3 Freebird wireless Controller", 0, XTYPE_XBOX }, + { 0x0e6f, 0x0005, "Eclipse wireless Controller", 0, XTYPE_XBOX }, + { 0x0e6f, 0x0006, "Edge wireless Controller", 0, XTYPE_XBOX }, + { 0x0e6f, 0x0006, "Pelican 'TSZ' Wired Xbox 360 Controller", 0, XTYPE_XBOX360 }, + { 0x0e8f, 0x0201, "SmartJoy Frag Xpad/PS2 adaptor", 0, XTYPE_XBOX }, + { 0x0f30, 0x0202, "Joytech Advanced Controller", 0, XTYPE_XBOX }, + { 0x0f30, 0x8888, "BigBen XBMiniPad Controller", 0, XTYPE_XBOX }, + { 0x102c, 0xff0c, "Joytech Wireless Advanced Controller", 0, XTYPE_XBOX }, { 0x12ab, 0x8809, "Xbox DDR dancepad", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX }, - { 0x1430, 0x4748, "RedOctane Guitar Hero X-plorer", MAP_DPAD_TO_AXES, XTYPE_XBOX360 }, + { 0x1430, 0x4748, "RedOctane Guitar Hero X-plorer", 0, XTYPE_XBOX360 }, { 0x1430, 0x8888, "TX6500+ Dance Pad (first generation)", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX }, - { 0x146b, 0x0601, "BigBen Interactive XBOX 360 Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX360 }, - { 0x045e, 0x028e, "Microsoft X-Box 360 pad", MAP_DPAD_TO_AXES, XTYPE_XBOX360 }, + { 0x146b, 0x0601, "BigBen Interactive XBOX 360 Controller", 0, XTYPE_XBOX360 }, + { 0x045e, 0x028e, "Microsoft X-Box 360 pad", 0, XTYPE_XBOX360 }, { 0x1bad, 0x0003, "Harmonix Rock Band Drumkit", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX360 }, - { 0x0f0d, 0x0016, "Hori Real Arcade Pro.EX", MAP_DPAD_TO_AXES, XTYPE_XBOX360 }, - { 0xffff, 0xffff, "Chinese-made Xbox Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX }, - { 0x0000, 0x0000, "Generic X-Box pad", MAP_DPAD_UNKNOWN, XTYPE_UNKNOWN } + { 0x0f0d, 0x0016, "Hori Real Arcade Pro.EX", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX360 }, + { 0xffff, 0xffff, "Chinese-made Xbox Controller", 0, XTYPE_XBOX }, + { 0x0000, 0x0000, "Generic X-Box pad", 0, XTYPE_UNKNOWN } }; /* buttons shared with xbox and xbox360 */ @@ -165,13 +168,20 @@ static const signed short xpad_btn[] = { -1 /* terminating entry */ }; -/* only used if MAP_DPAD_TO_BUTTONS */ +/* used when dpad is mapped to nuttons */ static const signed short xpad_btn_pad[] = { BTN_LEFT, BTN_RIGHT, /* d-pad left, right */ BTN_0, BTN_1, /* d-pad up, down (XXX names??) */ -1 /* terminating entry */ }; +/* used when triggers are mapped to buttons */ +static const signed short xpad_btn_triggers[] = { + BTN_TL2, BTN_TR2, /* triggers left/right */ + -1 +}; + + static const signed short xpad360_btn[] = { /* buttons for x360 controller */ BTN_TL, BTN_TR, /* Button LB/RB */ BTN_MODE, /* The big X button */ @@ -181,16 +191,21 @@ static const signed short xpad360_btn[] = { /* buttons for x360 controller */ static const signed short xpad_abs[] = { ABS_X, ABS_Y, /* left stick */ ABS_RX, ABS_RY, /* right stick */ - ABS_Z, ABS_RZ, /* triggers left/right */ -1 /* terminating entry */ }; -/* only used if MAP_DPAD_TO_AXES */ +/* used when dpad is mapped to axes */ static const signed short xpad_abs_pad[] = { ABS_HAT0X, ABS_HAT0Y, /* d-pad axes */ -1 /* terminating entry */ }; +/* used when triggers are mapped to axes */ +static const signed short xpad_abs_triggers[] = { + ABS_Z, ABS_RZ, /* triggers left/right */ + -1 +}; + /* Xbox 360 has a vendor-specific class, so we cannot match it with only * USB_INTERFACE_INFO (also specifically refused by USB subsystem), so we * match against vendor id as well. Wired Xbox 360 devices have protocol 1, @@ -246,7 +261,7 @@ struct usb_xpad { char phys[64]; /* physical device path */ - int dpad_mapping; /* map d-pad to buttons or to axes */ + int mapping; /* map d-pad to buttons or to axes */ int xtype; /* type of xbox device */ }; @@ -277,20 +292,25 @@ static void xpad_process_packet(struct usb_xpad *xpad, u16 cmd, unsigned char *d ~(__s16) le16_to_cpup((__le16 *)(data + 18))); /* triggers left/right */ - input_report_abs(dev, ABS_Z, data[10]); - input_report_abs(dev, ABS_RZ, data[11]); + if (xpad->mapping & MAP_TRIGGERS_TO_BUTTONS) { + input_report_key(dev, BTN_TL2, data[10]); + input_report_key(dev, BTN_TR2, data[11]); + } else { + input_report_abs(dev, ABS_Z, data[10]); + input_report_abs(dev, ABS_RZ, data[11]); + } /* digital pad */ - if (xpad->dpad_mapping == MAP_DPAD_TO_AXES) { - input_report_abs(dev, ABS_HAT0X, - !!(data[2] & 0x08) - !!(data[2] & 0x04)); - input_report_abs(dev, ABS_HAT0Y, - !!(data[2] & 0x02) - !!(data[2] & 0x01)); - } else /* xpad->dpad_mapping == MAP_DPAD_TO_BUTTONS */ { + if (xpad->mapping & MAP_DPAD_TO_BUTTONS) { input_report_key(dev, BTN_LEFT, data[2] & 0x04); input_report_key(dev, BTN_RIGHT, data[2] & 0x08); input_report_key(dev, BTN_0, data[2] & 0x01); /* up */ input_report_key(dev, BTN_1, data[2] & 0x02); /* down */ + } else { + input_report_abs(dev, ABS_HAT0X, + !!(data[2] & 0x08) - !!(data[2] & 0x04)); + input_report_abs(dev, ABS_HAT0Y, + !!(data[2] & 0x02) - !!(data[2] & 0x01)); } /* start/back buttons and stick press left/right */ @@ -328,17 +348,17 @@ static void xpad360_process_packet(struct usb_xpad *xpad, struct input_dev *dev = xpad->dev; /* digital pad */ - if (xpad->dpad_mapping == MAP_DPAD_TO_AXES) { - input_report_abs(dev, ABS_HAT0X, - !!(data[2] & 0x08) - !!(data[2] & 0x04)); - input_report_abs(dev, ABS_HAT0Y, - !!(data[2] & 0x02) - !!(data[2] & 0x01)); - } else if (xpad->dpad_mapping == MAP_DPAD_TO_BUTTONS) { + if (xpad->mapping & MAP_DPAD_TO_BUTTONS) { /* dpad as buttons (right, left, down, up) */ input_report_key(dev, BTN_LEFT, data[2] & 0x04); input_report_key(dev, BTN_RIGHT, data[2] & 0x08); input_report_key(dev, BTN_0, data[2] & 0x01); /* up */ input_report_key(dev, BTN_1, data[2] & 0x02); /* down */ + } else { + input_report_abs(dev, ABS_HAT0X, + !!(data[2] & 0x08) - !!(data[2] & 0x04)); + input_report_abs(dev, ABS_HAT0Y, + !!(data[2] & 0x02) - !!(data[2] & 0x01)); } /* start/back buttons */ @@ -371,8 +391,13 @@ static void xpad360_process_packet(struct usb_xpad *xpad, ~(__s16) le16_to_cpup((__le16 *)(data + 12))); /* triggers left/right */ - input_report_abs(dev, ABS_Z, data[4]); - input_report_abs(dev, ABS_RZ, data[5]); + if (xpad->mapping & MAP_TRIGGERS_TO_BUTTONS) { + input_report_key(dev, BTN_TL2, data[4]); + input_report_key(dev, BTN_TR2, data[5]); + } else { + input_report_abs(dev, ABS_Z, data[4]); + input_report_abs(dev, ABS_RZ, data[5]); + } input_sync(dev); } @@ -712,11 +737,11 @@ static void xpad_set_up_abs(struct input_dev *input_dev, signed short abs) input_set_abs_params(input_dev, abs, -32768, 32767, 16, 128); break; case ABS_Z: - case ABS_RZ: /* the triggers */ + case ABS_RZ: /* the triggers (if mapped to axes) */ input_set_abs_params(input_dev, abs, 0, 255, 0, 0); break; case ABS_HAT0X: - case ABS_HAT0Y: /* the d-pad (only if MAP_DPAD_TO_AXES) */ + case ABS_HAT0Y: /* the d-pad (only if dpad is mapped to axes */ input_set_abs_params(input_dev, abs, -1, 1, 0, 0); break; } @@ -752,10 +777,9 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id goto fail2; xpad->udev = udev; - xpad->dpad_mapping = xpad_device[i].dpad_mapping; + xpad->mapping = xpad_device[i].mapping; xpad->xtype = xpad_device[i].xtype; - if (xpad->dpad_mapping == MAP_DPAD_UNKNOWN) - xpad->dpad_mapping = !dpad_to_buttons; + if (xpad->xtype == XTYPE_UNKNOWN) { if (intf->cur_altsetting->desc.bInterfaceClass == USB_CLASS_VENDOR_SPEC) { if (intf->cur_altsetting->desc.bInterfaceProtocol == 129) @@ -764,7 +788,13 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id xpad->xtype = XTYPE_XBOX360; } else xpad->xtype = XTYPE_XBOX; + + if (dpad_to_buttons) + xpad->mapping |= MAP_DPAD_TO_BUTTONS; + if (triggers_to_buttons) + xpad->mapping |= MAP_TRIGGERS_TO_BUTTONS; } + xpad->dev = input_dev; usb_make_path(udev, xpad->phys, sizeof(xpad->phys)); strlcat(xpad->phys, "/input0", sizeof(xpad->phys)); @@ -781,25 +811,37 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); - /* set up buttons */ + /* set up standard buttons and axes */ for (i = 0; xpad_common_btn[i] >= 0; i++) - set_bit(xpad_common_btn[i], input_dev->keybit); - if ((xpad->xtype == XTYPE_XBOX360) || (xpad->xtype == XTYPE_XBOX360W)) - for (i = 0; xpad360_btn[i] >= 0; i++) - set_bit(xpad360_btn[i], input_dev->keybit); - else - for (i = 0; xpad_btn[i] >= 0; i++) - set_bit(xpad_btn[i], input_dev->keybit); - if (xpad->dpad_mapping == MAP_DPAD_TO_BUTTONS) - for (i = 0; xpad_btn_pad[i] >= 0; i++) - set_bit(xpad_btn_pad[i], input_dev->keybit); + __set_bit(xpad_common_btn[i], input_dev->keybit); - /* set up axes */ for (i = 0; xpad_abs[i] >= 0; i++) xpad_set_up_abs(input_dev, xpad_abs[i]); - if (xpad->dpad_mapping == MAP_DPAD_TO_AXES) + + /* Now set up model-specific ones */ + if (xpad->xtype == XTYPE_XBOX360 || xpad->xtype == XTYPE_XBOX360W) { + for (i = 0; xpad360_btn[i] >= 0; i++) + __set_bit(xpad360_btn[i], input_dev->keybit); + } else { + for (i = 0; xpad_btn[i] >= 0; i++) + __set_bit(xpad_btn[i], input_dev->keybit); + } + + if (xpad->mapping & MAP_DPAD_TO_BUTTONS) { + for (i = 0; xpad_btn_pad[i] >= 0; i++) + __set_bit(xpad_btn_pad[i], input_dev->keybit); + } else { for (i = 0; xpad_abs_pad[i] >= 0; i++) xpad_set_up_abs(input_dev, xpad_abs_pad[i]); + } + + if (xpad->mapping & MAP_TRIGGERS_TO_BUTTONS) { + for (i = 0; xpad_btn_triggers[i] >= 0; i++) + __set_bit(xpad_btn_triggers[i], input_dev->keybit); + } else { + for (i = 0; xpad_abs_triggers[i] >= 0; i++) + xpad_set_up_abs(input_dev, xpad_abs_triggers[i]); + } error = xpad_init_output(intf, xpad); if (error) -- cgit v1.2.3 From 386d8772980be01b94bd463ea1e745732d7eb502 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Tue, 5 Jan 2010 17:56:03 -0800 Subject: Input: serio - use device core to create 'id' attribute group Instead of creating 'id' sysfs attribute group by ourselves rely on device core to do that for us. Signed-off-by: Dmitry Torokhov --- drivers/input/serio/serio.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) (limited to 'drivers/input') diff --git a/drivers/input/serio/serio.c b/drivers/input/serio/serio.c index 0236f0d5fd91..0a278f9f1d3a 100644 --- a/drivers/input/serio/serio.c +++ b/drivers/input/serio/serio.c @@ -452,6 +452,11 @@ static struct attribute_group serio_id_attr_group = { .attrs = serio_device_id_attrs, }; +static const struct attribute_group *serio_device_attr_groups[] = { + &serio_id_attr_group, + NULL +}; + static ssize_t serio_rebind_driver(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct serio *serio = to_serio_port(dev); @@ -539,6 +544,7 @@ static void serio_init_port(struct serio *serio) (long)atomic_inc_return(&serio_no) - 1); serio->dev.bus = &serio_bus; serio->dev.release = serio_release_port; + serio->dev.groups = serio_device_attr_groups; if (serio->parent) { serio->dev.parent = &serio->parent->dev; serio->depth = serio->parent->depth + 1; @@ -562,21 +568,17 @@ static void serio_add_port(struct serio *serio) } list_add_tail(&serio->node, &serio_list); + if (serio->start) serio->start(serio); + error = device_add(&serio->dev); if (error) printk(KERN_ERR "serio: device_add() failed for %s (%s), error: %d\n", serio->phys, serio->name, error); - else { + else serio->registered = true; - error = sysfs_create_group(&serio->dev.kobj, &serio_id_attr_group); - if (error) - printk(KERN_ERR - "serio: sysfs_create_group() failed for %s (%s), error: %d\n", - serio->phys, serio->name, error); - } } /* @@ -604,7 +606,6 @@ static void serio_destroy_port(struct serio *serio) } if (serio->registered) { - sysfs_remove_group(&serio->dev.kobj, &serio_id_attr_group); device_del(&serio->dev); serio->registered = false; } -- cgit v1.2.3 From ddf1ffbd40c92ff1e58c45fa96d309788f7beb60 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Tue, 5 Jan 2010 17:56:04 -0800 Subject: Input: serio - let device core tell us if device was registered No need to keep track of it by ourselves. Signed-off-by: Dmitry Torokhov --- drivers/input/serio/serio.c | 8 ++------ include/linux/serio.h | 1 - 2 files changed, 2 insertions(+), 7 deletions(-) (limited to 'drivers/input') diff --git a/drivers/input/serio/serio.c b/drivers/input/serio/serio.c index 0a278f9f1d3a..d89880450f77 100644 --- a/drivers/input/serio/serio.c +++ b/drivers/input/serio/serio.c @@ -577,8 +577,6 @@ static void serio_add_port(struct serio *serio) printk(KERN_ERR "serio: device_add() failed for %s (%s), error: %d\n", serio->phys, serio->name, error); - else - serio->registered = true; } /* @@ -605,10 +603,8 @@ static void serio_destroy_port(struct serio *serio) serio->parent = NULL; } - if (serio->registered) { + if (device_is_registered(&serio->dev)) device_del(&serio->dev); - serio->registered = false; - } list_del_init(&serio->node); serio_remove_pending_events(serio); @@ -995,7 +991,7 @@ irqreturn_t serio_interrupt(struct serio *serio, if (likely(serio->drv)) { ret = serio->drv->interrupt(serio, data, dfl); - } else if (!dfl && serio->registered) { + } else if (!dfl && device_is_registered(&serio->dev)) { serio_rescan(serio); ret = IRQ_HANDLED; } diff --git a/include/linux/serio.h b/include/linux/serio.h index e2f3044d4a4a..d0fb702059cd 100644 --- a/include/linux/serio.h +++ b/include/linux/serio.h @@ -30,7 +30,6 @@ struct serio { char phys[32]; bool manual_bind; - bool registered; /* port has been fully registered with driver core */ struct serio_device_id id; -- cgit v1.2.3 From 4516c8183213b59c3645d810ccb04b70c2606743 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Tue, 5 Jan 2010 17:56:04 -0800 Subject: Input: serio - use list_first_entry() helper Signed-off-by: Dmitry Torokhov --- drivers/input/serio/serio.c | 31 +++++++++++-------------------- 1 file changed, 11 insertions(+), 20 deletions(-) (limited to 'drivers/input') diff --git a/drivers/input/serio/serio.c b/drivers/input/serio/serio.c index d89880450f77..7fbf7670ae09 100644 --- a/drivers/input/serio/serio.c +++ b/drivers/input/serio/serio.c @@ -230,14 +230,12 @@ static void serio_free_event(struct serio_event *event) static void serio_remove_duplicate_events(struct serio_event *event) { - struct list_head *node, *next; - struct serio_event *e; + struct serio_event *e, *next; unsigned long flags; spin_lock_irqsave(&serio_event_lock, flags); - list_for_each_safe(node, next, &serio_event_list) { - e = list_entry(node, struct serio_event, node); + list_for_each_entry_safe(e, next, &serio_event_list, node) { if (event->object == e->object) { /* * If this event is of different type we should not @@ -247,7 +245,7 @@ static void serio_remove_duplicate_events(struct serio_event *event) if (event->type != e->type) break; - list_del_init(node); + list_del_init(&e->node); serio_free_event(e); } } @@ -258,23 +256,18 @@ static void serio_remove_duplicate_events(struct serio_event *event) static struct serio_event *serio_get_event(void) { - struct serio_event *event; - struct list_head *node; + struct serio_event *event = NULL; unsigned long flags; spin_lock_irqsave(&serio_event_lock, flags); - if (list_empty(&serio_event_list)) { - spin_unlock_irqrestore(&serio_event_lock, flags); - return NULL; + if (!list_empty(&serio_event_list)) { + event = list_first_entry(&serio_event_list, + struct serio_event, node); + list_del_init(&event->node); } - node = serio_event_list.next; - event = list_entry(node, struct serio_event, node); - list_del_init(node); - spin_unlock_irqrestore(&serio_event_lock, flags); - return event; } @@ -331,16 +324,14 @@ static void serio_handle_event(void) */ static void serio_remove_pending_events(void *object) { - struct list_head *node, *next; - struct serio_event *event; + struct serio_event *event, *next; unsigned long flags; spin_lock_irqsave(&serio_event_lock, flags); - list_for_each_safe(node, next, &serio_event_list) { - event = list_entry(node, struct serio_event, node); + list_for_each_entry_safe(event, next, &serio_event_list, node) { if (event->object == object) { - list_del_init(node); + list_del_init(&event->node); serio_free_event(event); } } -- cgit v1.2.3 From cac9169bf75ea8cbaab75be9dbe5eb79a2bad6f5 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Tue, 5 Jan 2010 17:56:04 -0800 Subject: Input: serio - use pr_xxx() and dev_xxx() helpers pr_xxx() and dev_xxx() helpers ensure that all messages emitted by the module have consistent prefixes, so let's use them. Also fix some formatting issues. Signed-off-by: Dmitry Torokhov --- drivers/input/serio/serio.c | 77 +++++++++++++++++++++------------------------ 1 file changed, 35 insertions(+), 42 deletions(-) (limited to 'drivers/input') diff --git a/drivers/input/serio/serio.c b/drivers/input/serio/serio.c index 7fbf7670ae09..ee69ec399e08 100644 --- a/drivers/input/serio/serio.c +++ b/drivers/input/serio/serio.c @@ -26,6 +26,8 @@ * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include @@ -119,11 +121,10 @@ static int serio_bind_driver(struct serio *serio, struct serio_driver *drv) error = device_bind_driver(&serio->dev); if (error) { - printk(KERN_WARNING - "serio: device_bind_driver() failed " - "for %s (%s) and %s, error: %d\n", - serio->phys, serio->name, - drv->description, error); + dev_warn(&serio->dev, + "device_bind_driver() failed for %s (%s) and %s, error: %d\n", + serio->phys, serio->name, + drv->description, error); serio_disconnect_driver(serio); serio->dev.driver = NULL; return error; @@ -138,9 +139,9 @@ static void serio_find_driver(struct serio *serio) error = device_attach(&serio->dev); if (error < 0) - printk(KERN_WARNING - "serio: device_attach() failed for %s (%s), error: %d\n", - serio->phys, serio->name, error); + dev_warn(&serio->dev, + "device_attach() failed for %s (%s), error: %d\n", + serio->phys, serio->name, error); } @@ -194,17 +195,14 @@ static int serio_queue_event(void *object, struct module *owner, event = kmalloc(sizeof(struct serio_event), GFP_ATOMIC); if (!event) { - printk(KERN_ERR - "serio: Not enough memory to queue event %d\n", - event_type); + pr_err("Not enough memory to queue event %d\n", event_type); retval = -ENOMEM; goto out; } if (!try_module_get(owner)) { - printk(KERN_WARNING - "serio: Can't get module reference, dropping event %d\n", - event_type); + pr_warning("Can't get module reference, dropping event %d\n", + event_type); kfree(event); retval = -EINVAL; goto out; @@ -286,29 +284,27 @@ static void serio_handle_event(void) if ((event = serio_get_event())) { switch (event->type) { - case SERIO_REGISTER_PORT: - serio_add_port(event->object); - break; - case SERIO_RECONNECT_PORT: - serio_reconnect_port(event->object); - break; + case SERIO_REGISTER_PORT: + serio_add_port(event->object); + break; - case SERIO_RESCAN_PORT: - serio_disconnect_port(event->object); - serio_find_driver(event->object); - break; + case SERIO_RECONNECT_PORT: + serio_reconnect_port(event->object); + break; - case SERIO_RECONNECT_CHAIN: - serio_reconnect_chain(event->object); - break; + case SERIO_RESCAN_PORT: + serio_disconnect_port(event->object); + serio_find_driver(event->object); + break; - case SERIO_ATTACH_DRIVER: - serio_attach_driver(event->object); - break; + case SERIO_RECONNECT_CHAIN: + serio_reconnect_chain(event->object); + break; - default: - break; + case SERIO_ATTACH_DRIVER: + serio_attach_driver(event->object); + break; } serio_remove_duplicate_events(event); @@ -378,7 +374,6 @@ static int serio_thread(void *nothing) kthread_should_stop() || !list_empty(&serio_event_list)); } while (!kthread_should_stop()); - printk(KERN_DEBUG "serio: kseriod exiting\n"); return 0; } @@ -565,8 +560,8 @@ static void serio_add_port(struct serio *serio) error = device_add(&serio->dev); if (error) - printk(KERN_ERR - "serio: device_add() failed for %s (%s), error: %d\n", + dev_err(&serio->dev, + "device_add() failed for %s (%s), error: %d\n", serio->phys, serio->name, error); } @@ -793,9 +788,8 @@ static void serio_attach_driver(struct serio_driver *drv) error = driver_attach(&drv->driver); if (error) - printk(KERN_WARNING - "serio: driver_attach() failed for %s with error %d\n", - drv->driver.name, error); + pr_warning("driver_attach() failed for %s with error %d\n", + drv->driver.name, error); } int __serio_register_driver(struct serio_driver *drv, struct module *owner, const char *mod_name) @@ -815,8 +809,7 @@ int __serio_register_driver(struct serio_driver *drv, struct module *owner, cons error = driver_register(&drv->driver); if (error) { - printk(KERN_ERR - "serio: driver_register() failed for %s, error: %d\n", + pr_err("driver_register() failed for %s, error: %d\n", drv->driver.name, error); return error; } @@ -1013,7 +1006,7 @@ static int __init serio_init(void) error = bus_register(&serio_bus); if (error) { - printk(KERN_ERR "serio: failed to register serio bus, error: %d\n", error); + pr_err("Failed to register serio bus, error: %d\n", error); return error; } @@ -1021,7 +1014,7 @@ static int __init serio_init(void) if (IS_ERR(serio_task)) { bus_unregister(&serio_bus); error = PTR_ERR(serio_task); - printk(KERN_ERR "serio: Failed to start kseriod, error: %d\n", error); + pr_err("Failed to start kseriod, error: %d\n", error); return error; } -- cgit v1.2.3 From 361b7b5b032338361ea88412f1fc45479fdd5859 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Tue, 5 Jan 2010 17:56:03 -0800 Subject: Input: gameport - let device core tell us if device was registered No need to keep track of it by ourselves. Signed-off-by: Dmitry Torokhov --- drivers/input/gameport/gameport.c | 6 +----- include/linux/gameport.h | 1 - 2 files changed, 1 insertion(+), 6 deletions(-) (limited to 'drivers/input') diff --git a/drivers/input/gameport/gameport.c b/drivers/input/gameport/gameport.c index ac11be08585e..f9e5f8e1690b 100644 --- a/drivers/input/gameport/gameport.c +++ b/drivers/input/gameport/gameport.c @@ -561,8 +561,6 @@ static void gameport_add_port(struct gameport *gameport) printk(KERN_ERR "gameport: device_add() failed for %s (%s), error: %d\n", gameport->phys, gameport->name, error); - else - gameport->registered = 1; } /* @@ -584,10 +582,8 @@ static void gameport_destroy_port(struct gameport *gameport) gameport->parent = NULL; } - if (gameport->registered) { + if (device_is_registered(&gameport->dev)) device_del(&gameport->dev); - gameport->registered = 0; - } list_del_init(&gameport->node); diff --git a/include/linux/gameport.h b/include/linux/gameport.h index 1bc08541c2b9..48e68da097f6 100644 --- a/include/linux/gameport.h +++ b/include/linux/gameport.h @@ -46,7 +46,6 @@ struct gameport { struct mutex drv_mutex; /* protects serio->drv so attributes can pin driver */ struct device dev; - unsigned int registered; /* port has been fully registered with driver core */ struct list_head node; }; -- cgit v1.2.3 From d621af473079851caac873adc5431a05c9d78dfd Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Tue, 5 Jan 2010 17:56:03 -0800 Subject: Input: gameport - make use of list_first_entry() helper Signed-off-by: Dmitry Torokhov --- drivers/input/gameport/gameport.c | 30 +++++++++++------------------- 1 file changed, 11 insertions(+), 19 deletions(-) (limited to 'drivers/input') diff --git a/drivers/input/gameport/gameport.c b/drivers/input/gameport/gameport.c index f9e5f8e1690b..953a20bf26e8 100644 --- a/drivers/input/gameport/gameport.c +++ b/drivers/input/gameport/gameport.c @@ -298,14 +298,12 @@ static void gameport_free_event(struct gameport_event *event) static void gameport_remove_duplicate_events(struct gameport_event *event) { - struct list_head *node, *next; - struct gameport_event *e; + struct gameport_event *e, *next; unsigned long flags; spin_lock_irqsave(&gameport_event_lock, flags); - list_for_each_safe(node, next, &gameport_event_list) { - e = list_entry(node, struct gameport_event, node); + list_for_each_entry_safe(e, next, &gameport_event_list, node) { if (event->object == e->object) { /* * If this event is of different type we should not @@ -315,7 +313,7 @@ static void gameport_remove_duplicate_events(struct gameport_event *event) if (event->type != e->type) break; - list_del_init(node); + list_del_init(&e->node); gameport_free_event(e); } } @@ -325,21 +323,17 @@ static void gameport_remove_duplicate_events(struct gameport_event *event) static struct gameport_event *gameport_get_event(void) { - struct gameport_event *event; - struct list_head *node; + struct gameport_event *event = NULL; unsigned long flags; spin_lock_irqsave(&gameport_event_lock, flags); - if (list_empty(&gameport_event_list)) { - spin_unlock_irqrestore(&gameport_event_lock, flags); - return NULL; + if (!list_empty(&gameport_event_list)) { + event = list_first_entry(&gameport_event_list, + struct gameport_event, node); + list_del_init(&event->node); } - node = gameport_event_list.next; - event = list_entry(node, struct gameport_event, node); - list_del_init(node); - spin_unlock_irqrestore(&gameport_event_lock, flags); return event; @@ -385,16 +379,14 @@ static void gameport_handle_event(void) */ static void gameport_remove_pending_events(void *object) { - struct list_head *node, *next; - struct gameport_event *event; + struct gameport_event *event, *next; unsigned long flags; spin_lock_irqsave(&gameport_event_lock, flags); - list_for_each_safe(node, next, &gameport_event_list) { - event = list_entry(node, struct gameport_event, node); + list_for_each_entry_safe(event, next, &gameport_event_list, node) { if (event->object == object) { - list_del_init(node); + list_del_init(&event->node); gameport_free_event(event); } } -- cgit v1.2.3 From fc99ec6f4b6116305bca56a781b8b3b2ac054d27 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Tue, 5 Jan 2010 17:56:03 -0800 Subject: Input: gameport - switch to using pr_xxx() and dev_xxx() pr_xxx() and dev_xxx() helpers ensure that all messages emitted by the module have consistent prefixes, so let's use them. Also fix some formatting issues. Signed-off-by: Dmitry Torokhov --- drivers/input/gameport/gameport.c | 62 ++++++++++++++++++--------------------- 1 file changed, 28 insertions(+), 34 deletions(-) (limited to 'drivers/input') diff --git a/drivers/input/gameport/gameport.c b/drivers/input/gameport/gameport.c index 953a20bf26e8..7e18bcf05a66 100644 --- a/drivers/input/gameport/gameport.c +++ b/drivers/input/gameport/gameport.c @@ -11,6 +11,8 @@ * the Free Software Foundation. */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include @@ -190,9 +192,8 @@ static int gameport_bind_driver(struct gameport *gameport, struct gameport_drive error = device_bind_driver(&gameport->dev); if (error) { - printk(KERN_WARNING - "gameport: device_bind_driver() failed " - "for %s (%s) and %s, error: %d\n", + dev_warn(&gameport->dev, + "device_bind_driver() failed for %s (%s) and %s, error: %d\n", gameport->phys, gameport->name, drv->description, error); drv->disconnect(gameport); @@ -209,9 +210,9 @@ static void gameport_find_driver(struct gameport *gameport) error = device_attach(&gameport->dev); if (error < 0) - printk(KERN_WARNING - "gameport: device_attach() failed for %s (%s), error: %d\n", - gameport->phys, gameport->name, error); + dev_warn(&gameport->dev, + "device_attach() failed for %s (%s), error: %d\n", + gameport->phys, gameport->name, error); } @@ -262,17 +263,14 @@ static int gameport_queue_event(void *object, struct module *owner, event = kmalloc(sizeof(struct gameport_event), GFP_ATOMIC); if (!event) { - printk(KERN_ERR - "gameport: Not enough memory to queue event %d\n", - event_type); + pr_err("Not enough memory to queue event %d\n", event_type); retval = -ENOMEM; goto out; } if (!try_module_get(owner)) { - printk(KERN_WARNING - "gameport: Can't get module reference, dropping event %d\n", - event_type); + pr_warning("Can't get module reference, dropping event %d\n", + event_type); kfree(event); retval = -EINVAL; goto out; @@ -335,7 +333,6 @@ static struct gameport_event *gameport_get_event(void) } spin_unlock_irqrestore(&gameport_event_lock, flags); - return event; } @@ -354,16 +351,14 @@ static void gameport_handle_event(void) if ((event = gameport_get_event())) { switch (event->type) { - case GAMEPORT_REGISTER_PORT: - gameport_add_port(event->object); - break; - case GAMEPORT_ATTACH_DRIVER: - gameport_attach_driver(event->object); - break; + case GAMEPORT_REGISTER_PORT: + gameport_add_port(event->object); + break; - default: - break; + case GAMEPORT_ATTACH_DRIVER: + gameport_attach_driver(event->object); + break; } gameport_remove_duplicate_events(event); @@ -433,7 +428,6 @@ static int gameport_thread(void *nothing) kthread_should_stop() || !list_empty(&gameport_event_list)); } while (!kthread_should_stop()); - printk(KERN_DEBUG "gameport: kgameportd exiting\n"); return 0; } @@ -445,6 +439,7 @@ static int gameport_thread(void *nothing) 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); } @@ -513,7 +508,8 @@ static void gameport_init_port(struct gameport *gameport) mutex_init(&gameport->drv_mutex); device_initialize(&gameport->dev); - dev_set_name(&gameport->dev, "gameport%lu", (unsigned long)atomic_inc_return(&gameport_no) - 1); + dev_set_name(&gameport->dev, "gameport%lu", + (unsigned long)atomic_inc_return(&gameport_no) - 1); gameport->dev.bus = &gameport_bus; gameport->dev.release = gameport_release_port; if (gameport->parent) @@ -542,16 +538,16 @@ static void gameport_add_port(struct gameport *gameport) list_add_tail(&gameport->node, &gameport_list); if (gameport->io) - printk(KERN_INFO "gameport: %s is %s, io %#x, speed %dkHz\n", - gameport->name, gameport->phys, gameport->io, gameport->speed); + dev_info(&gameport->dev, "%s is %s, io %#x, speed %dkHz\n", + gameport->name, gameport->phys, gameport->io, gameport->speed); else - printk(KERN_INFO "gameport: %s is %s, speed %dkHz\n", + dev_info(&gameport->dev, "%s is %s, speed %dkHz\n", gameport->name, gameport->phys, gameport->speed); error = device_add(&gameport->dev); if (error) - printk(KERN_ERR - "gameport: device_add() failed for %s (%s), error: %d\n", + dev_err(&gameport->dev, + "device_add() failed for %s (%s), error: %d\n", gameport->phys, gameport->name, error); } @@ -693,8 +689,7 @@ static void gameport_attach_driver(struct gameport_driver *drv) error = driver_attach(&drv->driver); if (error) - printk(KERN_ERR - "gameport: driver_attach() failed for %s, error: %d\n", + pr_err("driver_attach() failed for %s, error: %d\n", drv->driver.name, error); } @@ -715,8 +710,7 @@ int __gameport_register_driver(struct gameport_driver *drv, struct module *owner error = driver_register(&drv->driver); if (error) { - printk(KERN_ERR - "gameport: driver_register() failed for %s, error: %d\n", + pr_err("driver_register() failed for %s, error: %d\n", drv->driver.name, error); return error; } @@ -816,7 +810,7 @@ static int __init gameport_init(void) error = bus_register(&gameport_bus); if (error) { - printk(KERN_ERR "gameport: failed to register gameport bus, error: %d\n", error); + pr_err("failed to register gameport bus, error: %d\n", error); return error; } @@ -824,7 +818,7 @@ static int __init gameport_init(void) if (IS_ERR(gameport_task)) { bus_unregister(&gameport_bus); error = PTR_ERR(gameport_task); - printk(KERN_ERR "gameport: Failed to start kgameportd, error: %d\n", error); + pr_err("Failed to start kgameportd, error: %d\n", error); return error; } -- cgit v1.2.3 From 4f93df40859cf471774f6ef3ec7f2870c2e8e260 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Tue, 5 Jan 2010 17:56:00 -0800 Subject: Input: automatically reset KEY_RESERVED bit for all input devices KEY_RESERVED is not supposed to be reported to userspace but rather to mark unused entries in keymaps. Acked-by: Henrique de Moraes Holschuh Signed-off-by: Dmitry Torokhov --- drivers/input/input.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) (limited to 'drivers/input') diff --git a/drivers/input/input.c b/drivers/input/input.c index ab060710688f..910d7be06eff 100644 --- a/drivers/input/input.c +++ b/drivers/input/input.c @@ -613,12 +613,12 @@ static int input_default_setkeycode(struct input_dev *dev, } } - clear_bit(old_keycode, dev->keybit); - set_bit(keycode, dev->keybit); + __clear_bit(old_keycode, dev->keybit); + __set_bit(keycode, dev->keybit); for (i = 0; i < dev->keycodemax; i++) { if (input_fetch_keycode(dev, i) == old_keycode) { - set_bit(old_keycode, dev->keybit); + __set_bit(old_keycode, dev->keybit); break; /* Setting the bit twice is useless, so break */ } } @@ -676,6 +676,9 @@ int input_set_keycode(struct input_dev *dev, int scancode, int keycode) if (retval) goto out; + /* Make sure KEY_RESERVED did not get enabled. */ + __clear_bit(KEY_RESERVED, dev->keybit); + /* * Simulate keyup event if keycode is not present * in the keymap anymore @@ -1513,13 +1516,16 @@ int input_register_device(struct input_dev *dev) const char *path; int error; + /* Every input device generates EV_SYN/SYN_REPORT events. */ __set_bit(EV_SYN, dev->evbit); + /* KEY_RESERVED is not supposed to be transmitted to userspace. */ + __clear_bit(KEY_RESERVED, dev->keybit); + /* * If delay and period are pre-set by the driver, then autorepeating * is handled by the driver itself and we don't do it in input.c. */ - init_timer(&dev->timer); if (!dev->rep[REP_DELAY] && !dev->rep[REP_PERIOD]) { dev->timer.data = (long) dev; -- cgit v1.2.3 From 92a3a58788790645c6143b5353ef065fd26110bb Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Tue, 5 Jan 2010 17:56:01 -0800 Subject: Input: cleanse capabilities bits before registering device To avoid showing garbage in capability bits, zero out bitmasks absent from dev->evbit in case driver inadvertently leaves some garbage there. Signed-off-by: Dmitry Torokhov --- drivers/input/input.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) (limited to 'drivers/input') diff --git a/drivers/input/input.c b/drivers/input/input.c index 910d7be06eff..a31394c1eca8 100644 --- a/drivers/input/input.c +++ b/drivers/input/input.c @@ -1497,6 +1497,25 @@ void input_set_capability(struct input_dev *dev, unsigned int type, unsigned int } EXPORT_SYMBOL(input_set_capability); +#define INPUT_CLEANSE_BITMASK(dev, type, bits) \ + do { \ + if (!test_bit(EV_##type, dev->evbit)) \ + memset(dev->bits##bit, 0, \ + sizeof(dev->bits##bit)); \ + } while (0) + +static void input_cleanse_bitmasks(struct input_dev *dev) +{ + INPUT_CLEANSE_BITMASK(dev, KEY, key); + INPUT_CLEANSE_BITMASK(dev, REL, rel); + INPUT_CLEANSE_BITMASK(dev, ABS, abs); + INPUT_CLEANSE_BITMASK(dev, MSC, msc); + INPUT_CLEANSE_BITMASK(dev, LED, led); + INPUT_CLEANSE_BITMASK(dev, SND, snd); + INPUT_CLEANSE_BITMASK(dev, FF, ff); + INPUT_CLEANSE_BITMASK(dev, SW, sw); +} + /** * input_register_device - register device with input core * @dev: device to be registered @@ -1522,6 +1541,9 @@ int input_register_device(struct input_dev *dev) /* KEY_RESERVED is not supposed to be transmitted to userspace. */ __clear_bit(KEY_RESERVED, dev->keybit); + /* Make sure that bitmasks not mentioned in dev->evbit are clean. */ + input_cleanse_bitmasks(dev); + /* * If delay and period are pre-set by the driver, then autorepeating * is handled by the driver itself and we don't do it in input.c. -- cgit v1.2.3 From 3032458e38b583c92842818871e85c0f936b8645 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Wed, 6 Jan 2010 00:33:07 -0800 Subject: Input: psmouse - remove unused 'autocal' parameter from hgpk protocol Signed-off-by: Dmitry Torokhov --- drivers/input/mouse/hgpk.c | 4 ---- 1 file changed, 4 deletions(-) (limited to 'drivers/input') diff --git a/drivers/input/mouse/hgpk.c b/drivers/input/mouse/hgpk.c index b146237266d8..29dc6aade766 100644 --- a/drivers/input/mouse/hgpk.c +++ b/drivers/input/mouse/hgpk.c @@ -68,10 +68,6 @@ module_param(post_interrupt_delay, int, 0644); MODULE_PARM_DESC(post_interrupt_delay, "delay (ms) before recal after recal interrupt detected"); -static int autorecal = 1; -module_param(autorecal, int, 0644); -MODULE_PARM_DESC(autorecal, "enable recalibration in the driver"); - /* * When the touchpad gets ultra-sensitive, one can keep their finger 1/2" * above the pad and still have it send packets. This causes a jump cursor -- cgit v1.2.3 From a9a1f9c315c27fe7a260cd453167981cd680dae8 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Wed, 6 Jan 2010 23:51:47 -0800 Subject: Input: atkbd - switch to dev_err() and friends dev_err(), dev_warn() and dev_dbg() ensure consistency in driver messages. Also switch to using bool where appropriate and fix some formatting issues. Signed-off-by: Dmitry Torokhov --- drivers/input/keyboard/atkbd.c | 283 +++++++++++++++++++++-------------------- 1 file changed, 146 insertions(+), 137 deletions(-) (limited to 'drivers/input') diff --git a/drivers/input/keyboard/atkbd.c b/drivers/input/keyboard/atkbd.c index a3573570c52f..7c235013dba3 100644 --- a/drivers/input/keyboard/atkbd.c +++ b/drivers/input/keyboard/atkbd.c @@ -40,26 +40,26 @@ module_param_named(set, atkbd_set, int, 0); MODULE_PARM_DESC(set, "Select keyboard code set (2 = default, 3 = PS/2 native)"); #if defined(__i386__) || defined(__x86_64__) || defined(__hppa__) -static int atkbd_reset; +static bool atkbd_reset; #else -static int atkbd_reset = 1; +static bool atkbd_reset = true; #endif module_param_named(reset, atkbd_reset, bool, 0); MODULE_PARM_DESC(reset, "Reset keyboard during initialization"); -static int atkbd_softrepeat; +static bool atkbd_softrepeat; module_param_named(softrepeat, atkbd_softrepeat, bool, 0); MODULE_PARM_DESC(softrepeat, "Use software keyboard repeat"); -static int atkbd_softraw = 1; +static bool atkbd_softraw = true; module_param_named(softraw, atkbd_softraw, bool, 0); MODULE_PARM_DESC(softraw, "Use software generated rawmode"); -static int atkbd_scroll; +static bool atkbd_scroll; module_param_named(scroll, atkbd_scroll, bool, 0); MODULE_PARM_DESC(scroll, "Enable scroll-wheel on MS Office and similar keyboards"); -static int atkbd_extra; +static bool atkbd_extra; module_param_named(extra, atkbd_extra, bool, 0); MODULE_PARM_DESC(extra, "Enable extra LEDs and keys on IBM RapidAcces, EzKey and similar keyboards"); @@ -205,18 +205,18 @@ struct atkbd { unsigned short keycode[ATKBD_KEYMAP_SIZE]; DECLARE_BITMAP(force_release_mask, ATKBD_KEYMAP_SIZE); unsigned char set; - unsigned char translated; - unsigned char extra; - unsigned char write; - unsigned char softrepeat; - unsigned char softraw; - unsigned char scroll; - unsigned char enabled; + bool translated; + bool extra; + bool write; + bool softrepeat; + bool softraw; + bool scroll; + bool enabled; /* Accessed only from interrupt */ unsigned char emul; - unsigned char resend; - unsigned char release; + bool resend; + bool release; unsigned long xl_bit; unsigned int last; unsigned long time; @@ -298,18 +298,18 @@ static const unsigned int xl_table[] = { * Checks if we should mangle the scancode to extract 'release' bit * in translated mode. */ -static int atkbd_need_xlate(unsigned long xl_bit, unsigned char code) +static bool atkbd_need_xlate(unsigned long xl_bit, unsigned char code) { int i; if (code == ATKBD_RET_EMUL0 || code == ATKBD_RET_EMUL1) - return 0; + return false; for (i = 0; i < ARRAY_SIZE(xl_table); i++) if (code == xl_table[i]) return test_bit(i, &xl_bit); - return 1; + return true; } /* @@ -356,7 +356,7 @@ static unsigned int atkbd_compat_scancode(struct atkbd *atkbd, unsigned int code */ static irqreturn_t atkbd_interrupt(struct serio *serio, unsigned char data, - unsigned int flags) + unsigned int flags) { struct atkbd *atkbd = serio_get_drvdata(serio); struct input_dev *dev = atkbd->dev; @@ -365,20 +365,18 @@ static irqreturn_t atkbd_interrupt(struct serio *serio, unsigned char data, int value; unsigned short keycode; -#ifdef ATKBD_DEBUG - printk(KERN_DEBUG "atkbd.c: Received %02x flags %02x\n", data, flags); -#endif + dev_dbg(&serio->dev, "Received %02x flags %02x\n", data, flags); #if !defined(__i386__) && !defined (__x86_64__) if ((flags & (SERIO_FRAME | SERIO_PARITY)) && (~flags & SERIO_TIMEOUT) && !atkbd->resend && atkbd->write) { - printk(KERN_WARNING "atkbd.c: frame/parity error: %02x\n", flags); + dev_warn(&serio->dev, "Frame/parity error: %02x\n", flags); serio_write(serio, ATKBD_CMD_RESEND); - atkbd->resend = 1; + atkbd->resend = true; goto out; } if (!flags && data == ATKBD_RET_ACK) - atkbd->resend = 0; + atkbd->resend = false; #endif if (unlikely(atkbd->ps2dev.flags & PS2_FLAG_ACK)) @@ -409,32 +407,32 @@ static irqreturn_t atkbd_interrupt(struct serio *serio, unsigned char data, } switch (code) { - case ATKBD_RET_BAT: - atkbd->enabled = 0; - serio_reconnect(atkbd->ps2dev.serio); - goto out; - case ATKBD_RET_EMUL0: - atkbd->emul = 1; - goto out; - case ATKBD_RET_EMUL1: - atkbd->emul = 2; - goto out; - case ATKBD_RET_RELEASE: - atkbd->release = 1; - goto out; - case ATKBD_RET_ACK: - case ATKBD_RET_NAK: - if (printk_ratelimit()) - printk(KERN_WARNING "atkbd.c: Spurious %s on %s. " - "Some program might be trying access hardware directly.\n", - data == ATKBD_RET_ACK ? "ACK" : "NAK", serio->phys); - goto out; - case ATKBD_RET_ERR: - atkbd->err_count++; -#ifdef ATKBD_DEBUG - printk(KERN_DEBUG "atkbd.c: Keyboard on %s reports too many keys pressed.\n", serio->phys); -#endif - goto out; + case ATKBD_RET_BAT: + atkbd->enabled = false; + serio_reconnect(atkbd->ps2dev.serio); + goto out; + case ATKBD_RET_EMUL0: + atkbd->emul = 1; + goto out; + case ATKBD_RET_EMUL1: + atkbd->emul = 2; + goto out; + case ATKBD_RET_RELEASE: + atkbd->release = true; + goto out; + case ATKBD_RET_ACK: + case ATKBD_RET_NAK: + if (printk_ratelimit()) + dev_warn(&serio->dev, + "Spurious %s on %s. " + "Some program might be trying access hardware directly.\n", + data == ATKBD_RET_ACK ? "ACK" : "NAK", serio->phys); + goto out; + case ATKBD_RET_ERR: + atkbd->err_count++; + dev_dbg(&serio->dev, "Keyboard on %s reports too many keys pressed.\n", + serio->phys); + goto out; } code = atkbd_compat_scancode(atkbd, code); @@ -448,71 +446,72 @@ static irqreturn_t atkbd_interrupt(struct serio *serio, unsigned char data, input_event(dev, EV_MSC, MSC_SCAN, code); switch (keycode) { - case ATKBD_KEY_NULL: - break; - case ATKBD_KEY_UNKNOWN: - printk(KERN_WARNING - "atkbd.c: Unknown key %s (%s set %d, code %#x on %s).\n", - atkbd->release ? "released" : "pressed", - atkbd->translated ? "translated" : "raw", - atkbd->set, code, serio->phys); - printk(KERN_WARNING - "atkbd.c: Use 'setkeycodes %s%02x ' to make it known.\n", - code & 0x80 ? "e0" : "", code & 0x7f); - input_sync(dev); - break; - case ATKBD_SCR_1: - scroll = 1 - atkbd->release * 2; - break; - case ATKBD_SCR_2: - scroll = 2 - atkbd->release * 4; - break; - case ATKBD_SCR_4: - scroll = 4 - atkbd->release * 8; - break; - case ATKBD_SCR_8: - scroll = 8 - atkbd->release * 16; - break; - case ATKBD_SCR_CLICK: - click = !atkbd->release; - break; - case ATKBD_SCR_LEFT: - hscroll = -1; - break; - case ATKBD_SCR_RIGHT: - hscroll = 1; - break; - default: - if (atkbd->release) { - value = 0; - atkbd->last = 0; - } else if (!atkbd->softrepeat && test_bit(keycode, dev->key)) { - /* Workaround Toshiba laptop multiple keypress */ - value = time_before(jiffies, atkbd->time) && atkbd->last == code ? 1 : 2; - } else { - value = 1; - atkbd->last = code; - atkbd->time = jiffies + msecs_to_jiffies(dev->rep[REP_DELAY]) / 2; - } - - input_event(dev, EV_KEY, keycode, value); - input_sync(dev); + case ATKBD_KEY_NULL: + break; + case ATKBD_KEY_UNKNOWN: + dev_warn(&serio->dev, + "Unknown key %s (%s set %d, code %#x on %s).\n", + atkbd->release ? "released" : "pressed", + atkbd->translated ? "translated" : "raw", + atkbd->set, code, serio->phys); + dev_warn(&serio->dev, + "Use 'setkeycodes %s%02x ' to make it known.\n", + code & 0x80 ? "e0" : "", code & 0x7f); + input_sync(dev); + break; + case ATKBD_SCR_1: + scroll = 1; + break; + case ATKBD_SCR_2: + scroll = 2; + break; + case ATKBD_SCR_4: + scroll = 4; + break; + case ATKBD_SCR_8: + scroll = 8; + break; + case ATKBD_SCR_CLICK: + click = !atkbd->release; + break; + case ATKBD_SCR_LEFT: + hscroll = -1; + break; + case ATKBD_SCR_RIGHT: + hscroll = 1; + break; + default: + if (atkbd->release) { + value = 0; + atkbd->last = 0; + } else if (!atkbd->softrepeat && test_bit(keycode, dev->key)) { + /* Workaround Toshiba laptop multiple keypress */ + value = time_before(jiffies, atkbd->time) && atkbd->last == code ? 1 : 2; + } else { + value = 1; + atkbd->last = code; + atkbd->time = jiffies + msecs_to_jiffies(dev->rep[REP_DELAY]) / 2; + } + + input_event(dev, EV_KEY, keycode, value); + input_sync(dev); - if (value && test_bit(code, atkbd->force_release_mask)) { - input_report_key(dev, keycode, 0); - input_sync(dev); - } + if (value && test_bit(code, atkbd->force_release_mask)) { + input_report_key(dev, keycode, 0); + input_sync(dev); + } } if (atkbd->scroll) { if (click != -1) input_report_key(dev, BTN_MIDDLE, click); - input_report_rel(dev, REL_WHEEL, scroll); + input_report_rel(dev, REL_WHEEL, + atkbd->release ? -scroll : scroll); input_report_rel(dev, REL_HWHEEL, hscroll); input_sync(dev); } - atkbd->release = 0; + atkbd->release = false; out: return IRQ_HANDLED; } @@ -631,17 +630,18 @@ static int atkbd_event(struct input_dev *dev, switch (type) { - case EV_LED: - atkbd_schedule_event_work(atkbd, ATKBD_LED_EVENT_BIT); - return 0; + case EV_LED: + atkbd_schedule_event_work(atkbd, ATKBD_LED_EVENT_BIT); + return 0; - case EV_REP: - if (!atkbd->softrepeat) - atkbd_schedule_event_work(atkbd, ATKBD_REP_EVENT_BIT); - return 0; - } + case EV_REP: + if (!atkbd->softrepeat) + atkbd_schedule_event_work(atkbd, ATKBD_REP_EVENT_BIT); + return 0; - return -1; + default: + return -1; + } } /* @@ -652,7 +652,7 @@ static int atkbd_event(struct input_dev *dev, static inline void atkbd_enable(struct atkbd *atkbd) { serio_pause_rx(atkbd->ps2dev.serio); - atkbd->enabled = 1; + atkbd->enabled = true; serio_continue_rx(atkbd->ps2dev.serio); } @@ -664,7 +664,7 @@ static inline void atkbd_enable(struct atkbd *atkbd) static inline void atkbd_disable(struct atkbd *atkbd) { serio_pause_rx(atkbd->ps2dev.serio); - atkbd->enabled = 0; + atkbd->enabled = false; serio_continue_rx(atkbd->ps2dev.serio); } @@ -685,7 +685,9 @@ static int atkbd_probe(struct atkbd *atkbd) if (atkbd_reset) if (ps2_command(ps2dev, NULL, ATKBD_CMD_RESET_BAT)) - printk(KERN_WARNING "atkbd.c: keyboard reset failed on %s\n", ps2dev->serio->phys); + dev_warn(&ps2dev->serio->dev, + "keyboard reset failed on %s\n", + ps2dev->serio->phys); /* * Then we check the keyboard ID. We should get 0xab83 under normal conditions. @@ -715,8 +717,9 @@ static int atkbd_probe(struct atkbd *atkbd) atkbd->id = (param[0] << 8) | param[1]; if (atkbd->id == 0xaca1 && atkbd->translated) { - printk(KERN_ERR "atkbd.c: NCD terminal keyboards are only supported on non-translating\n"); - printk(KERN_ERR "atkbd.c: controllers. Use i8042.direct=1 to disable translation.\n"); + dev_err(&ps2dev->serio->dev, + "NCD terminal keyboards are only supported on non-translating controlelrs. " + "Use i8042.direct=1 to disable translation.\n"); return -1; } @@ -734,7 +737,7 @@ static int atkbd_select_set(struct atkbd *atkbd, int target_set, int allow_extra struct ps2dev *ps2dev = &atkbd->ps2dev; unsigned char param[2]; - atkbd->extra = 0; + atkbd->extra = false; /* * For known special keyboards we can go ahead and set the correct set. * We check for NCD PS/2 Sun, NorthGate OmniKey 101 and @@ -753,7 +756,7 @@ static int atkbd_select_set(struct atkbd *atkbd, int target_set, int allow_extra if (allow_extra) { param[0] = 0x71; if (!ps2_command(ps2dev, param, ATKBD_CMD_EX_ENABLE)) { - atkbd->extra = 1; + atkbd->extra = true; return 2; } } @@ -818,7 +821,8 @@ static int atkbd_activate(struct atkbd *atkbd) */ if (ps2_command(ps2dev, NULL, ATKBD_CMD_ENABLE)) { - printk(KERN_ERR "atkbd.c: Failed to enable keyboard on %s\n", + dev_err(&ps2dev->serio->dev, + "Failed to enable keyboard on %s\n", ps2dev->serio->phys); return -1; } @@ -1090,12 +1094,14 @@ static int atkbd_connect(struct serio *serio, struct serio_driver *drv) switch (serio->id.type) { - case SERIO_8042_XL: - atkbd->translated = 1; - case SERIO_8042: - if (serio->write) - atkbd->write = 1; - break; + case SERIO_8042_XL: + atkbd->translated = true; + /* Fall through */ + + case SERIO_8042: + if (serio->write) + atkbd->write = true; + break; } atkbd->softraw = atkbd_softraw; @@ -1103,7 +1109,7 @@ static int atkbd_connect(struct serio *serio, struct serio_driver *drv) atkbd->scroll = atkbd_scroll; if (atkbd->softrepeat) - atkbd->softraw = 1; + atkbd->softraw = true; serio_set_drvdata(serio, atkbd); @@ -1161,7 +1167,8 @@ static int atkbd_reconnect(struct serio *serio) struct serio_driver *drv = serio->drv; if (!atkbd || !drv) { - printk(KERN_DEBUG "atkbd: reconnect request, but serio is disconnected, ignoring...\n"); + dev_dbg(&serio->dev, + "reconnect request, but serio is disconnected, ignoring...\n"); return -1; } @@ -1288,7 +1295,8 @@ static ssize_t atkbd_set_extra(struct atkbd *atkbd, const char *buf, size_t coun struct input_dev *old_dev, *new_dev; unsigned long value; int err; - unsigned char old_extra, old_set; + bool old_extra; + unsigned char old_set; if (!atkbd->write) return -EIO; @@ -1371,7 +1379,7 @@ static ssize_t atkbd_set_scroll(struct atkbd *atkbd, const char *buf, size_t cou struct input_dev *old_dev, *new_dev; unsigned long value; int err; - unsigned char old_scroll; + bool old_scroll; if (strict_strtoul(buf, 10, &value) || value > 1) return -EINVAL; @@ -1415,7 +1423,8 @@ static ssize_t atkbd_set_set(struct atkbd *atkbd, const char *buf, size_t count) struct input_dev *old_dev, *new_dev; unsigned long value; int err; - unsigned char old_set, old_extra; + unsigned char old_set; + bool old_extra; if (!atkbd->write) return -EIO; @@ -1465,7 +1474,7 @@ static ssize_t atkbd_set_softrepeat(struct atkbd *atkbd, const char *buf, size_t struct input_dev *old_dev, *new_dev; unsigned long value; int err; - unsigned char old_softrepeat, old_softraw; + bool old_softrepeat, old_softraw; if (!atkbd->write) return -EIO; @@ -1485,7 +1494,7 @@ static ssize_t atkbd_set_softrepeat(struct atkbd *atkbd, const char *buf, size_t atkbd->dev = new_dev; atkbd->softrepeat = value; if (atkbd->softrepeat) - atkbd->softraw = 1; + atkbd->softraw = true; atkbd_set_device_attrs(atkbd); err = input_register_device(atkbd->dev); @@ -1515,7 +1524,7 @@ static ssize_t atkbd_set_softraw(struct atkbd *atkbd, const char *buf, size_t co struct input_dev *old_dev, *new_dev; unsigned long value; int err; - unsigned char old_softraw; + bool old_softraw; if (strict_strtoul(buf, 10, &value) || value > 1) return -EINVAL; -- cgit v1.2.3 From 8cab9ba10493cea164ac8bbbc733c21a528e6fe5 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Wed, 6 Jan 2010 23:52:12 -0800 Subject: Input: elo - switch to using dev_xxx() when printing messages Also fix formatting of "switch" statements. Signed-off-by: Dmitry Torokhov --- drivers/input/touchscreen/elo.c | 225 +++++++++++++++++++++------------------- 1 file changed, 120 insertions(+), 105 deletions(-) (limited to 'drivers/input') diff --git a/drivers/input/touchscreen/elo.c b/drivers/input/touchscreen/elo.c index 8f38c5e55ce6..486d31ba9c09 100644 --- a/drivers/input/touchscreen/elo.c +++ b/drivers/input/touchscreen/elo.c @@ -72,45 +72,49 @@ static void elo_process_data_10(struct elo *elo, unsigned char data) struct input_dev *dev = elo->dev; elo->data[elo->idx] = data; - switch (elo->idx++) { - case 0: - elo->csum = 0xaa; - if (data != ELO10_LEAD_BYTE) { - pr_debug("elo: unsynchronized data: 0x%02x\n", data); - elo->idx = 0; - } - break; - case 9: + switch (elo->idx++) { + case 0: + elo->csum = 0xaa; + if (data != ELO10_LEAD_BYTE) { + dev_dbg(&elo->serio->dev, + "unsynchronized data: 0x%02x\n", data); elo->idx = 0; - if (data != elo->csum) { - pr_debug("elo: bad checksum: 0x%02x, expected 0x%02x\n", - data, elo->csum); - break; - } - if (elo->data[1] != elo->expected_packet) { - if (elo->data[1] != ELO10_TOUCH_PACKET) - pr_debug("elo: unexpected packet: 0x%02x\n", - elo->data[1]); - break; - } - if (likely(elo->data[1] == ELO10_TOUCH_PACKET)) { - 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]); - if (elo->data[2] & ELO10_PRESSURE) - input_report_abs(dev, ABS_PRESSURE, - (elo->data[8] << 8) | elo->data[7]); - input_report_key(dev, BTN_TOUCH, elo->data[2] & ELO10_TOUCH); - input_sync(dev); - } else if (elo->data[1] == ELO10_ACK_PACKET) { - if (elo->data[2] == '0') - elo->expected_packet = ELO10_TOUCH_PACKET; - complete(&elo->cmd_done); - } else { - memcpy(elo->response, &elo->data[1], ELO10_PACKET_LEN); - elo->expected_packet = ELO10_ACK_PACKET; - } + } + break; + + case 9: + elo->idx = 0; + if (data != elo->csum) { + dev_dbg(&elo->serio->dev, + "bad checksum: 0x%02x, expected 0x%02x\n", + data, elo->csum); + break; + } + if (elo->data[1] != elo->expected_packet) { + if (elo->data[1] != ELO10_TOUCH_PACKET) + dev_dbg(&elo->serio->dev, + "unexpected packet: 0x%02x\n", + elo->data[1]); break; + } + if (likely(elo->data[1] == ELO10_TOUCH_PACKET)) { + 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]); + if (elo->data[2] & ELO10_PRESSURE) + input_report_abs(dev, ABS_PRESSURE, + (elo->data[8] << 8) | elo->data[7]); + input_report_key(dev, BTN_TOUCH, elo->data[2] & ELO10_TOUCH); + input_sync(dev); + } else if (elo->data[1] == ELO10_ACK_PACKET) { + if (elo->data[2] == '0') + elo->expected_packet = ELO10_TOUCH_PACKET; + complete(&elo->cmd_done); + } else { + memcpy(elo->response, &elo->data[1], ELO10_PACKET_LEN); + elo->expected_packet = ELO10_ACK_PACKET; + } + break; } elo->csum += data; } @@ -123,42 +127,53 @@ static void elo_process_data_6(struct elo *elo, unsigned char data) switch (elo->idx++) { - case 0: if ((data & 0xc0) != 0xc0) elo->idx = 0; break; - case 1: if ((data & 0xc0) != 0x80) elo->idx = 0; break; - case 2: if ((data & 0xc0) != 0x40) elo->idx = 0; break; - - case 3: - if (data & 0xc0) { - elo->idx = 0; - break; - } + case 0: + if ((data & 0xc0) != 0xc0) + elo->idx = 0; + break; - input_report_abs(dev, ABS_X, ((elo->data[0] & 0x3f) << 6) | (elo->data[1] & 0x3f)); - input_report_abs(dev, ABS_Y, ((elo->data[2] & 0x3f) << 6) | (elo->data[3] & 0x3f)); + case 1: + if ((data & 0xc0) != 0x80) + elo->idx = 0; + break; - if (elo->id == 2) { - input_report_key(dev, BTN_TOUCH, 1); - input_sync(dev); - elo->idx = 0; - } + case 2: + if ((data & 0xc0) != 0x40) + elo->idx = 0; + break; + case 3: + if (data & 0xc0) { + elo->idx = 0; break; + } - case 4: - if (data) { - input_sync(dev); - elo->idx = 0; - } - break; + input_report_abs(dev, ABS_X, ((elo->data[0] & 0x3f) << 6) | (elo->data[1] & 0x3f)); + input_report_abs(dev, ABS_Y, ((elo->data[2] & 0x3f) << 6) | (elo->data[3] & 0x3f)); - case 5: - if ((data & 0xf0) == 0) { - input_report_abs(dev, ABS_PRESSURE, elo->data[5]); - input_report_key(dev, BTN_TOUCH, !!elo->data[5]); - } + if (elo->id == 2) { + input_report_key(dev, BTN_TOUCH, 1); input_sync(dev); elo->idx = 0; - break; + } + + break; + + case 4: + if (data) { + input_sync(dev); + elo->idx = 0; + } + break; + + 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_sync(dev); + elo->idx = 0; + break; } } @@ -170,17 +185,17 @@ static void elo_process_data_3(struct elo *elo, unsigned char data) switch (elo->idx++) { - case 0: - if ((data & 0x7f) != 0x01) - elo->idx = 0; - break; - case 2: - input_report_key(dev, BTN_TOUCH, !(elo->data[1] & 0x80)); - input_report_abs(dev, ABS_X, elo->data[1]); - input_report_abs(dev, ABS_Y, elo->data[2]); - input_sync(dev); + case 0: + if ((data & 0x7f) != 0x01) elo->idx = 0; - break; + break; + case 2: + input_report_key(dev, BTN_TOUCH, !(elo->data[1] & 0x80)); + input_report_abs(dev, ABS_X, elo->data[1]); + input_report_abs(dev, ABS_Y, elo->data[2]); + input_sync(dev); + elo->idx = 0; + break; } } @@ -189,19 +204,19 @@ static irqreturn_t elo_interrupt(struct serio *serio, { struct elo *elo = serio_get_drvdata(serio); - switch(elo->id) { - case 0: - elo_process_data_10(elo, data); - break; - - case 1: - case 2: - elo_process_data_6(elo, data); - break; - - case 3: - elo_process_data_3(elo, data); - break; + switch (elo->id) { + case 0: + elo_process_data_10(elo, data); + break; + + case 1: + case 2: + elo_process_data_6(elo, data); + break; + + case 3: + elo_process_data_3(elo, data); + break; } return IRQ_HANDLED; @@ -261,10 +276,10 @@ static int elo_setup_10(struct elo *elo) if (packet[3] & ELO10_PRESSURE) input_set_abs_params(dev, ABS_PRESSURE, 0, 255, 0, 0); - printk(KERN_INFO "elo: %sTouch touchscreen, fw: %02x.%02x, " - "features: 0x%02x, controller: 0x%02x\n", - elo_types[(packet[1] -'0') & 0x03], - packet[5], packet[4], packet[3], packet[7]); + dev_info(&elo->serio->dev, + "%sTouch touchscreen, fw: %02x.%02x, features: 0x%02x, controller: 0x%02x\n", + elo_types[(packet[1] -'0') & 0x03], + packet[5], packet[4], packet[3], packet[7]); return 0; } @@ -330,24 +345,24 @@ static int elo_connect(struct serio *serio, struct serio_driver *drv) switch (elo->id) { - case 0: /* 10-byte protocol */ - if (elo_setup_10(elo)) - goto fail3; + case 0: /* 10-byte protocol */ + if (elo_setup_10(elo)) + goto fail3; - break; + break; - case 1: /* 6-byte protocol */ - input_set_abs_params(input_dev, ABS_PRESSURE, 0, 15, 0, 0); + case 1: /* 6-byte protocol */ + input_set_abs_params(input_dev, ABS_PRESSURE, 0, 15, 0, 0); - case 2: /* 4-byte protocol */ - input_set_abs_params(input_dev, ABS_X, 96, 4000, 0, 0); - input_set_abs_params(input_dev, ABS_Y, 96, 4000, 0, 0); - break; + case 2: /* 4-byte protocol */ + input_set_abs_params(input_dev, ABS_X, 96, 4000, 0, 0); + input_set_abs_params(input_dev, ABS_Y, 96, 4000, 0, 0); + break; - case 3: /* 3-byte protocol */ - input_set_abs_params(input_dev, ABS_X, 0, 255, 0, 0); - input_set_abs_params(input_dev, ABS_Y, 0, 255, 0, 0); - break; + case 3: /* 3-byte protocol */ + input_set_abs_params(input_dev, ABS_X, 0, 255, 0, 0); + input_set_abs_params(input_dev, ABS_Y, 0, 255, 0, 0); + break; } err = input_register_device(elo->dev); -- cgit v1.2.3 From ce7b39a181571ed5a87f3ca62d4cffe4835c6ae9 Mon Sep 17 00:00:00 2001 From: Márton Németh Date: Sat, 9 Jan 2010 23:23:02 -0800 Subject: Input: make i2c device ids constant MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The id_table field of the struct i2c_driver is defined as constant in so it makes sense to mark the initialization data also constant. Signed-off-by: Márton Németh Signed-off-by: Dmitry Torokhov --- drivers/input/keyboard/qt2160.c | 2 +- drivers/input/misc/apanel.c | 2 +- drivers/input/touchscreen/tsc2007.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/input') diff --git a/drivers/input/keyboard/qt2160.c b/drivers/input/keyboard/qt2160.c index 191cc51d6cf8..31f30087b591 100644 --- a/drivers/input/keyboard/qt2160.c +++ b/drivers/input/keyboard/qt2160.c @@ -362,7 +362,7 @@ static int __devexit qt2160_remove(struct i2c_client *client) return 0; } -static struct i2c_device_id qt2160_idtable[] = { +static const struct i2c_device_id qt2160_idtable[] = { { "qt2160", 0, }, { } }; diff --git a/drivers/input/misc/apanel.c b/drivers/input/misc/apanel.c index 71b82434264d..a8d2b8db4e35 100644 --- a/drivers/input/misc/apanel.c +++ b/drivers/input/misc/apanel.c @@ -149,7 +149,7 @@ static void apanel_shutdown(struct i2c_client *client) apanel_remove(client); } -static struct i2c_device_id apanel_id[] = { +static const struct i2c_device_id apanel_id[] = { { "fujitsu_apanel", 0 }, { } }; diff --git a/drivers/input/touchscreen/tsc2007.c b/drivers/input/touchscreen/tsc2007.c index 7ef0d1420d3c..be23780e8a3e 100644 --- a/drivers/input/touchscreen/tsc2007.c +++ b/drivers/input/touchscreen/tsc2007.c @@ -358,7 +358,7 @@ static int __devexit tsc2007_remove(struct i2c_client *client) return 0; } -static struct i2c_device_id tsc2007_idtable[] = { +static const struct i2c_device_id tsc2007_idtable[] = { { "tsc2007", 0 }, { } }; -- cgit v1.2.3 From ef9a16f15dccba6630d8860a964a4adef1a4ab98 Mon Sep 17 00:00:00 2001 From: Márton Németh Date: Sat, 9 Jan 2010 23:23:02 -0800 Subject: Input: xilinx_ps2 - make Open Firmware device ids constant MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The match_table field of the struct of_device_id is constant in so it makes sense to mark xps2_of_match also constant. Signed-off-by: Márton Németh Signed-off-by: Dmitry Torokhov --- drivers/input/serio/xilinx_ps2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/input') diff --git a/drivers/input/serio/xilinx_ps2.c b/drivers/input/serio/xilinx_ps2.c index ebb22f88c842..78c64fb8a4b0 100644 --- a/drivers/input/serio/xilinx_ps2.c +++ b/drivers/input/serio/xilinx_ps2.c @@ -354,7 +354,7 @@ static int __devexit xps2_of_remove(struct of_device *of_dev) } /* Match table for of_platform binding */ -static struct of_device_id xps2_of_match[] __devinitdata = { +static const struct of_device_id xps2_of_match[] __devinitconst = { { .compatible = "xlnx,xps-ps2-1.00.a", }, { /* end of list */ }, }; -- cgit v1.2.3 From a9844b18502bde376284e4ad83b04fa20eb5afa5 Mon Sep 17 00:00:00 2001 From: Márton Németh Date: Sat, 9 Jan 2010 23:23:58 -0800 Subject: Input: make PCI device ids constant MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The id_table field of the struct pci_driver is constant in so it makes sense to mark initialization data also constant. Signed-off-by: Márton Németh Signed-off-by: Dmitry Torokhov --- drivers/input/gameport/emu10k1-gp.c | 2 +- drivers/input/gameport/fm801-gp.c | 2 +- drivers/input/serio/pcips2.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/input') diff --git a/drivers/input/gameport/emu10k1-gp.c b/drivers/input/gameport/emu10k1-gp.c index b04930f7ea7d..7392992da424 100644 --- a/drivers/input/gameport/emu10k1-gp.c +++ b/drivers/input/gameport/emu10k1-gp.c @@ -46,7 +46,7 @@ struct emu { int size; }; -static struct pci_device_id emu_tbl[] = { +static const struct pci_device_id emu_tbl[] = { { 0x1102, 0x7002, PCI_ANY_ID, PCI_ANY_ID }, /* SB Live gameport */ { 0x1102, 0x7003, PCI_ANY_ID, PCI_ANY_ID }, /* Audigy gameport */ diff --git a/drivers/input/gameport/fm801-gp.c b/drivers/input/gameport/fm801-gp.c index 8a1810f88b9e..14d3f3e208a2 100644 --- a/drivers/input/gameport/fm801-gp.c +++ b/drivers/input/gameport/fm801-gp.c @@ -140,7 +140,7 @@ static void __devexit fm801_gp_remove(struct pci_dev *pci) } } -static struct pci_device_id fm801_gp_id_table[] = { +static const struct pci_device_id fm801_gp_id_table[] = { { PCI_VENDOR_ID_FORTEMEDIA, PCI_DEVICE_ID_FM801_GP, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, { 0 } }; diff --git a/drivers/input/serio/pcips2.c b/drivers/input/serio/pcips2.c index 1dacbe0d9348..797314be7af2 100644 --- a/drivers/input/serio/pcips2.c +++ b/drivers/input/serio/pcips2.c @@ -186,7 +186,7 @@ static void __devexit pcips2_remove(struct pci_dev *dev) pci_disable_device(dev); } -static struct pci_device_id pcips2_ids[] = { +static const struct pci_device_id pcips2_ids[] = { { .vendor = 0x14f2, /* MOBILITY */ .device = 0x0123, /* Keyboard */ -- cgit v1.2.3 From 35c4b918a696f20cb775f1a65955c8ed0fe7c052 Mon Sep 17 00:00:00 2001 From: Márton Németh Date: Sat, 9 Jan 2010 23:24:48 -0800 Subject: Input: ns558 - make pnp device ids constant MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The id_table field of the struct pnp_driver is constant in so it makes sense to mark pnp_devids also constant. Signed-off-by: Márton Németh Signed-off-by: Dmitry Torokhov --- drivers/input/gameport/ns558.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/input') diff --git a/drivers/input/gameport/ns558.c b/drivers/input/gameport/ns558.c index db556b71ddda..7c217848613e 100644 --- a/drivers/input/gameport/ns558.c +++ b/drivers/input/gameport/ns558.c @@ -166,7 +166,7 @@ static int ns558_isa_probe(int io) #ifdef CONFIG_PNP -static struct pnp_device_id pnp_devids[] = { +static const struct pnp_device_id pnp_devids[] = { { .id = "@P@0001", .driver_data = 0 }, /* ALS 100 */ { .id = "@P@0020", .driver_data = 0 }, /* ALS 200 */ { .id = "@P@1001", .driver_data = 0 }, /* ALS 100+ */ -- cgit v1.2.3 From c6d5709384090de541158a6bba8d4ae50242ff94 Mon Sep 17 00:00:00 2001 From: Márton Németh Date: Sat, 9 Jan 2010 23:25:44 -0800 Subject: Input: xen-kbdfront - make xenbus device ids constant MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The ids field of the struct xenbus_device_id is constant in so it makes sense to mark xenkbd_ids also constant. Signed-off-by: Márton Németh Signed-off-by: Dmitry Torokhov --- drivers/input/xen-kbdfront.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/input') diff --git a/drivers/input/xen-kbdfront.c b/drivers/input/xen-kbdfront.c index c721c0a23eb8..d30436fee476 100644 --- a/drivers/input/xen-kbdfront.c +++ b/drivers/input/xen-kbdfront.c @@ -321,7 +321,7 @@ InitWait: } } -static struct xenbus_device_id xenkbd_ids[] = { +static const struct xenbus_device_id xenkbd_ids[] = { { "vkbd" }, { "" } }; -- cgit v1.2.3 From 9cb3ce52ca45d089d5be90d2f34005296fc5a34e Mon Sep 17 00:00:00 2001 From: Márton Németh Date: Sun, 10 Jan 2010 23:59:05 -0800 Subject: Input: make USB device ids constant MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The id_table field of the struct usb_device_id is constant in so it makes sense to mark the initialization data also constant. Signed-off-by: Márton Németh Signed-off-by: Dmitry Torokhov --- drivers/input/tablet/gtco.c | 2 +- drivers/input/touchscreen/usbtouchscreen.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/input') diff --git a/drivers/input/tablet/gtco.c b/drivers/input/tablet/gtco.c index 3d32d3f4e486..866a9ee1af1a 100644 --- a/drivers/input/tablet/gtco.c +++ b/drivers/input/tablet/gtco.c @@ -92,7 +92,7 @@ Scott Hill shill@gtcocalcomp.com /* DATA STRUCTURES */ /* Device table */ -static struct usb_device_id gtco_usbid_table [] = { +static const struct usb_device_id gtco_usbid_table[] = { { USB_DEVICE(VENDOR_ID_GTCO, PID_400) }, { USB_DEVICE(VENDOR_ID_GTCO, PID_401) }, { USB_DEVICE(VENDOR_ID_GTCO, PID_1000) }, diff --git a/drivers/input/touchscreen/usbtouchscreen.c b/drivers/input/touchscreen/usbtouchscreen.c index 09a5e7341bd5..b1b99e931f80 100644 --- a/drivers/input/touchscreen/usbtouchscreen.c +++ b/drivers/input/touchscreen/usbtouchscreen.c @@ -144,7 +144,7 @@ enum { .bInterfaceClass = USB_INTERFACE_CLASS_HID, \ .bInterfaceProtocol = USB_INTERFACE_PROTOCOL_MOUSE -static struct usb_device_id usbtouch_devices[] = { +static const struct usb_device_id usbtouch_devices[] = { #ifdef CONFIG_TOUCHSCREEN_USB_EGALAX /* ignore the HID capable devices, handled by usbhid */ {USB_DEVICE_HID_CLASS(0x0eef, 0x0001), .driver_info = DEVTYPE_IGNORE}, -- cgit v1.2.3 From a5abd95cc0b35034186a9f76b0f2b83458425f47 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 13 Jan 2010 00:34:12 -0800 Subject: Input: ep93xx_keypad - cleanup and use matrix_keypad helpers Use struct matrix_keymap_data to supply the keymap from the platform code and matrix_keypad_build_keymap() to initialize the keymap. Signed-off-by: H Hartley Sweeten Signed-off-by: Dmitry Torokhov --- arch/arm/mach-ep93xx/include/mach/ep93xx_keypad.h | 14 ++++---- drivers/input/keyboard/ep93xx_keypad.c | 40 +++++++++-------------- 2 files changed, 22 insertions(+), 32 deletions(-) (limited to 'drivers/input') diff --git a/arch/arm/mach-ep93xx/include/mach/ep93xx_keypad.h b/arch/arm/mach-ep93xx/include/mach/ep93xx_keypad.h index 62d17421e48c..1e2f4e97f428 100644 --- a/arch/arm/mach-ep93xx/include/mach/ep93xx_keypad.h +++ b/arch/arm/mach-ep93xx/include/mach/ep93xx_keypad.h @@ -5,6 +5,8 @@ #ifndef __ASM_ARCH_EP93XX_KEYPAD_H #define __ASM_ARCH_EP93XX_KEYPAD_H +struct matrix_keymap_data; + /* flags for the ep93xx_keypad driver */ #define EP93XX_KEYPAD_DISABLE_3_KEY (1<<0) /* disable 3-key reset */ #define EP93XX_KEYPAD_DIAG_MODE (1<<1) /* diagnostic mode */ @@ -15,15 +17,13 @@ /** * struct ep93xx_keypad_platform_data - platform specific device structure - * @matrix_key_map: array of keycodes defining the keypad matrix - * @matrix_key_map_size: ARRAY_SIZE(matrix_key_map) - * @debounce: debounce start count; terminal count is 0xff - * @prescale: row/column counter pre-scaler load value - * @flags: see above + * @keymap_data: pointer to &matrix_keymap_data + * @debounce: debounce start count; terminal count is 0xff + * @prescale: row/column counter pre-scaler load value + * @flags: see above */ struct ep93xx_keypad_platform_data { - unsigned int *matrix_key_map; - int matrix_key_map_size; + struct matrix_keymap_data *keymap_data; unsigned int debounce; unsigned int prescale; unsigned int flags; diff --git a/drivers/input/keyboard/ep93xx_keypad.c b/drivers/input/keyboard/ep93xx_keypad.c index e45740429f7e..bd25a3af1664 100644 --- a/drivers/input/keyboard/ep93xx_keypad.c +++ b/drivers/input/keyboard/ep93xx_keypad.c @@ -69,7 +69,7 @@ struct ep93xx_keypad { void __iomem *mmio_base; - unsigned int matrix_keycodes[EP93XX_MATRIX_SIZE]; + unsigned short keycodes[EP93XX_MATRIX_SIZE]; int key1; int key2; @@ -79,24 +79,6 @@ struct ep93xx_keypad { bool enabled; }; -static void ep93xx_keypad_build_keycode(struct ep93xx_keypad *keypad) -{ - struct ep93xx_keypad_platform_data *pdata = keypad->pdata; - struct input_dev *input_dev = keypad->input_dev; - unsigned int *key; - int i; - - key = &pdata->matrix_key_map[0]; - for (i = 0; i < pdata->matrix_key_map_size; i++, key++) { - int row = KEY_ROW(*key); - int col = KEY_COL(*key); - int code = KEY_VAL(*key); - - keypad->matrix_keycodes[(row << 3) + col] = code; - __set_bit(code, input_dev->keybit); - } -} - static irqreturn_t ep93xx_keypad_irq_handler(int irq, void *dev_id) { struct ep93xx_keypad *keypad = dev_id; @@ -107,10 +89,10 @@ static irqreturn_t ep93xx_keypad_irq_handler(int irq, void *dev_id) status = __raw_readl(keypad->mmio_base + KEY_REG); keycode = (status & KEY_REG_KEY1_MASK) >> KEY_REG_KEY1_SHIFT; - key1 = keypad->matrix_keycodes[keycode]; + key1 = keypad->keycodes[keycode]; keycode = (status & KEY_REG_KEY2_MASK) >> KEY_REG_KEY2_SHIFT; - key2 = keypad->matrix_keycodes[keycode]; + key2 = keypad->keycodes[keycode]; if (status & KEY_REG_2KEYS) { if (keypad->key1 && key1 != keypad->key1 && key2 != keypad->key1) @@ -256,6 +238,7 @@ static int ep93xx_keypad_resume(struct platform_device *pdev) static int __devinit ep93xx_keypad_probe(struct platform_device *pdev) { struct ep93xx_keypad *keypad; + const struct matrix_keymap_data *keymap_data; struct input_dev *input_dev; struct resource *res; int err; @@ -270,6 +253,12 @@ static int __devinit ep93xx_keypad_probe(struct platform_device *pdev) goto failed_free; } + keymap_data = keypad->pdata->keymap_data; + if (!keymap_data) { + err = -EINVAL; + goto failed_free; + } + keypad->irq = platform_get_irq(pdev, 0); if (!keypad->irq) { err = -ENXIO; @@ -317,9 +306,9 @@ static int __devinit ep93xx_keypad_probe(struct platform_device *pdev) input_dev->open = ep93xx_keypad_open; input_dev->close = ep93xx_keypad_close; input_dev->dev.parent = &pdev->dev; - input_dev->keycode = keypad->matrix_keycodes; - input_dev->keycodesize = sizeof(keypad->matrix_keycodes[0]); - input_dev->keycodemax = ARRAY_SIZE(keypad->matrix_keycodes); + input_dev->keycode = keypad->keycodes; + input_dev->keycodesize = sizeof(keypad->keycodes[0]); + input_dev->keycodemax = ARRAY_SIZE(keypad->keycodes); input_set_drvdata(input_dev, keypad); @@ -327,7 +316,8 @@ static int __devinit ep93xx_keypad_probe(struct platform_device *pdev) if (keypad->pdata->flags & EP93XX_KEYPAD_AUTOREPEAT) input_dev->evbit[0] |= BIT_MASK(EV_REP); - ep93xx_keypad_build_keycode(keypad); + matrix_keypad_build_keymap(keymap_data, 3, + input_dev->keycode, input_dev->keybit); platform_set_drvdata(pdev, keypad); err = request_irq(keypad->irq, ep93xx_keypad_irq_handler, -- cgit v1.2.3 From 5a9003db1faa34c0560561f66b263f288d623324 Mon Sep 17 00:00:00 2001 From: Michael Hennerich Date: Tue, 19 Jan 2010 00:28:44 -0800 Subject: Input: ADP5588 - add support for ADP5587 devices The ADP5587 is quite similar to the ADP5588 but features a greater I/O voltage range and lacks the Dual Light Sensor Interface. This new part is also supported by this driver. Signed-off-by: Michael Hennerich Signed-off-by: Mike Frysinger Signed-off-by: Dmitry Torokhov --- drivers/input/keyboard/Kconfig | 4 ++-- drivers/input/keyboard/adp5588-keys.c | 6 ++++-- 2 files changed, 6 insertions(+), 4 deletions(-) (limited to 'drivers/input') diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig index 02c836e11813..c72283c6916f 100644 --- a/drivers/input/keyboard/Kconfig +++ b/drivers/input/keyboard/Kconfig @@ -35,10 +35,10 @@ config KEYBOARD_ADP5520 be called adp5520-keys. config KEYBOARD_ADP5588 - tristate "ADP5588 I2C QWERTY Keypad and IO Expander" + tristate "ADP5588/87 I2C QWERTY Keypad and IO Expander" depends on I2C help - Say Y here if you want to use a ADP5588 attached to your + Say Y here if you want to use a ADP5588/87 attached to your system I2C bus. To compile this driver as a module, choose M here: the diff --git a/drivers/input/keyboard/adp5588-keys.c b/drivers/input/keyboard/adp5588-keys.c index d48c808d5928..6737fe4c0f12 100644 --- a/drivers/input/keyboard/adp5588-keys.c +++ b/drivers/input/keyboard/adp5588-keys.c @@ -1,6 +1,7 @@ /* * File: drivers/input/keyboard/adp5588_keys.c - * Description: keypad driver for ADP5588 I2C QWERTY Keypad and IO Expander + * Description: keypad driver for ADP5588 and ADP5587 + * I2C QWERTY Keypad and IO Expander * Bugs: Enter bugs at http://blackfin.uclinux.org/ * * Copyright (C) 2008-2009 Analog Devices Inc. @@ -327,6 +328,7 @@ static struct dev_pm_ops adp5588_dev_pm_ops = { static const struct i2c_device_id adp5588_id[] = { { KBUILD_MODNAME, 0 }, + { "adp5587-keys", 0 }, { } }; MODULE_DEVICE_TABLE(i2c, adp5588_id); @@ -357,5 +359,5 @@ module_exit(adp5588_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Michael Hennerich "); -MODULE_DESCRIPTION("ADP5588 Keypad driver"); +MODULE_DESCRIPTION("ADP5588/87 Keypad driver"); MODULE_ALIAS("platform:adp5588-keys"); -- cgit v1.2.3 From 3bf127637e22ddf95e67e10a23c339cee3d52429 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Thu, 21 Jan 2010 00:02:36 -0800 Subject: Input: sh_keysc - add mode 4 and mode 5 support Add Mode 4 and Mode 5 support to the SH_KEYSC driver. These modes allow slightly larger key pad matrixes. While at it, make use of resource_size(). Signed-off-by: Magnus Damm Signed-off-by: Dmitry Torokhov --- drivers/input/keyboard/sh_keysc.c | 6 +++--- include/linux/input/sh_keysc.h | 5 +++-- 2 files changed, 6 insertions(+), 5 deletions(-) (limited to 'drivers/input') diff --git a/drivers/input/keyboard/sh_keysc.c b/drivers/input/keyboard/sh_keysc.c index 076111fc72d2..25706f802258 100644 --- a/drivers/input/keyboard/sh_keysc.c +++ b/drivers/input/keyboard/sh_keysc.c @@ -36,6 +36,8 @@ static const struct { [SH_KEYSC_MODE_1] = { 0, 6, 5 }, [SH_KEYSC_MODE_2] = { 1, 5, 6 }, [SH_KEYSC_MODE_3] = { 2, 4, 7 }, + [SH_KEYSC_MODE_4] = { 3, 6, 6 }, + [SH_KEYSC_MODE_5] = { 4, 6, 7 }, }; struct sh_keysc_priv { @@ -122,8 +124,6 @@ static irqreturn_t sh_keysc_isr(int irq, void *dev_id) return IRQ_HANDLED; } -#define res_size(res) ((res)->end - (res)->start + 1) - static int __devinit sh_keysc_probe(struct platform_device *pdev) { struct sh_keysc_priv *priv; @@ -164,7 +164,7 @@ static int __devinit sh_keysc_probe(struct platform_device *pdev) memcpy(&priv->pdata, pdev->dev.platform_data, sizeof(priv->pdata)); pdata = &priv->pdata; - priv->iomem_base = ioremap_nocache(res->start, res_size(res)); + priv->iomem_base = ioremap_nocache(res->start, resource_size(res)); if (priv->iomem_base == NULL) { dev_err(&pdev->dev, "failed to remap I/O memory\n"); error = -ENXIO; diff --git a/include/linux/input/sh_keysc.h b/include/linux/input/sh_keysc.h index c211b5cf08e6..2aff38bcf2ba 100644 --- a/include/linux/input/sh_keysc.h +++ b/include/linux/input/sh_keysc.h @@ -1,10 +1,11 @@ #ifndef __SH_KEYSC_H__ #define __SH_KEYSC_H__ -#define SH_KEYSC_MAXKEYS 30 +#define SH_KEYSC_MAXKEYS 42 struct sh_keysc_info { - enum { SH_KEYSC_MODE_1, SH_KEYSC_MODE_2, SH_KEYSC_MODE_3 } mode; + enum { SH_KEYSC_MODE_1, SH_KEYSC_MODE_2, SH_KEYSC_MODE_3, + SH_KEYSC_MODE_4, SH_KEYSC_MODE_5 } mode; int scan_timing; /* 0 -> 7, see KYCR1, SCN[2:0] */ int delay; int kycr2_delay; -- cgit v1.2.3 From ce841b945b84bf7360aa32e60ddaa1e9ccae3e96 Mon Sep 17 00:00:00 2001 From: Tobias Klauser Date: Thu, 21 Jan 2010 23:52:37 -0800 Subject: Input: xilinx_ps2 - use resource_size Use the resource_size inline function instead of manually calculating the resource size. Signed-off-by: Tobias Klauser Acked-by: John Linn Signed-off-by: Dmitry Torokhov --- drivers/input/serio/xilinx_ps2.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/input') diff --git a/drivers/input/serio/xilinx_ps2.c b/drivers/input/serio/xilinx_ps2.c index 78c64fb8a4b0..8298e1f68234 100644 --- a/drivers/input/serio/xilinx_ps2.c +++ b/drivers/input/serio/xilinx_ps2.c @@ -270,7 +270,7 @@ static int __devinit xps2_of_probe(struct of_device *ofdev, drvdata->irq = r_irq.start; phys_addr = r_mem.start; - remap_size = r_mem.end - r_mem.start + 1; + remap_size = resource_size(&r_mem); 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); @@ -344,7 +344,7 @@ static int __devexit xps2_of_remove(struct of_device *of_dev) 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); + release_mem_region(r_mem.start, resource_size(&r_mem)); kfree(drvdata); -- cgit v1.2.3 From 121873059fbe3b4f1ddb4781b578a2128e78be4a Mon Sep 17 00:00:00 2001 From: Benjamin Valentin Date: Thu, 21 Jan 2010 20:19:06 -0800 Subject: Input: xpad - add rumble support for original xbox controller Signed-off-by: Benjamin Valentin Signed-off-by: Dmitry Torokhov --- drivers/input/joystick/xpad.c | 53 ++++++++++++++++++++++++++++++------------- 1 file changed, 37 insertions(+), 16 deletions(-) (limited to 'drivers/input') diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c index 66be6901619d..9b3353b404da 100644 --- a/drivers/input/joystick/xpad.c +++ b/drivers/input/joystick/xpad.c @@ -530,7 +530,7 @@ static int xpad_init_output(struct usb_interface *intf, struct usb_xpad *xpad) struct usb_endpoint_descriptor *ep_irq_out; int error = -ENOMEM; - if (xpad->xtype != XTYPE_XBOX360) + if (xpad->xtype != XTYPE_XBOX360 && xpad->xtype != XTYPE_XBOX) return 0; xpad->odata = usb_buffer_alloc(xpad->udev, XPAD_PKT_LEN, @@ -560,13 +560,13 @@ static int xpad_init_output(struct usb_interface *intf, struct usb_xpad *xpad) static void xpad_stop_output(struct usb_xpad *xpad) { - if (xpad->xtype == XTYPE_XBOX360) + if (xpad->xtype == XTYPE_XBOX360 || xpad->xtype == XTYPE_XBOX) usb_kill_urb(xpad->irq_out); } static void xpad_deinit_output(struct usb_xpad *xpad) { - if (xpad->xtype == XTYPE_XBOX360) { + if (xpad->xtype == XTYPE_XBOX360 || xpad->xtype == XTYPE_XBOX) { usb_free_urb(xpad->irq_out); usb_buffer_free(xpad->udev, XPAD_PKT_LEN, xpad->odata, xpad->odata_dma); @@ -579,24 +579,45 @@ static void xpad_stop_output(struct usb_xpad *xpad) {} #endif #ifdef CONFIG_JOYSTICK_XPAD_FF -static int xpad_play_effect(struct input_dev *dev, void *data, - struct ff_effect *effect) +static int xpad_play_effect(struct input_dev *dev, void *data, struct ff_effect *effect) { struct usb_xpad *xpad = input_get_drvdata(dev); if (effect->type == FF_RUMBLE) { __u16 strong = effect->u.rumble.strong_magnitude; __u16 weak = effect->u.rumble.weak_magnitude; - xpad->odata[0] = 0x00; - xpad->odata[1] = 0x08; - xpad->odata[2] = 0x00; - xpad->odata[3] = strong / 256; - xpad->odata[4] = weak / 256; - xpad->odata[5] = 0x00; - xpad->odata[6] = 0x00; - xpad->odata[7] = 0x00; - xpad->irq_out->transfer_buffer_length = 8; - usb_submit_urb(xpad->irq_out, GFP_ATOMIC); + + switch (xpad->xtype) { + + case XTYPE_XBOX: + xpad->odata[0] = 0x00; + xpad->odata[1] = 0x06; + xpad->odata[2] = 0x00; + xpad->odata[3] = strong / 256; /* left actuator */ + xpad->odata[4] = 0x00; + xpad->odata[5] = weak / 256; /* right actuator */ + xpad->irq_out->transfer_buffer_length = 6; + + return usb_submit_urb(xpad->irq_out, GFP_ATOMIC); + + case XTYPE_XBOX360: + xpad->odata[0] = 0x00; + xpad->odata[1] = 0x08; + xpad->odata[2] = 0x00; + xpad->odata[3] = strong / 256; /* left actuator? */ + xpad->odata[4] = weak / 256; /* right actuator? */ + xpad->odata[5] = 0x00; + xpad->odata[6] = 0x00; + xpad->odata[7] = 0x00; + xpad->irq_out->transfer_buffer_length = 8; + + return usb_submit_urb(xpad->irq_out, GFP_ATOMIC); + + default: + dbg("%s - rumble command sent to unsupported xpad type: %d", + __func__, xpad->xtype); + return -1; + } } return 0; @@ -604,7 +625,7 @@ static int xpad_play_effect(struct input_dev *dev, void *data, static int xpad_init_ff(struct usb_xpad *xpad) { - if (xpad->xtype != XTYPE_XBOX360) + if (xpad->xtype != XTYPE_XBOX360 && xpad->xtype != XTYPE_XBOX) return 0; input_set_capability(xpad->dev, EV_FF, FF_RUMBLE); -- cgit v1.2.3 From 439913fffd39374c3737186b22d2d56c3a0ae526 Mon Sep 17 00:00:00 2001 From: Lin Ming Date: Thu, 28 Jan 2010 10:53:19 +0800 Subject: ACPI: replace acpi_integer by u64 acpi_integer is now obsolete and removed from the ACPICA code base, replaced by u64. Signed-off-by: Lin Ming Signed-off-by: Len Brown --- arch/ia64/hp/common/aml_nfw.c | 6 ++--- arch/x86/kernel/cpu/cpufreq/powernow-k8.c | 6 ++--- drivers/acpi/battery.c | 4 +-- drivers/acpi/ec.c | 4 +-- drivers/acpi/glue.c | 4 +-- drivers/acpi/osl.c | 4 +-- drivers/acpi/power_meter.c | 30 +++++++++++----------- drivers/acpi/processor_idle.c | 2 +- drivers/acpi/processor_throttling.c | 24 +++++++++--------- drivers/acpi/utils.c | 16 ++++++------ drivers/acpi/video.c | 2 +- drivers/ata/libata-acpi.c | 4 +-- drivers/ide/ide-acpi.c | 8 +++--- drivers/input/misc/atlas_btns.c | 2 +- drivers/pci/pci-acpi.c | 2 +- drivers/platform/x86/toshiba_bluetooth.c | 4 +-- drivers/platform/x86/wmi.c | 4 +-- include/acpi/acpi_bus.h | 6 ++--- include/acpi/processor.h | 42 +++++++++++++++---------------- 19 files changed, 87 insertions(+), 87 deletions(-) (limited to 'drivers/input') diff --git a/arch/ia64/hp/common/aml_nfw.c b/arch/ia64/hp/common/aml_nfw.c index 4abd2c79bb1d..22078486d35d 100644 --- a/arch/ia64/hp/common/aml_nfw.c +++ b/arch/ia64/hp/common/aml_nfw.c @@ -77,7 +77,7 @@ static void aml_nfw_execute(struct ia64_nfw_context *c) c->arg[4], c->arg[5], c->arg[6], c->arg[7]); } -static void aml_nfw_read_arg(u8 *offset, u32 bit_width, acpi_integer *value) +static void aml_nfw_read_arg(u8 *offset, u32 bit_width, u64 *value) { switch (bit_width) { case 8: @@ -95,7 +95,7 @@ static void aml_nfw_read_arg(u8 *offset, u32 bit_width, acpi_integer *value) } } -static void aml_nfw_write_arg(u8 *offset, u32 bit_width, acpi_integer *value) +static void aml_nfw_write_arg(u8 *offset, u32 bit_width, u64 *value) { switch (bit_width) { case 8: @@ -114,7 +114,7 @@ static void aml_nfw_write_arg(u8 *offset, u32 bit_width, acpi_integer *value) } static acpi_status aml_nfw_handler(u32 function, acpi_physical_address address, - u32 bit_width, acpi_integer *value, void *handler_context, + u32 bit_width, u64 *value, void *handler_context, void *region_context) { struct ia64_nfw_context *context = handler_context; diff --git a/arch/x86/kernel/cpu/cpufreq/powernow-k8.c b/arch/x86/kernel/cpu/cpufreq/powernow-k8.c index f125e5c551c0..55d42bc443e8 100644 --- a/arch/x86/kernel/cpu/cpufreq/powernow-k8.c +++ b/arch/x86/kernel/cpu/cpufreq/powernow-k8.c @@ -806,7 +806,7 @@ static int find_psb_table(struct powernow_k8_data *data) static void powernow_k8_acpi_pst_values(struct powernow_k8_data *data, unsigned int index) { - acpi_integer control; + u64 control; if (!data->acpi_data.state_count || (cpu_family == CPU_HW_PSTATE)) return; @@ -824,7 +824,7 @@ static int powernow_k8_cpu_init_acpi(struct powernow_k8_data *data) { struct cpufreq_frequency_table *powernow_table; int ret_val = -ENODEV; - acpi_integer control, status; + u64 control, status; if (acpi_processor_register_performance(&data->acpi_data, data->cpu)) { dprintk("register performance failed: bad ACPI data\n"); @@ -948,7 +948,7 @@ static int fill_powernow_table_fidvid(struct powernow_k8_data *data, u32 fid; u32 vid; u32 freq, index; - acpi_integer status, control; + u64 status, control; if (data->exttype) { status = data->acpi_data.states[i].status; diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c index cada73ffdfa7..58d2c91ba62b 100644 --- a/drivers/acpi/battery.c +++ b/drivers/acpi/battery.c @@ -324,8 +324,8 @@ static int extract_package(struct acpi_battery *battery, strncpy(ptr, element->string.pointer, 32); else if (element->type == ACPI_TYPE_INTEGER) { strncpy(ptr, (u8 *)&element->integer.value, - sizeof(acpi_integer)); - ptr[sizeof(acpi_integer)] = 0; + sizeof(u64)); + ptr[sizeof(u64)] = 0; } else *ptr = 0; /* don't have value */ } else { diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index d6471bb6852f..748ced85dec5 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c @@ -589,7 +589,7 @@ static u32 acpi_ec_gpe_handler(void *data) static acpi_status acpi_ec_space_handler(u32 function, acpi_physical_address address, - u32 bits, acpi_integer *value, + u32 bits, u64 *value, void *handler_context, void *region_context) { struct acpi_ec *ec = handler_context; @@ -620,7 +620,7 @@ acpi_ec_space_handler(u32 function, acpi_physical_address address, ++address; if (function == ACPI_READ) { result = acpi_ec_read(ec, address, &temp); - (*value) |= ((acpi_integer)temp) << i; + (*value) |= ((u64)temp) << i; } else { temp = 0xff & ((*value) >> i); result = acpi_ec_write(ec, address, temp); diff --git a/drivers/acpi/glue.c b/drivers/acpi/glue.c index 4c8fcff662cf..6d5b64b7d526 100644 --- a/drivers/acpi/glue.c +++ b/drivers/acpi/glue.c @@ -87,7 +87,7 @@ static int acpi_find_bridge_device(struct device *dev, acpi_handle * handle) /* Get device's handler per its address under its parent */ struct acpi_find_child { acpi_handle handle; - acpi_integer address; + u64 address; }; static acpi_status @@ -106,7 +106,7 @@ do_acpi_find_child(acpi_handle handle, u32 lvl, void *context, void **rv) return AE_OK; } -acpi_handle acpi_get_child(acpi_handle parent, acpi_integer address) +acpi_handle acpi_get_child(acpi_handle parent, u64 address) { struct acpi_find_child find = { NULL, address }; diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c index 02e8464e480f..8e6d8665f0ae 100644 --- a/drivers/acpi/osl.c +++ b/drivers/acpi/osl.c @@ -436,7 +436,7 @@ acpi_status acpi_os_remove_interrupt_handler(u32 irq, acpi_osd_handler handler) * Running in interpreter thread context, safe to sleep */ -void acpi_os_sleep(acpi_integer ms) +void acpi_os_sleep(u64 ms) { schedule_timeout_interruptible(msecs_to_jiffies(ms)); } @@ -603,7 +603,7 @@ acpi_os_read_pci_configuration(struct acpi_pci_id * pci_id, u32 reg, acpi_status acpi_os_write_pci_configuration(struct acpi_pci_id * pci_id, u32 reg, - acpi_integer value, u32 width) + u64 value, u32 width) { int result, size; diff --git a/drivers/acpi/power_meter.c b/drivers/acpi/power_meter.c index dc4ffadf8122..834c5af0de4b 100644 --- a/drivers/acpi/power_meter.c +++ b/drivers/acpi/power_meter.c @@ -71,17 +71,17 @@ static const struct acpi_device_id power_meter_ids[] = { MODULE_DEVICE_TABLE(acpi, power_meter_ids); struct acpi_power_meter_capabilities { - acpi_integer flags; - acpi_integer units; - acpi_integer type; - acpi_integer accuracy; - acpi_integer sampling_time; - acpi_integer min_avg_interval; - acpi_integer max_avg_interval; - acpi_integer hysteresis; - acpi_integer configurable_cap; - acpi_integer min_cap; - acpi_integer max_cap; + u64 flags; + u64 units; + u64 type; + u64 accuracy; + u64 sampling_time; + u64 min_avg_interval; + u64 max_avg_interval; + u64 hysteresis; + u64 configurable_cap; + u64 min_cap; + u64 max_cap; }; struct acpi_power_meter_resource { @@ -93,9 +93,9 @@ struct acpi_power_meter_resource { acpi_string model_number; acpi_string serial_number; acpi_string oem_info; - acpi_integer power; - acpi_integer cap; - acpi_integer avg_interval; + u64 power; + u64 cap; + u64 avg_interval; int sensors_valid; unsigned long sensors_last_updated; struct sensor_device_attribute sensors[NUM_SENSORS]; @@ -402,7 +402,7 @@ static ssize_t show_val(struct device *dev, struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); struct acpi_device *acpi_dev = to_acpi_device(dev); struct acpi_power_meter_resource *resource = acpi_dev->driver_data; - acpi_integer val = 0; + u64 val = 0; switch (attr->index) { case 0: diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c index 7c0441f63b39..3455d7abf5f3 100644 --- a/drivers/acpi/processor_idle.c +++ b/drivers/acpi/processor_idle.c @@ -352,7 +352,7 @@ static int acpi_processor_get_power_info_default(struct acpi_processor *pr) static int acpi_processor_get_power_info_cst(struct acpi_processor *pr) { acpi_status status = 0; - acpi_integer count; + u64 count; int current_count; int i; struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; diff --git a/drivers/acpi/processor_throttling.c b/drivers/acpi/processor_throttling.c index 1c5d7a8b2fdf..7ded7542fc9d 100644 --- a/drivers/acpi/processor_throttling.c +++ b/drivers/acpi/processor_throttling.c @@ -660,7 +660,7 @@ static int acpi_processor_get_throttling_fadt(struct acpi_processor *pr) #ifdef CONFIG_X86 static int acpi_throttling_rdmsr(struct acpi_processor *pr, - acpi_integer * value) + u64 *value) { struct cpuinfo_x86 *c; u64 msr_high, msr_low; @@ -681,13 +681,13 @@ static int acpi_throttling_rdmsr(struct acpi_processor *pr, rdmsr_safe(MSR_IA32_THERM_CONTROL, (u32 *)&msr_low , (u32 *) &msr_high); msr = (msr_high << 32) | msr_low; - *value = (acpi_integer) msr; + *value = (u64) msr; ret = 0; } return ret; } -static int acpi_throttling_wrmsr(struct acpi_processor *pr, acpi_integer value) +static int acpi_throttling_wrmsr(struct acpi_processor *pr, u64 value) { struct cpuinfo_x86 *c; unsigned int cpu; @@ -711,14 +711,14 @@ static int acpi_throttling_wrmsr(struct acpi_processor *pr, acpi_integer value) } #else static int acpi_throttling_rdmsr(struct acpi_processor *pr, - acpi_integer * value) + u64 *value) { printk(KERN_ERR PREFIX "HARDWARE addr space,NOT supported yet\n"); return -1; } -static int acpi_throttling_wrmsr(struct acpi_processor *pr, acpi_integer value) +static int acpi_throttling_wrmsr(struct acpi_processor *pr, u64 value) { printk(KERN_ERR PREFIX "HARDWARE addr space,NOT supported yet\n"); @@ -727,7 +727,7 @@ static int acpi_throttling_wrmsr(struct acpi_processor *pr, acpi_integer value) #endif static int acpi_read_throttling_status(struct acpi_processor *pr, - acpi_integer *value) + u64 *value) { u32 bit_width, bit_offset; u64 ptc_value; @@ -746,7 +746,7 @@ static int acpi_read_throttling_status(struct acpi_processor *pr, address, (u32 *) &ptc_value, (u32) (bit_width + bit_offset)); ptc_mask = (1 << bit_width) - 1; - *value = (acpi_integer) ((ptc_value >> bit_offset) & ptc_mask); + *value = (u64) ((ptc_value >> bit_offset) & ptc_mask); ret = 0; break; case ACPI_ADR_SPACE_FIXED_HARDWARE: @@ -760,7 +760,7 @@ static int acpi_read_throttling_status(struct acpi_processor *pr, } static int acpi_write_throttling_state(struct acpi_processor *pr, - acpi_integer value) + u64 value) { u32 bit_width, bit_offset; u64 ptc_value; @@ -793,7 +793,7 @@ static int acpi_write_throttling_state(struct acpi_processor *pr, } static int acpi_get_throttling_state(struct acpi_processor *pr, - acpi_integer value) + u64 value) { int i; @@ -808,7 +808,7 @@ static int acpi_get_throttling_state(struct acpi_processor *pr, } static int acpi_get_throttling_value(struct acpi_processor *pr, - int state, acpi_integer *value) + int state, u64 *value) { int ret = -1; @@ -826,7 +826,7 @@ static int acpi_processor_get_throttling_ptc(struct acpi_processor *pr) { int state = 0; int ret; - acpi_integer value; + u64 value; if (!pr) return -EINVAL; @@ -993,7 +993,7 @@ static int acpi_processor_set_throttling_ptc(struct acpi_processor *pr, int state, bool force) { int ret; - acpi_integer value; + u64 value; if (!pr) return -EINVAL; diff --git a/drivers/acpi/utils.c b/drivers/acpi/utils.c index 811fec10462b..11882dbe2094 100644 --- a/drivers/acpi/utils.c +++ b/drivers/acpi/utils.c @@ -107,12 +107,12 @@ acpi_extract_package(union acpi_object *package, case ACPI_TYPE_INTEGER: switch (format_string[i]) { case 'N': - size_required += sizeof(acpi_integer); - tail_offset += sizeof(acpi_integer); + size_required += sizeof(u64); + tail_offset += sizeof(u64); break; case 'S': size_required += - sizeof(char *) + sizeof(acpi_integer) + + sizeof(char *) + sizeof(u64) + sizeof(char); tail_offset += sizeof(char *); break; @@ -193,17 +193,17 @@ acpi_extract_package(union acpi_object *package, case ACPI_TYPE_INTEGER: switch (format_string[i]) { case 'N': - *((acpi_integer *) head) = + *((u64 *) head) = element->integer.value; - head += sizeof(acpi_integer); + head += sizeof(u64); break; case 'S': pointer = (u8 **) head; *pointer = tail; - *((acpi_integer *) tail) = + *((u64 *) tail) = element->integer.value; - head += sizeof(acpi_integer *); - tail += sizeof(acpi_integer); + head += sizeof(u64 *); + tail += sizeof(u64); /* NULL terminate string */ *tail = (char)0; tail += sizeof(char); diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c index b765790b32be..6e9b49149fce 100644 --- a/drivers/acpi/video.c +++ b/drivers/acpi/video.c @@ -759,7 +759,7 @@ acpi_video_bus_POST_options(struct acpi_video_bus *video, static int acpi_video_bus_DOS(struct acpi_video_bus *video, int bios_flag, int lcd_flag) { - acpi_integer status = 0; + u64 status = 0; union acpi_object arg0 = { ACPI_TYPE_INTEGER }; struct acpi_object_list args = { 1, &arg0 }; diff --git a/drivers/ata/libata-acpi.c b/drivers/ata/libata-acpi.c index 1245838ac13d..292fdbc0431a 100644 --- a/drivers/ata/libata-acpi.c +++ b/drivers/ata/libata-acpi.c @@ -64,7 +64,7 @@ void ata_acpi_associate_sata_port(struct ata_port *ap) WARN_ON(!(ap->flags & ATA_FLAG_ACPI_SATA)); if (!sata_pmp_attached(ap)) { - acpi_integer adr = SATA_ADR(ap->port_no, NO_PORT_MULT); + u64 adr = SATA_ADR(ap->port_no, NO_PORT_MULT); ap->link.device->acpi_handle = acpi_get_child(ap->host->acpi_handle, adr); @@ -74,7 +74,7 @@ void ata_acpi_associate_sata_port(struct ata_port *ap) ap->link.device->acpi_handle = NULL; ata_for_each_link(link, ap, EDGE) { - acpi_integer adr = SATA_ADR(ap->port_no, link->pmp); + u64 adr = SATA_ADR(ap->port_no, link->pmp); link->device->acpi_handle = acpi_get_child(ap->host->acpi_handle, adr); diff --git a/drivers/ide/ide-acpi.c b/drivers/ide/ide-acpi.c index c0cf45a11b93..5cb01e5c323c 100644 --- a/drivers/ide/ide-acpi.c +++ b/drivers/ide/ide-acpi.c @@ -108,11 +108,11 @@ bool ide_port_acpi(ide_hwif_t *hwif) * Returns 0 on success, <0 on error. */ static int ide_get_dev_handle(struct device *dev, acpi_handle *handle, - acpi_integer *pcidevfn) + u64 *pcidevfn) { struct pci_dev *pdev = to_pci_dev(dev); unsigned int bus, devnum, func; - acpi_integer addr; + u64 addr; acpi_handle dev_handle; acpi_status status; struct acpi_device_info *dinfo = NULL; @@ -122,7 +122,7 @@ static int ide_get_dev_handle(struct device *dev, acpi_handle *handle, devnum = PCI_SLOT(pdev->devfn); func = PCI_FUNC(pdev->devfn); /* ACPI _ADR encoding for PCI bus: */ - addr = (acpi_integer)(devnum << 16 | func); + addr = (u64)(devnum << 16 | func); DEBPRINT("ENTER: pci %02x:%02x.%01x\n", bus, devnum, func); @@ -169,7 +169,7 @@ static acpi_handle ide_acpi_hwif_get_handle(ide_hwif_t *hwif) { struct device *dev = hwif->gendev.parent; acpi_handle uninitialized_var(dev_handle); - acpi_integer pcidevfn; + u64 pcidevfn; acpi_handle chan_handle; int err; diff --git a/drivers/input/misc/atlas_btns.c b/drivers/input/misc/atlas_btns.c index 1b871917340a..dfaa9a045ed8 100644 --- a/drivers/input/misc/atlas_btns.c +++ b/drivers/input/misc/atlas_btns.c @@ -47,7 +47,7 @@ static acpi_status acpi_atlas_button_setup(acpi_handle region_handle, static acpi_status acpi_atlas_button_handler(u32 function, acpi_physical_address address, - u32 bit_width, acpi_integer *value, + u32 bit_width, u64 *value, void *handler_context, void *region_context) { acpi_status status; diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c index 7e2829538a4c..441326c44138 100644 --- a/drivers/pci/pci-acpi.c +++ b/drivers/pci/pci-acpi.c @@ -143,7 +143,7 @@ static struct pci_platform_pm_ops acpi_pci_platform_pm = { static int acpi_pci_find_device(struct device *dev, acpi_handle *handle) { struct pci_dev * pci_dev; - acpi_integer addr; + u64 addr; pci_dev = to_pci_dev(dev); /* Please ref to ACPI spec for the syntax of _ADR */ diff --git a/drivers/platform/x86/toshiba_bluetooth.c b/drivers/platform/x86/toshiba_bluetooth.c index a350418e87ea..944068611919 100644 --- a/drivers/platform/x86/toshiba_bluetooth.c +++ b/drivers/platform/x86/toshiba_bluetooth.c @@ -57,7 +57,7 @@ static struct acpi_driver toshiba_bt_rfkill_driver = { static int toshiba_bluetooth_enable(acpi_handle handle) { acpi_status res1, res2; - acpi_integer result; + u64 result; /* * Query ACPI to verify RFKill switch is set to 'on'. @@ -95,7 +95,7 @@ static int toshiba_bt_resume(struct acpi_device *device) static int toshiba_bt_rfkill_add(struct acpi_device *device) { acpi_status status; - acpi_integer bt_present; + u64 bt_present; int result = -ENODEV; /* diff --git a/drivers/platform/x86/wmi.c b/drivers/platform/x86/wmi.c index b104302fea0a..09e9918c69c1 100644 --- a/drivers/platform/x86/wmi.c +++ b/drivers/platform/x86/wmi.c @@ -796,7 +796,7 @@ static __init acpi_status parse_wdg(acpi_handle handle) */ static acpi_status acpi_wmi_ec_space_handler(u32 function, acpi_physical_address address, - u32 bits, acpi_integer * value, + u32 bits, u64 *value, void *handler_context, void *region_context) { int result = 0, i = 0; @@ -813,7 +813,7 @@ acpi_wmi_ec_space_handler(u32 function, acpi_physical_address address, if (function == ACPI_READ) { result = ec_read(address, &temp); - (*value) |= ((acpi_integer)temp) << i; + (*value) |= ((u64)temp) << i; } else { temp = 0xff & ((*value) >> i); result = ec_write(address, temp); diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h index 3cd9ccdcbd8f..71c105c9b0ee 100644 --- a/include/acpi/acpi_bus.h +++ b/include/acpi/acpi_bus.h @@ -250,8 +250,8 @@ struct acpi_device_wakeup_state { struct acpi_device_wakeup { acpi_handle gpe_device; - acpi_integer gpe_number; - acpi_integer sleep_state; + u64 gpe_number; + u64 sleep_state; struct acpi_handle_list resources; struct acpi_device_wakeup_state state; struct acpi_device_wakeup_flags flags; @@ -380,7 +380,7 @@ struct acpi_pci_root { }; /* helper */ -acpi_handle acpi_get_child(acpi_handle, acpi_integer); +acpi_handle acpi_get_child(acpi_handle, u64); int acpi_is_root_bridge(acpi_handle); acpi_handle acpi_get_pci_rootbridge_handle(unsigned int, unsigned int); struct acpi_pci_root *acpi_pci_find_root(acpi_handle handle); diff --git a/include/acpi/processor.h b/include/acpi/processor.h index 0ea5ef4eb6a9..29831768c0e6 100644 --- a/include/acpi/processor.h +++ b/include/acpi/processor.h @@ -92,11 +92,11 @@ struct acpi_processor_power { /* Performance Management */ struct acpi_psd_package { - acpi_integer num_entries; - acpi_integer revision; - acpi_integer domain; - acpi_integer coord_type; - acpi_integer num_processors; + u64 num_entries; + u64 revision; + u64 domain; + u64 coord_type; + u64 num_processors; } __attribute__ ((packed)); struct acpi_pct_register { @@ -110,12 +110,12 @@ struct acpi_pct_register { } __attribute__ ((packed)); struct acpi_processor_px { - acpi_integer core_frequency; /* megahertz */ - acpi_integer power; /* milliWatts */ - acpi_integer transition_latency; /* microseconds */ - acpi_integer bus_master_latency; /* microseconds */ - acpi_integer control; /* control value */ - acpi_integer status; /* success indicator */ + u64 core_frequency; /* megahertz */ + u64 power; /* milliWatts */ + u64 transition_latency; /* microseconds */ + u64 bus_master_latency; /* microseconds */ + u64 control; /* control value */ + u64 status; /* success indicator */ }; struct acpi_processor_performance { @@ -133,11 +133,11 @@ struct acpi_processor_performance { /* Throttling Control */ struct acpi_tsd_package { - acpi_integer num_entries; - acpi_integer revision; - acpi_integer domain; - acpi_integer coord_type; - acpi_integer num_processors; + u64 num_entries; + u64 revision; + u64 domain; + u64 coord_type; + u64 num_processors; } __attribute__ ((packed)); struct acpi_ptc_register { @@ -151,11 +151,11 @@ struct acpi_ptc_register { } __attribute__ ((packed)); struct acpi_processor_tx_tss { - acpi_integer freqpercentage; /* */ - acpi_integer power; /* milliWatts */ - acpi_integer transition_latency; /* microseconds */ - acpi_integer control; /* control value */ - acpi_integer status; /* success indicator */ + u64 freqpercentage; /* */ + u64 power; /* milliWatts */ + u64 transition_latency; /* microseconds */ + u64 control; /* control value */ + u64 status; /* success indicator */ }; struct acpi_processor_tx { u16 power; -- cgit v1.2.3 From dcfc32babbece923381bd3bffaf17373b5d97568 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Thu, 28 Jan 2010 22:37:39 -0800 Subject: Input: wm97xx - provide coordinate logs for accelerated I/O This aids debug of problematic systems. Signed-off-by: Mark Brown Signed-off-by: Dmitry Torokhov --- drivers/input/touchscreen/mainstone-wm97xx.c | 3 +++ drivers/input/touchscreen/zylonite-wm97xx.c | 3 +++ 2 files changed, 6 insertions(+) (limited to 'drivers/input') diff --git a/drivers/input/touchscreen/mainstone-wm97xx.c b/drivers/input/touchscreen/mainstone-wm97xx.c index 6cdcf2a6e036..b6b8b1c7ecea 100644 --- a/drivers/input/touchscreen/mainstone-wm97xx.c +++ b/drivers/input/touchscreen/mainstone-wm97xx.c @@ -153,6 +153,9 @@ static int wm97xx_acc_pen_down(struct wm97xx *wm) if (pressure) p = MODR; + dev_dbg(wm->dev, "Raw coordinates: x=%x, y=%x, p=%x\n", + x, y, p); + /* are samples valid */ if ((x & WM97XX_ADCSRC_MASK) != WM97XX_ADCSEL_X || (y & WM97XX_ADCSRC_MASK) != WM97XX_ADCSEL_Y || diff --git a/drivers/input/touchscreen/zylonite-wm97xx.c b/drivers/input/touchscreen/zylonite-wm97xx.c index eca54dbdf493..048849867643 100644 --- a/drivers/input/touchscreen/zylonite-wm97xx.c +++ b/drivers/input/touchscreen/zylonite-wm97xx.c @@ -118,6 +118,9 @@ static int wm97xx_acc_pen_down(struct wm97xx *wm) if (pressure) p = MODR; + dev_dbg(wm->dev, "Raw coordinates: x=%x, y=%x, p=%x\n", + x, y, p); + /* are samples valid */ if ((x & WM97XX_ADCSRC_MASK) != WM97XX_ADCSEL_X || (y & WM97XX_ADCSRC_MASK) != WM97XX_ADCSEL_Y || -- cgit v1.2.3 From 45cdba4d376adfd30cfbda1b7d43110818d967cc Mon Sep 17 00:00:00 2001 From: Thadeu Lima de Souza Cascardo Date: Fri, 29 Jan 2010 23:53:57 -0800 Subject: Input: uinput - remove BKL from uinput_open function Commit 8702965848ed4bee27486a3e3d2ae34ebba6dd83 pushed down the BKL into uinput open function. However, there's nothing that needs locking in there. Signed-off-by: Thadeu Lima de Souza Cascardo Signed-off-by: Dmitry Torokhov --- drivers/input/misc/uinput.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'drivers/input') diff --git a/drivers/input/misc/uinput.c b/drivers/input/misc/uinput.c index d3f57245420a..18206e18d1b1 100644 --- a/drivers/input/misc/uinput.c +++ b/drivers/input/misc/uinput.c @@ -34,7 +34,6 @@ #include #include #include -#include #include #include #include @@ -284,7 +283,6 @@ static int uinput_open(struct inode *inode, struct file *file) if (!newdev) return -ENOMEM; - lock_kernel(); mutex_init(&newdev->mutex); spin_lock_init(&newdev->requests_lock); init_waitqueue_head(&newdev->requests_waitq); @@ -292,7 +290,6 @@ static int uinput_open(struct inode *inode, struct file *file) newdev->state = UIST_NEW_DEVICE; file->private_data = newdev; - unlock_kernel(); return 0; } -- cgit v1.2.3 From ef7995f4e46b1677f3eaaf547316e1a910b38dcb Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Fri, 29 Jan 2010 23:59:12 -0800 Subject: Input: implement input filters Sometimes it is desirable to suppress certain events from reaching input handlers and thus user space. One such example is Mac mouse button emulation code which catches certain key presses and converts them into button clicks as if they were emitted by a virtual mouse. The original key press events should be completely suppressed, otherwise user space will be confused, and while keyboard driver does it on its own evdev is blissfully unaware of this arrangement. This patch adds notion of 'filter' to the standard input handlers, which may flag event as filtered thus preventing it from reaching other input handlers. Filters don't (nor will they ever) have a notion of priority relative to each other, input core will run all of them first and any one of them may mark event as filtered. This patch is inspired by similar patch by Matthew Garret but the implementation and intended usage are quite different. Signed-off-by: Dmitry Torokhov --- drivers/input/input.c | 41 ++++++++++++++++++++++++++++++++++------- include/linux/input.h | 8 ++++++++ 2 files changed, 42 insertions(+), 7 deletions(-) (limited to 'drivers/input') diff --git a/drivers/input/input.c b/drivers/input/input.c index 6c161e220868..7080a9d4b840 100644 --- a/drivers/input/input.c +++ b/drivers/input/input.c @@ -86,12 +86,14 @@ static int input_defuzz_abs_event(int value, int old_val, int fuzz) } /* - * Pass event through all open handles. This function is called with + * Pass event first through all filters and then, if event has not been + * filtered out, through all open handles. This function is called with * dev->event_lock held and interrupts disabled. */ static void input_pass_event(struct input_dev *dev, unsigned int type, unsigned int code, int value) { + struct input_handler *handler; struct input_handle *handle; rcu_read_lock(); @@ -99,11 +101,25 @@ static void input_pass_event(struct input_dev *dev, handle = rcu_dereference(dev->grab); if (handle) handle->handler->event(handle, type, code, value); - else - list_for_each_entry_rcu(handle, &dev->h_list, d_node) - if (handle->open) - handle->handler->event(handle, - type, code, value); + else { + bool filtered = false; + + list_for_each_entry_rcu(handle, &dev->h_list, d_node) { + if (!handle->open) + continue; + + handler = handle->handler; + if (!handler->filter) { + if (filtered) + break; + + handler->event(handle, type, code, value); + + } else if (handler->filter(handle, type, code, value)) + filtered = true; + } + } + rcu_read_unlock(); } @@ -990,6 +1006,8 @@ static int input_handlers_seq_show(struct seq_file *seq, void *v) union input_seq_state *state = (union input_seq_state *)&seq->private; seq_printf(seq, "N: Number=%u Name=%s", state->pos, handler->name); + if (handler->filter) + seq_puts(seq, " (filter)"); if (handler->fops) seq_printf(seq, " Minor=%d", handler->minor); seq_putc(seq, '\n'); @@ -1803,7 +1821,16 @@ int input_register_handle(struct input_handle *handle) error = mutex_lock_interruptible(&dev->mutex); if (error) return error; - list_add_tail_rcu(&handle->d_node, &dev->h_list); + + /* + * Filters go to the head of the list, normal handlers + * to the tail. + */ + if (handler->filter) + list_add_rcu(&handle->d_node, &dev->h_list); + else + list_add_tail_rcu(&handle->d_node, &dev->h_list); + mutex_unlock(&dev->mutex); /* diff --git a/include/linux/input.h b/include/linux/input.h index 7be8a6537b57..6c9d3d49fa91 100644 --- a/include/linux/input.h +++ b/include/linux/input.h @@ -1198,6 +1198,8 @@ struct input_handle; * @event: event handler. This method is being called by input core with * interrupts disabled and dev->event_lock spinlock held and so * it may not sleep + * @filter: similar to @event; separates normal event handlers from + * "filters". * @connect: called when attaching a handler to an input device * @disconnect: disconnects a handler from input device * @start: starts handler for given handle. This function is called by @@ -1219,6 +1221,11 @@ struct input_handle; * same time. All of them will get their copy of input event generated by * the device. * + * The very same structure is used to implement input filters. Input core + * allows filters to run first and will not pass event to regular handlers + * if any of the filters indicate that the event should be filtered (by + * returning %true from their filter() method). + * * Note that input core serializes calls to connect() and disconnect() * methods. */ @@ -1227,6 +1234,7 @@ struct input_handler { void *private; void (*event)(struct input_handle *handle, unsigned int type, unsigned int code, int value); + bool (*filter)(struct input_handle *handle, unsigned int type, unsigned int code, int value); int (*connect)(struct input_handler *handler, struct input_dev *dev, const struct input_device_id *id); void (*disconnect)(struct input_handle *handle); void (*start)(struct input_handle *handle); -- cgit v1.2.3 From 76cdc083f4d1a2a12a961634672fb9ca7adca29c Mon Sep 17 00:00:00 2001 From: Alberto Panizzo Date: Sun, 31 Jan 2010 17:52:07 -0800 Subject: Input: add imx-keypad driver to support the IMX Keypad Port The IMX family of Application Processors is shipped with a Keypad Port supported by this driver. The peripheral can control up to an 8x8 matrix key pad where all the scanning is done via software. The hardware provides two interrupts: one for key presses (KDI) and one for all key releases (KRI). There is also a simple circuit for glitch reduction (said for synchronization) made by two series of 3 D-latches clocked by the keypad-clock that stabilize the interrupts sources. KDI and KRI are fired only if the respective conditions are maintained for at last 4 keypad-clock cycle. Since those circuits are poor for a correct debounce process (the keypad-clock frequency is 32K and bounces longer than 94us are not masked) the driver, when an interrupt arrives, samples the matrix with a period of 10ms until the readins are stable for IMX_KEYPAD_SCANS_FOR_STABILITY times (currently set at 3). After getting stable result appropriate events are sent through the input stack. If some keys are maintained pressed, the driver continues to scan the matrix with a longer period (60ms) to catch possible multiple key presses without overloading the cpu. This process ends when all keys are released. This driver is tested to build in kernel or as a module and follow the specification of Freescale Application processors: i.MX25 i.MX27 i.MX31 i.MX35 i.MX51 especially tested on i.MX31. Signed-off-by: Alberto Panizzo Signed-off-by: Dmitry Torokhov --- drivers/input/keyboard/Kconfig | 9 + drivers/input/keyboard/Makefile | 1 + drivers/input/keyboard/imx_keypad.c | 594 ++++++++++++++++++++++++++++++++++++ 3 files changed, 604 insertions(+) create mode 100644 drivers/input/keyboard/imx_keypad.c (limited to 'drivers/input') diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig index c72283c6916f..616a3916d187 100644 --- a/drivers/input/keyboard/Kconfig +++ b/drivers/input/keyboard/Kconfig @@ -292,6 +292,15 @@ config KEYBOARD_MAX7359 To compile this driver as a module, choose M here: the module will be called max7359_keypad. +config KEYBOARD_IMX + tristate "IMX keypad support" + depends on ARCH_MXC + help + Enable support for IMX keypad port. + + To compile this driver as a module, choose M here: the + module will be called imx_keypad. + config KEYBOARD_NEWTON tristate "Newton keyboard" select SERIO diff --git a/drivers/input/keyboard/Makefile b/drivers/input/keyboard/Makefile index 78654ef65206..706c6b5ed5f4 100644 --- a/drivers/input/keyboard/Makefile +++ b/drivers/input/keyboard/Makefile @@ -17,6 +17,7 @@ obj-$(CONFIG_KEYBOARD_EP93XX) += ep93xx_keypad.o obj-$(CONFIG_KEYBOARD_GPIO) += gpio_keys.o obj-$(CONFIG_KEYBOARD_HIL) += hil_kbd.o obj-$(CONFIG_KEYBOARD_HIL_OLD) += hilkbd.o +obj-$(CONFIG_KEYBOARD_IMX) += imx_keypad.o obj-$(CONFIG_KEYBOARD_HP6XX) += jornada680_kbd.o obj-$(CONFIG_KEYBOARD_HP7XX) += jornada720_kbd.o obj-$(CONFIG_KEYBOARD_LKKBD) += lkkbd.o diff --git a/drivers/input/keyboard/imx_keypad.c b/drivers/input/keyboard/imx_keypad.c new file mode 100644 index 000000000000..2ee5b798024d --- /dev/null +++ b/drivers/input/keyboard/imx_keypad.c @@ -0,0 +1,594 @@ +/* + * Driver for the IMX keypad port. + * Copyright (C) 2009 Alberto Panizzo + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * <>. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * Keypad Controller registers (halfword) + */ +#define KPCR 0x00 /* Keypad Control Register */ + +#define KPSR 0x02 /* Keypad Status Register */ +#define KBD_STAT_KPKD (0x1 << 0) /* Key Press Interrupt Status bit (w1c) */ +#define KBD_STAT_KPKR (0x1 << 1) /* Key Release Interrupt Status bit (w1c) */ +#define KBD_STAT_KDSC (0x1 << 2) /* Key Depress Synch Chain Status bit (w1c)*/ +#define KBD_STAT_KRSS (0x1 << 3) /* Key Release Synch Status bit (w1c)*/ +#define KBD_STAT_KDIE (0x1 << 8) /* Key Depress Interrupt Enable Status bit */ +#define KBD_STAT_KRIE (0x1 << 9) /* Key Release Interrupt Enable */ +#define KBD_STAT_KPPEN (0x1 << 10) /* Keypad Clock Enable */ + +#define KDDR 0x04 /* Keypad Data Direction Register */ +#define KPDR 0x06 /* Keypad Data Register */ + +#define MAX_MATRIX_KEY_ROWS 8 +#define MAX_MATRIX_KEY_COLS 8 +#define MATRIX_ROW_SHIFT 3 + +#define MAX_MATRIX_KEY_NUM (MAX_MATRIX_KEY_ROWS * MAX_MATRIX_KEY_COLS) + +struct imx_keypad { + + struct clk *clk; + struct input_dev *input_dev; + void __iomem *mmio_base; + + int irq; + struct timer_list check_matrix_timer; + + /* + * The matrix is stable only if no changes are detected after + * IMX_KEYPAD_SCANS_FOR_STABILITY scans + */ +#define IMX_KEYPAD_SCANS_FOR_STABILITY 3 + int stable_count; + + bool enabled; + + /* Masks for enabled rows/cols */ + unsigned short rows_en_mask; + unsigned short cols_en_mask; + + unsigned short keycodes[MAX_MATRIX_KEY_NUM]; + + /* + * Matrix states: + * -stable: achieved after a complete debounce process. + * -unstable: used in the debouncing process. + */ + unsigned short matrix_stable_state[MAX_MATRIX_KEY_COLS]; + unsigned short matrix_unstable_state[MAX_MATRIX_KEY_COLS]; +}; + +/* Scan the matrix and return the new state in *matrix_volatile_state. */ +static void imx_keypad_scan_matrix(struct imx_keypad *keypad, + unsigned short *matrix_volatile_state) +{ + int col; + unsigned short reg_val; + + for (col = 0; col < MAX_MATRIX_KEY_COLS; col++) { + if ((keypad->cols_en_mask & (1 << col)) == 0) + continue; + /* + * Discharge keypad capacitance: + * 2. write 1s on column data. + * 3. configure columns as totem-pole to discharge capacitance. + * 4. configure columns as open-drain. + */ + reg_val = readw(keypad->mmio_base + KPDR); + reg_val |= 0xff00; + writew(reg_val, keypad->mmio_base + KPDR); + + reg_val = readw(keypad->mmio_base + KPCR); + reg_val &= ~((keypad->cols_en_mask & 0xff) << 8); + writew(reg_val, keypad->mmio_base + KPCR); + + udelay(2); + + reg_val = readw(keypad->mmio_base + KPCR); + reg_val |= (keypad->cols_en_mask & 0xff) << 8; + writew(reg_val, keypad->mmio_base + KPCR); + + /* + * 5. Write a single column to 0, others to 1. + * 6. Sample row inputs and save data. + * 7. Repeat steps 2 - 6 for remaining columns. + */ + reg_val = readw(keypad->mmio_base + KPDR); + reg_val &= ~(1 << (8 + col)); + writew(reg_val, keypad->mmio_base + KPDR); + + /* + * Delay added to avoid propagating the 0 from column to row + * when scanning. + */ + udelay(5); + + /* + * 1s in matrix_volatile_state[col] means key pressures + * throw data from non enabled rows. + */ + reg_val = readw(keypad->mmio_base + KPDR); + matrix_volatile_state[col] = (~reg_val) & keypad->rows_en_mask; + } + + /* + * Return in standby mode: + * 9. write 0s to columns + */ + reg_val = readw(keypad->mmio_base + KPDR); + reg_val &= 0x00ff; + writew(reg_val, keypad->mmio_base + KPDR); +} + +/* + * Compare the new matrix state (volatile) with the stable one stored in + * keypad->matrix_stable_state and fire events if changes are detected. + */ +static void imx_keypad_fire_events(struct imx_keypad *keypad, + unsigned short *matrix_volatile_state) +{ + struct input_dev *input_dev = keypad->input_dev; + int row, col; + + for (col = 0; col < MAX_MATRIX_KEY_COLS; col++) { + unsigned short bits_changed; + int code; + + if ((keypad->cols_en_mask & (1 << col)) == 0) + continue; /* Column is not enabled */ + + bits_changed = keypad->matrix_stable_state[col] ^ + matrix_volatile_state[col]; + + if (bits_changed == 0) + continue; /* Column does not contain changes */ + + for (row = 0; row < MAX_MATRIX_KEY_ROWS; row++) { + if ((keypad->rows_en_mask & (1 << row)) == 0) + continue; /* Row is not enabled */ + if ((bits_changed & (1 << row)) == 0) + continue; /* Row does not contain changes */ + + code = MATRIX_SCAN_CODE(row, col, MATRIX_ROW_SHIFT); + input_event(input_dev, EV_MSC, MSC_SCAN, code); + input_report_key(input_dev, keypad->keycodes[code], + matrix_volatile_state[col] & (1 << row)); + dev_dbg(&input_dev->dev, "Event code: %d, val: %d", + keypad->keycodes[code], + matrix_volatile_state[col] & (1 << row)); + } + } + input_sync(input_dev); +} + +/* + * imx_keypad_check_for_events is the timer handler. + */ +static void imx_keypad_check_for_events(unsigned long data) +{ + struct imx_keypad *keypad = (struct imx_keypad *) data; + unsigned short matrix_volatile_state[MAX_MATRIX_KEY_COLS]; + unsigned short reg_val; + bool state_changed, is_zero_matrix; + int i; + + memset(matrix_volatile_state, 0, sizeof(matrix_volatile_state)); + + imx_keypad_scan_matrix(keypad, matrix_volatile_state); + + state_changed = false; + for (i = 0; i < MAX_MATRIX_KEY_COLS; i++) { + if ((keypad->cols_en_mask & (1 << i)) == 0) + continue; + + if (keypad->matrix_unstable_state[i] ^ matrix_volatile_state[i]) { + state_changed = true; + break; + } + } + + /* + * If the matrix state is changed from the previous scan + * (Re)Begin the debouncing process, saving the new state in + * keypad->matrix_unstable_state. + * else + * Increase the count of number of scans with a stable state. + */ + if (state_changed) { + memcpy(keypad->matrix_unstable_state, matrix_volatile_state, + sizeof(matrix_volatile_state)); + keypad->stable_count = 0; + } else + keypad->stable_count++; + + /* + * If the matrix is not as stable as we want reschedule scan + * in the near future. + */ + if (keypad->stable_count < IMX_KEYPAD_SCANS_FOR_STABILITY) { + mod_timer(&keypad->check_matrix_timer, + jiffies + msecs_to_jiffies(10)); + return; + } + + /* + * If the matrix state is stable, fire the events and save the new + * stable state. Note, if the matrix is kept stable for longer + * (keypad->stable_count > IMX_KEYPAD_SCANS_FOR_STABILITY) all + * events have already been generated. + */ + if (keypad->stable_count == IMX_KEYPAD_SCANS_FOR_STABILITY) { + imx_keypad_fire_events(keypad, matrix_volatile_state); + + memcpy(keypad->matrix_stable_state, matrix_volatile_state, + sizeof(matrix_volatile_state)); + } + + is_zero_matrix = true; + for (i = 0; i < MAX_MATRIX_KEY_COLS; i++) { + if (matrix_volatile_state[i] != 0) { + is_zero_matrix = false; + break; + } + } + + + if (is_zero_matrix) { + /* + * All keys have been released. Enable only the KDI + * interrupt for future key presses (clear the KDI + * status bit and its sync chain before that). + */ + reg_val = readw(keypad->mmio_base + KPSR); + reg_val |= KBD_STAT_KPKD | KBD_STAT_KDSC; + writew(reg_val, keypad->mmio_base + KPSR); + + reg_val = readw(keypad->mmio_base + KPSR); + reg_val |= KBD_STAT_KDIE; + reg_val &= ~KBD_STAT_KRIE; + writew(reg_val, keypad->mmio_base + KPSR); + } else { + /* + * Some keys are still pressed. Schedule a rescan in + * attempt to detect multiple key presses and enable + * the KRI interrupt to react quickly to key release + * event. + */ + mod_timer(&keypad->check_matrix_timer, + jiffies + msecs_to_jiffies(60)); + + reg_val = readw(keypad->mmio_base + KPSR); + reg_val |= KBD_STAT_KPKR | KBD_STAT_KRSS; + writew(reg_val, keypad->mmio_base + KPSR); + + reg_val = readw(keypad->mmio_base + KPSR); + reg_val |= KBD_STAT_KRIE; + reg_val &= ~KBD_STAT_KDIE; + writew(reg_val, keypad->mmio_base + KPSR); + } +} + +static irqreturn_t imx_keypad_irq_handler(int irq, void *dev_id) +{ + struct imx_keypad *keypad = dev_id; + unsigned short reg_val; + + reg_val = readw(keypad->mmio_base + KPSR); + + /* Disable both interrupt types */ + reg_val &= ~(KBD_STAT_KRIE | KBD_STAT_KDIE); + /* Clear interrupts status bits */ + reg_val |= KBD_STAT_KPKR | KBD_STAT_KPKD; + writew(reg_val, keypad->mmio_base + KPSR); + + if (keypad->enabled) { + /* The matrix is supposed to be changed */ + keypad->stable_count = 0; + + /* Schedule the scanning procedure near in the future */ + mod_timer(&keypad->check_matrix_timer, + jiffies + msecs_to_jiffies(2)); + } + + return IRQ_HANDLED; +} + +static void imx_keypad_config(struct imx_keypad *keypad) +{ + unsigned short reg_val; + + /* + * Include enabled rows in interrupt generation (KPCR[7:0]) + * Configure keypad columns as open-drain (KPCR[15:8]) + */ + reg_val = readw(keypad->mmio_base + KPCR); + reg_val |= keypad->rows_en_mask & 0xff; /* rows */ + reg_val |= (keypad->cols_en_mask & 0xff) << 8; /* cols */ + writew(reg_val, keypad->mmio_base + KPCR); + + /* Write 0's to KPDR[15:8] (Colums) */ + reg_val = readw(keypad->mmio_base + KPDR); + reg_val &= 0x00ff; + writew(reg_val, keypad->mmio_base + KPDR); + + /* Configure columns as output, rows as input (KDDR[15:0]) */ + writew(0xff00, keypad->mmio_base + KDDR); + + /* + * Clear Key Depress and Key Release status bit. + * Clear both synchronizer chain. + */ + reg_val = readw(keypad->mmio_base + KPSR); + reg_val |= KBD_STAT_KPKR | KBD_STAT_KPKD | + KBD_STAT_KDSC | KBD_STAT_KRSS; + writew(reg_val, keypad->mmio_base + KPSR); + + /* Enable KDI and disable KRI (avoid false release events). */ + reg_val |= KBD_STAT_KDIE; + reg_val &= ~KBD_STAT_KRIE; + writew(reg_val, keypad->mmio_base + KPSR); +} + +static void imx_keypad_inhibit(struct imx_keypad *keypad) +{ + unsigned short reg_val; + + /* Inhibit KDI and KRI interrupts. */ + reg_val = readw(keypad->mmio_base + KPSR); + reg_val &= ~(KBD_STAT_KRIE | KBD_STAT_KDIE); + writew(reg_val, keypad->mmio_base + KPSR); + + /* Colums as open drain and disable all rows */ + writew(0xff00, keypad->mmio_base + KPCR); +} + +static void imx_keypad_close(struct input_dev *dev) +{ + struct imx_keypad *keypad = input_get_drvdata(dev); + + dev_dbg(&dev->dev, ">%s\n", __func__); + + /* Mark keypad as being inactive */ + keypad->enabled = false; + synchronize_irq(keypad->irq); + del_timer_sync(&keypad->check_matrix_timer); + + imx_keypad_inhibit(keypad); + + /* Disable clock unit */ + clk_disable(keypad->clk); +} + +static int imx_keypad_open(struct input_dev *dev) +{ + struct imx_keypad *keypad = input_get_drvdata(dev); + + dev_dbg(&dev->dev, ">%s\n", __func__); + + /* We became active from now */ + keypad->enabled = true; + + /* Enable the kpp clock */ + clk_enable(keypad->clk); + imx_keypad_config(keypad); + + /* Sanity control, not all the rows must be actived now. */ + if ((readw(keypad->mmio_base + KPDR) & keypad->rows_en_mask) == 0) { + dev_err(&dev->dev, + "too many keys pressed, control pins initialisation\n"); + goto open_err; + } + + return 0; + +open_err: + imx_keypad_close(dev); + return -EIO; +} + +static int __devinit imx_keypad_probe(struct platform_device *pdev) +{ + const struct matrix_keymap_data *keymap_data = pdev->dev.platform_data; + struct imx_keypad *keypad; + struct input_dev *input_dev; + struct resource *res; + int irq, error, i; + + if (keymap_data == NULL) { + dev_err(&pdev->dev, "no keymap defined\n"); + return -EINVAL; + } + + irq = platform_get_irq(pdev, 0); + if (irq < 0) { + dev_err(&pdev->dev, "no irq defined in platform data\n"); + return -EINVAL; + } + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (res == NULL) { + dev_err(&pdev->dev, "no I/O memory defined in platform data\n"); + return -EINVAL; + } + + res = request_mem_region(res->start, resource_size(res), pdev->name); + if (res == NULL) { + dev_err(&pdev->dev, "failed to request I/O memory\n"); + return -EBUSY; + } + + input_dev = input_allocate_device(); + if (!input_dev) { + dev_err(&pdev->dev, "failed to allocate the input device\n"); + error = -ENOMEM; + goto failed_rel_mem; + } + + keypad = kzalloc(sizeof(struct imx_keypad), GFP_KERNEL); + if (!keypad) { + dev_err(&pdev->dev, "not enough memory for driver data\n"); + error = -ENOMEM; + goto failed_free_input; + } + + keypad->input_dev = input_dev; + keypad->irq = irq; + keypad->stable_count = 0; + + setup_timer(&keypad->check_matrix_timer, + imx_keypad_check_for_events, (unsigned long) keypad); + + keypad->mmio_base = ioremap(res->start, resource_size(res)); + if (keypad->mmio_base == NULL) { + dev_err(&pdev->dev, "failed to remap I/O memory\n"); + error = -ENOMEM; + goto failed_free_priv; + } + + keypad->clk = clk_get(&pdev->dev, "kpp"); + if (IS_ERR(keypad->clk)) { + dev_err(&pdev->dev, "failed to get keypad clock\n"); + error = PTR_ERR(keypad->clk); + goto failed_unmap; + } + + /* Search for rows and cols enabled */ + for (i = 0; i < keymap_data->keymap_size; i++) { + keypad->rows_en_mask |= 1 << KEY_ROW(keymap_data->keymap[i]); + keypad->cols_en_mask |= 1 << KEY_COL(keymap_data->keymap[i]); + } + + if (keypad->rows_en_mask > ((1 << MAX_MATRIX_KEY_ROWS) - 1) || + keypad->cols_en_mask > ((1 << MAX_MATRIX_KEY_COLS) - 1)) { + dev_err(&pdev->dev, + "invalid key data (too many rows or colums)\n"); + error = -EINVAL; + goto failed_clock_put; + } + dev_dbg(&pdev->dev, "enabled rows mask: %x\n", keypad->rows_en_mask); + dev_dbg(&pdev->dev, "enabled cols mask: %x\n", keypad->cols_en_mask); + + /* Init the Input device */ + input_dev->name = pdev->name; + input_dev->id.bustype = BUS_HOST; + input_dev->dev.parent = &pdev->dev; + input_dev->open = imx_keypad_open; + input_dev->close = imx_keypad_close; + input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP); + input_dev->keycode = keypad->keycodes; + input_dev->keycodesize = sizeof(keypad->keycodes[0]); + input_dev->keycodemax = ARRAY_SIZE(keypad->keycodes); + + matrix_keypad_build_keymap(keymap_data, MATRIX_ROW_SHIFT, + keypad->keycodes, input_dev->keybit); + + input_set_capability(input_dev, EV_MSC, MSC_SCAN); + input_set_drvdata(input_dev, keypad); + + /* Ensure that the keypad will stay dormant until opened */ + imx_keypad_inhibit(keypad); + + error = request_irq(irq, imx_keypad_irq_handler, IRQF_DISABLED, + pdev->name, keypad); + if (error) { + dev_err(&pdev->dev, "failed to request IRQ\n"); + goto failed_clock_put; + } + + /* Register the input device */ + error = input_register_device(input_dev); + if (error) { + dev_err(&pdev->dev, "failed to register input device\n"); + goto failed_free_irq; + } + + platform_set_drvdata(pdev, keypad); + device_init_wakeup(&pdev->dev, 1); + + return 0; + +failed_free_irq: + free_irq(irq, pdev); +failed_clock_put: + clk_put(keypad->clk); +failed_unmap: + iounmap(keypad->mmio_base); +failed_free_priv: + kfree(keypad); +failed_free_input: + input_free_device(input_dev); +failed_rel_mem: + release_mem_region(res->start, resource_size(res)); + return error; +} + +static int __devexit imx_keypad_remove(struct platform_device *pdev) +{ + struct imx_keypad *keypad = platform_get_drvdata(pdev); + struct resource *res; + + dev_dbg(&pdev->dev, ">%s\n", __func__); + + platform_set_drvdata(pdev, NULL); + + input_unregister_device(keypad->input_dev); + + free_irq(keypad->irq, keypad); + clk_put(keypad->clk); + + iounmap(keypad->mmio_base); + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + release_mem_region(res->start, resource_size(res)); + + kfree(keypad); + + return 0; +} + +static struct platform_driver imx_keypad_driver = { + .driver = { + .name = "imx-keypad", + .owner = THIS_MODULE, + }, + .probe = imx_keypad_probe, + .remove = __devexit_p(imx_keypad_remove), +}; + +static int __init imx_keypad_init(void) +{ + return platform_driver_register(&imx_keypad_driver); +} + +static void __exit imx_keypad_exit(void) +{ + platform_driver_unregister(&imx_keypad_driver); +} + +module_init(imx_keypad_init); +module_exit(imx_keypad_exit); + +MODULE_AUTHOR("Alberto Panizzo "); +MODULE_DESCRIPTION("IMX Keypad Port Driver"); +MODULE_LICENSE("GPL v2"); +MODULE_ALIAS("platform:imx-keypad"); -- cgit v1.2.3 From fea4d14b69567e134e1838155a5dc857ebca70cb Mon Sep 17 00:00:00 2001 From: Ondrej Zary Date: Wed, 3 Feb 2010 23:46:48 -0800 Subject: Input: usbtouchscreen - convert from usb_device to usb_interface Convert usbtouchscreen from storing usb_device to usb_interface. This is needed for multi-interface touchscreen devices such as iNexio. Signed-off-by: Ondrej Zary Signed-off-by: Andrew Morton Signed-off-by: Dmitry Torokhov --- drivers/input/touchscreen/usbtouchscreen.c | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) (limited to 'drivers/input') diff --git a/drivers/input/touchscreen/usbtouchscreen.c b/drivers/input/touchscreen/usbtouchscreen.c index b1b99e931f80..69be77118884 100644 --- a/drivers/input/touchscreen/usbtouchscreen.c +++ b/drivers/input/touchscreen/usbtouchscreen.c @@ -104,7 +104,7 @@ struct usbtouch_usb { unsigned char *buffer; int buf_len; struct urb *irq; - struct usb_device *udev; + struct usb_interface *interface; struct input_dev *input; struct usbtouch_device_info *type; char name[128]; @@ -234,8 +234,9 @@ static const struct usb_device_id usbtouch_devices[] = { static int e2i_init(struct usbtouch_usb *usbtouch) { int ret; + struct usb_device *udev = interface_to_usbdev(usbtouch->interface); - ret = usb_control_msg(usbtouch->udev, usb_rcvctrlpipe(usbtouch->udev, 0), + ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), 0x01, 0x02, 0x0000, 0x0081, NULL, 0, USB_CTRL_SET_TIMEOUT); @@ -344,8 +345,9 @@ static int mtouch_read_data(struct usbtouch_usb *dev, unsigned char *pkt) static int mtouch_init(struct usbtouch_usb *usbtouch) { int ret, i; + struct usb_device *udev = interface_to_usbdev(usbtouch->interface); - ret = usb_control_msg(usbtouch->udev, usb_rcvctrlpipe(usbtouch->udev, 0), + ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), MTOUCHUSB_RESET, USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 1, 0, NULL, 0, USB_CTRL_SET_TIMEOUT); @@ -356,7 +358,7 @@ static int mtouch_init(struct usbtouch_usb *usbtouch) msleep(150); for (i = 0; i < 3; i++) { - ret = usb_control_msg(usbtouch->udev, usb_rcvctrlpipe(usbtouch->udev, 0), + ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), MTOUCHUSB_ASYNC_REPORT, USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 1, 1, NULL, 0, USB_CTRL_SET_TIMEOUT); @@ -489,7 +491,7 @@ static int gunze_read_data(struct usbtouch_usb *dev, unsigned char *pkt) static int dmc_tsc10_init(struct usbtouch_usb *usbtouch) { - struct usb_device *dev = usbtouch->udev; + struct usb_device *dev = interface_to_usbdev(usbtouch->interface); int ret = -ENOMEM; unsigned char *buf; @@ -1021,7 +1023,7 @@ static int usbtouch_open(struct input_dev *input) { struct usbtouch_usb *usbtouch = input_get_drvdata(input); - usbtouch->irq->dev = usbtouch->udev; + usbtouch->irq->dev = interface_to_usbdev(usbtouch->interface); if (!usbtouch->type->irq_always) { if (usb_submit_urb(usbtouch->irq, GFP_KERNEL)) @@ -1094,7 +1096,7 @@ static int usbtouch_probe(struct usb_interface *intf, goto out_free_buffers; } - usbtouch->udev = udev; + usbtouch->interface = intf; usbtouch->input = input_dev; if (udev->manufacturer) @@ -1133,12 +1135,12 @@ static int usbtouch_probe(struct usb_interface *intf, input_set_abs_params(input_dev, ABS_PRESSURE, type->min_press, type->max_press, 0, 0); - usb_fill_int_urb(usbtouch->irq, usbtouch->udev, - usb_rcvintpipe(usbtouch->udev, endpoint->bEndpointAddress), + usb_fill_int_urb(usbtouch->irq, udev, + usb_rcvintpipe(udev, endpoint->bEndpointAddress), usbtouch->data, type->rept_size, usbtouch_irq, usbtouch, endpoint->bInterval); - usbtouch->irq->dev = usbtouch->udev; + usbtouch->irq->dev = udev; usbtouch->irq->transfer_dma = usbtouch->data_dma; usbtouch->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; -- cgit v1.2.3 From f4a5e359c4bafc2269766ccd74256024160ed7ac Mon Sep 17 00:00:00 2001 From: Ondrej Zary Date: Wed, 3 Feb 2010 23:54:59 -0800 Subject: Input: usbtouchscreen - find input endpoint automatically Find input enpoint automatically instead of assuming that the first one is OK. This is needed for devices with multiple endpoints such as iNexio where the first endpoint might be output. Signed-off-by: Ondrej Zary Signed-off-by: Andrew Morton Signed-off-by: Dmitry Torokhov --- drivers/input/touchscreen/usbtouchscreen.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) (limited to 'drivers/input') diff --git a/drivers/input/touchscreen/usbtouchscreen.c b/drivers/input/touchscreen/usbtouchscreen.c index 69be77118884..a2a82351a42f 100644 --- a/drivers/input/touchscreen/usbtouchscreen.c +++ b/drivers/input/touchscreen/usbtouchscreen.c @@ -1050,13 +1050,23 @@ static void usbtouch_free_buffers(struct usb_device *udev, kfree(usbtouch->buffer); } +static struct usb_endpoint_descriptor * +usbtouch_get_input_endpoint(struct usb_host_interface *interface) +{ + int i; + + for (i = 0; i < interface->desc.bNumEndpoints; i++) + if (usb_endpoint_dir_in(&interface->endpoint[i].desc)) + return &interface->endpoint[i].desc; + + return NULL; +} static int usbtouch_probe(struct usb_interface *intf, const struct usb_device_id *id) { struct usbtouch_usb *usbtouch; struct input_dev *input_dev; - struct usb_host_interface *interface; struct usb_endpoint_descriptor *endpoint; struct usb_device *udev = interface_to_usbdev(intf); struct usbtouch_device_info *type; @@ -1066,8 +1076,9 @@ static int usbtouch_probe(struct usb_interface *intf, if (id->driver_info == DEVTYPE_IGNORE) return -ENODEV; - interface = intf->cur_altsetting; - endpoint = &interface->endpoint[0].desc; + endpoint = usbtouch_get_input_endpoint(intf->cur_altsetting); + if (!endpoint) + return -ENXIO; usbtouch = kzalloc(sizeof(struct usbtouch_usb), GFP_KERNEL); input_dev = input_allocate_device(); -- cgit v1.2.3 From 5197424cdcccd2b0b1922babb93969b2515c43ce Mon Sep 17 00:00:00 2001 From: Ondrej Zary Date: Thu, 4 Feb 2010 00:17:18 -0800 Subject: Input: usbtouchscreen - add NEXIO (or iNexio) support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add support for NEXIO (or iNexio) USB touchscreens to usbtouchscreen driver. Tested with NEX170MRT 17" LCD monitor with integrated touchscreen (with xserver-xorg-input-evtouch 0.8.8-1): T:  Bus=02 Lev=01 Prnt=01 Port=01 Cnt=01 Dev#= 54 Spd=12  MxCh= 0 D:  Ver= 1.10 Cls=02(comm.) Sub=00 Prot=00 MxPS= 8 #Cfgs=  1 P:  Vendor=1870 ProdID=0001 Rev= 1.00 S:  Manufacturer=iNexio S:  Product=iNexio USB C:* #Ifs= 2 Cfg#= 1 Atr=c0 MxPwr=500mA I:* If#= 0 Alt= 0 #EPs= 1 Cls=02(comm.) Sub=02 Prot=00 Driver=(none) E:  Ad=83(I) Atr=03(Int.) MxPS=   8 Ivl=255ms I:* If#= 1 Alt= 0 #EPs= 2 Cls=0a(data ) Sub=00 Prot=00 Driver=(none) E:  Ad=01(O) Atr=02(Bulk) MxPS=  64 Ivl=0ms E:  Ad=82(I) Atr=02(Bulk) MxPS=  64 Ivl=0ms No datasheet is available, this was written by capturing some data with SniffUSB in Windows: http://www.rainbow-software.org/linux_files/nexio/ Signed-off-by: Ondrej Zary Signed-off-by: Andrew Morton Signed-off-by: Dmitry Torokhov --- drivers/input/touchscreen/Kconfig | 5 + drivers/input/touchscreen/usbtouchscreen.c | 261 ++++++++++++++++++++++++++++- 2 files changed, 264 insertions(+), 2 deletions(-) (limited to 'drivers/input') diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig index dfafc76da4fb..a1e2d845f680 100644 --- a/drivers/input/touchscreen/Kconfig +++ b/drivers/input/touchscreen/Kconfig @@ -537,6 +537,11 @@ config TOUCHSCREEN_USB_ETT_TC5UH bool "ET&T TC5UH touchscreen controler support" if EMBEDDED depends on TOUCHSCREEN_USB_COMPOSITE +config TOUCHSCREEN_USB_NEXIO + default y + bool "NEXIO/iNexio device support" if EMBEDDED + depends on TOUCHSCREEN_USB_COMPOSITE + config TOUCHSCREEN_TOUCHIT213 tristate "Sahara TouchIT-213 touchscreen" select SERIO diff --git a/drivers/input/touchscreen/usbtouchscreen.c b/drivers/input/touchscreen/usbtouchscreen.c index a2a82351a42f..07656efee654 100644 --- a/drivers/input/touchscreen/usbtouchscreen.c +++ b/drivers/input/touchscreen/usbtouchscreen.c @@ -15,6 +15,7 @@ * - GoTop Super_Q2/GogoPen/PenPower tablets * - JASTEC USB touch controller/DigiTech DTR-02U * - Zytronic capacitive touchscreen + * - NEXIO/iNexio * * Copyright (C) 2004-2007 by Daniel Ritz * Copyright (C) by Todd E. Johnson (mtouchusb.c) @@ -95,6 +96,7 @@ struct usbtouch_device_info { int (*read_data) (struct usbtouch_usb *usbtouch, unsigned char *pkt); int (*init) (struct usbtouch_usb *usbtouch); + void (*exit) (struct usbtouch_usb *usbtouch); }; /* a usbtouch device */ @@ -109,6 +111,7 @@ struct usbtouch_usb { struct usbtouch_device_info *type; char name[128]; char phys[64]; + void *priv; int x, y; int touch, press; @@ -133,6 +136,7 @@ enum { DEVTYPE_E2I, DEVTYPE_ZYTRONIC, DEVTYPE_TC5UH, + DEVTYPE_NEXIO, }; #define USB_DEVICE_HID_CLASS(vend, prod) \ @@ -222,6 +226,14 @@ static const struct usb_device_id usbtouch_devices[] = { {USB_DEVICE(0x0664, 0x0309), .driver_info = DEVTYPE_TC5UH}, #endif +#ifdef CONFIG_TOUCHSCREEN_USB_NEXIO + /* data interface only */ + {USB_DEVICE_AND_INTERFACE_INFO(0x10f0, 0x2002, 0x0a, 0x00, 0x00), + .driver_info = DEVTYPE_NEXIO}, + {USB_DEVICE_AND_INTERFACE_INFO(0x1870, 0x0001, 0x0a, 0x00, 0x00), + .driver_info = DEVTYPE_NEXIO}, +#endif + {} }; @@ -691,6 +703,229 @@ static int zytronic_read_data(struct usbtouch_usb *dev, unsigned char *pkt) } #endif +/***************************************************************************** + * NEXIO Part + */ +#ifdef CONFIG_TOUCHSCREEN_USB_NEXIO + +#define NEXIO_TIMEOUT 5000 +#define NEXIO_BUFSIZE 1024 +#define NEXIO_THRESHOLD 50 + +struct nexio_priv { + struct urb *ack; + unsigned char *ack_buf; +}; + +struct nexio_touch_packet { + u8 flags; /* 0xe1 = touch, 0xe1 = release */ + __be16 data_len; /* total bytes of touch data */ + __be16 x_len; /* bytes for X axis */ + __be16 y_len; /* bytes for Y axis */ + u8 data[]; +} __attribute__ ((packed)); + +static unsigned char nexio_ack_pkt[2] = { 0xaa, 0x02 }; +static unsigned char nexio_init_pkt[4] = { 0x82, 0x04, 0x0a, 0x0f }; + +static void nexio_ack_complete(struct urb *urb) +{ +} + +static int nexio_init(struct usbtouch_usb *usbtouch) +{ + struct usb_device *dev = interface_to_usbdev(usbtouch->interface); + struct usb_host_interface *interface = usbtouch->interface->cur_altsetting; + struct nexio_priv *priv; + int ret = -ENOMEM; + int actual_len, i; + unsigned char *buf; + char *firmware_ver = NULL, *device_name = NULL; + int input_ep = 0, output_ep = 0; + + /* find first input and output endpoint */ + for (i = 0; i < interface->desc.bNumEndpoints; i++) { + if (!input_ep && + usb_endpoint_dir_in(&interface->endpoint[i].desc)) + input_ep = interface->endpoint[i].desc.bEndpointAddress; + if (!output_ep && + usb_endpoint_dir_out(&interface->endpoint[i].desc)) + output_ep = interface->endpoint[i].desc.bEndpointAddress; + } + if (!input_ep || !output_ep) + return -ENXIO; + + buf = kmalloc(NEXIO_BUFSIZE, GFP_KERNEL); + if (!buf) + goto out_buf; + + /* two empty reads */ + for (i = 0; i < 2; i++) { + ret = usb_bulk_msg(dev, usb_rcvbulkpipe(dev, input_ep), + buf, NEXIO_BUFSIZE, &actual_len, + NEXIO_TIMEOUT); + if (ret < 0) + goto out_buf; + } + + /* send init command */ + memcpy(buf, nexio_init_pkt, sizeof(nexio_init_pkt)); + ret = usb_bulk_msg(dev, usb_sndbulkpipe(dev, output_ep), + buf, sizeof(nexio_init_pkt), &actual_len, + NEXIO_TIMEOUT); + if (ret < 0) + goto out_buf; + + /* read replies */ + for (i = 0; i < 3; i++) { + memset(buf, 0, NEXIO_BUFSIZE); + ret = usb_bulk_msg(dev, usb_rcvbulkpipe(dev, input_ep), + buf, NEXIO_BUFSIZE, &actual_len, + NEXIO_TIMEOUT); + if (ret < 0 || actual_len < 1 || buf[1] != actual_len) + continue; + switch (buf[0]) { + case 0x83: /* firmware version */ + if (!firmware_ver) + firmware_ver = kstrdup(&buf[2], GFP_KERNEL); + break; + case 0x84: /* device name */ + if (!device_name) + device_name = kstrdup(&buf[2], GFP_KERNEL); + break; + } + } + + printk(KERN_INFO "Nexio device: %s, firmware version: %s\n", + device_name, firmware_ver); + + kfree(firmware_ver); + kfree(device_name); + + /* prepare ACK URB */ + ret = -ENOMEM; + + usbtouch->priv = kmalloc(sizeof(struct nexio_priv), GFP_KERNEL); + if (!usbtouch->priv) + goto out_buf; + + priv = usbtouch->priv; + + priv->ack_buf = kmalloc(sizeof(nexio_ack_pkt), GFP_KERNEL); + if (!priv->ack_buf) + goto err_priv; + + memcpy(priv->ack_buf, nexio_ack_pkt, sizeof(nexio_ack_pkt)); + + priv->ack = usb_alloc_urb(0, GFP_KERNEL); + if (!priv->ack) { + dbg("%s - usb_alloc_urb failed: usbtouch->ack", __func__); + goto err_ack_buf; + } + + usb_fill_bulk_urb(priv->ack, dev, usb_sndbulkpipe(dev, output_ep), + priv->ack_buf, sizeof(nexio_ack_pkt), + nexio_ack_complete, usbtouch); + ret = 0; + goto out_buf; + +err_ack_buf: + kfree(priv->ack_buf); +err_priv: + kfree(priv); +out_buf: + kfree(buf); + return ret; +} + +static void nexio_exit(struct usbtouch_usb *usbtouch) +{ + struct nexio_priv *priv = usbtouch->priv; + + usb_kill_urb(priv->ack); + usb_free_urb(priv->ack); + kfree(priv->ack_buf); + kfree(priv); +} + +static int nexio_read_data(struct usbtouch_usb *usbtouch, unsigned char *pkt) +{ + int x, y, begin_x, begin_y, end_x, end_y, w, h, ret; + struct nexio_touch_packet *packet = (void *) pkt; + struct nexio_priv *priv = usbtouch->priv; + + /* got touch data? */ + if ((pkt[0] & 0xe0) != 0xe0) + return 0; + + /* send ACK */ + ret = usb_submit_urb(priv->ack, GFP_ATOMIC); + + if (!usbtouch->type->max_xc) { + usbtouch->type->max_xc = 2 * be16_to_cpu(packet->x_len); + input_set_abs_params(usbtouch->input, ABS_X, 0, + 2 * be16_to_cpu(packet->x_len), 0, 0); + usbtouch->type->max_yc = 2 * be16_to_cpu(packet->y_len); + input_set_abs_params(usbtouch->input, ABS_Y, 0, + 2 * be16_to_cpu(packet->y_len), 0, 0); + } + /* + * The device reports state of IR sensors on X and Y axes. + * Each byte represents "darkness" percentage (0-100) of one element. + * 17" touchscreen reports only 64 x 52 bytes so the resolution is low. + * This also means that there's a limited multi-touch capability but + * it's disabled (and untested) here as there's no X driver for that. + */ + begin_x = end_x = begin_y = end_y = -1; + for (x = 0; x < be16_to_cpu(packet->x_len); x++) { + if (begin_x == -1 && packet->data[x] > NEXIO_THRESHOLD) { + begin_x = x; + continue; + } + if (end_x == -1 && begin_x != -1 && packet->data[x] < NEXIO_THRESHOLD) { + end_x = x - 1; + for (y = be16_to_cpu(packet->x_len); + y < be16_to_cpu(packet->data_len); y++) { + if (begin_y == -1 && packet->data[y] > NEXIO_THRESHOLD) { + begin_y = y - be16_to_cpu(packet->x_len); + continue; + } + if (end_y == -1 && + begin_y != -1 && packet->data[y] < NEXIO_THRESHOLD) { + end_y = y - 1 - be16_to_cpu(packet->x_len); + w = end_x - begin_x; + h = end_y - begin_y; +#if 0 + /* multi-touch */ + input_report_abs(usbtouch->input, + ABS_MT_TOUCH_MAJOR, max(w,h)); + input_report_abs(usbtouch->input, + ABS_MT_TOUCH_MINOR, min(x,h)); + input_report_abs(usbtouch->input, + ABS_MT_POSITION_X, 2*begin_x+w); + input_report_abs(usbtouch->input, + ABS_MT_POSITION_Y, 2*begin_y+h); + input_report_abs(usbtouch->input, + ABS_MT_ORIENTATION, w > h); + input_mt_sync(usbtouch->input); +#endif + /* single touch */ + usbtouch->x = 2 * begin_x + w; + usbtouch->y = 2 * begin_y + h; + usbtouch->touch = packet->flags & 0x01; + begin_y = end_y = -1; + return 1; + } + } + begin_x = end_x = -1; + } + + } + return 0; +} +#endif + + /***************************************************************************** * the different device descriptors */ @@ -875,6 +1110,16 @@ static struct usbtouch_device_info usbtouch_dev_info[] = { .read_data = tc5uh_read_data, }, #endif + +#ifdef CONFIG_TOUCHSCREEN_USB_NEXIO + [DEVTYPE_NEXIO] = { + .rept_size = 128, + .irq_always = true, + .read_data = nexio_read_data, + .init = nexio_init, + .exit = nexio_exit, + }, +#endif }; @@ -1000,6 +1245,7 @@ static void usbtouch_irq(struct urb *urb) case -ECONNRESET: case -ENOENT: case -ESHUTDOWN: + case -EPIPE: /* this urb is terminated, clean up */ dbg("%s - urb shutting down with status: %d", __func__, urb->status); @@ -1146,10 +1392,16 @@ static int usbtouch_probe(struct usb_interface *intf, input_set_abs_params(input_dev, ABS_PRESSURE, type->min_press, type->max_press, 0, 0); - usb_fill_int_urb(usbtouch->irq, udev, + if (usb_endpoint_type(endpoint) == USB_ENDPOINT_XFER_INT) + usb_fill_int_urb(usbtouch->irq, udev, usb_rcvintpipe(udev, endpoint->bEndpointAddress), usbtouch->data, type->rept_size, usbtouch_irq, usbtouch, endpoint->bInterval); + else + usb_fill_bulk_urb(usbtouch->irq, udev, + usb_rcvbulkpipe(udev, endpoint->bEndpointAddress), + usbtouch->data, type->rept_size, + usbtouch_irq, usbtouch); usbtouch->irq->dev = udev; usbtouch->irq->transfer_dma = usbtouch->data_dma; @@ -1167,7 +1419,7 @@ static int usbtouch_probe(struct usb_interface *intf, err = input_register_device(usbtouch->input); if (err) { dbg("%s - input_register_device failed, err: %d", __func__, err); - goto out_free_buffers; + goto out_do_exit; } usb_set_intfdata(intf, usbtouch); @@ -1177,6 +1429,9 @@ static int usbtouch_probe(struct usb_interface *intf, return 0; +out_do_exit: + if (type->exit) + type->exit(usbtouch); out_free_buffers: usbtouch_free_buffers(udev, usbtouch); out_free: @@ -1199,6 +1454,8 @@ static void usbtouch_disconnect(struct usb_interface *intf) /* this will stop IO via close */ input_unregister_device(usbtouch->input); usb_free_urb(usbtouch->irq); + if (usbtouch->type->exit) + usbtouch->type->exit(usbtouch); usbtouch_free_buffers(interface_to_usbdev(intf), usbtouch); kfree(usbtouch); } -- cgit v1.2.3 From 1e87a43080a259a0e9739377708ece163b08de8d Mon Sep 17 00:00:00 2001 From: Ondrej Zary Date: Thu, 4 Feb 2010 00:20:35 -0800 Subject: Input: usbtouchscreen - fix leaks and check return value of usb_submit_urb() Fix urb leak in error path of initialization and make sure we handle errors from initial usb_submit_urb(). Signed-off-by: Ondrej Zary Signed-off-by: Andrew Morton Signed-off-by: Dmitry Torokhov --- drivers/input/touchscreen/usbtouchscreen.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) (limited to 'drivers/input') diff --git a/drivers/input/touchscreen/usbtouchscreen.c b/drivers/input/touchscreen/usbtouchscreen.c index 07656efee654..7a2d39abc586 100644 --- a/drivers/input/touchscreen/usbtouchscreen.c +++ b/drivers/input/touchscreen/usbtouchscreen.c @@ -1412,7 +1412,7 @@ static int usbtouch_probe(struct usb_interface *intf, err = type->init(usbtouch); if (err) { dbg("%s - type->init() failed, err: %d", __func__, err); - goto out_free_buffers; + goto out_free_urb; } } @@ -1424,14 +1424,25 @@ static int usbtouch_probe(struct usb_interface *intf, usb_set_intfdata(intf, usbtouch); - if (usbtouch->type->irq_always) - usb_submit_urb(usbtouch->irq, GFP_KERNEL); + if (usbtouch->type->irq_always) { + err = usb_submit_urb(usbtouch->irq, GFP_KERNEL); + if (err) { + err("%s - usb_submit_urb failed with result: %d", + __func__, err); + goto out_unregister_input; + } + } return 0; +out_unregister_input: + input_unregister_device(input_dev); + input_dev = NULL; out_do_exit: if (type->exit) type->exit(usbtouch); +out_free_urb: + usb_free_urb(usbtouch->irq); out_free_buffers: usbtouch_free_buffers(udev, usbtouch); out_free: -- cgit v1.2.3 From 0b7024ac4df5821347141c18e680b7166bc1cb20 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Tue, 2 Feb 2010 21:08:26 -0800 Subject: Input: add match() method to input hanlders Get rid of blacklist in input handler structure and instead allow handlers to define their own match() method to perform fine-grained filtering of supported devices. Signed-off-by: Dmitry Torokhov --- drivers/char/keyboard.c | 24 ++++++++++++++++-------- drivers/input/input.c | 13 ++++++------- drivers/input/joydev.c | 32 +++++++++++++++----------------- include/linux/input.h | 6 +++--- 4 files changed, 40 insertions(+), 35 deletions(-) (limited to 'drivers/input') diff --git a/drivers/char/keyboard.c b/drivers/char/keyboard.c index cbf64b985ef4..ada25bb8941e 100644 --- a/drivers/char/keyboard.c +++ b/drivers/char/keyboard.c @@ -1323,6 +1323,21 @@ static void kbd_event(struct input_handle *handle, unsigned int event_type, schedule_console_callback(); } +static bool kbd_match(struct input_handler *handler, struct input_dev *dev) +{ + int i; + + if (test_bit(EV_SND, dev->evbit)) + return true; + + if (test_bit(EV_KEY, dev->evbit)) + for (i = KEY_RESERVED; i < BTN_MISC; i++) + if (test_bit(i, dev->keybit)) + return true; + + return false; +} + /* * When a keyboard (or other input device) is found, the kbd_connect * function is called. The function then looks at the device, and if it @@ -1334,14 +1349,6 @@ static int kbd_connect(struct input_handler *handler, struct input_dev *dev, { struct input_handle *handle; int error; - int i; - - for (i = KEY_RESERVED; i < BTN_MISC; i++) - if (test_bit(i, dev->keybit)) - break; - - if (i == BTN_MISC && !test_bit(EV_SND, dev->evbit)) - return -ENODEV; handle = kzalloc(sizeof(struct input_handle), GFP_KERNEL); if (!handle) @@ -1407,6 +1414,7 @@ MODULE_DEVICE_TABLE(input, kbd_ids); static struct input_handler kbd_handler = { .event = kbd_event, + .match = kbd_match, .connect = kbd_connect, .disconnect = kbd_disconnect, .start = kbd_start, diff --git a/drivers/input/input.c b/drivers/input/input.c index 7080a9d4b840..dae49eba6ccd 100644 --- a/drivers/input/input.c +++ b/drivers/input/input.c @@ -723,12 +723,13 @@ EXPORT_SYMBOL(input_set_keycode); if (i != BITS_TO_LONGS(max)) \ continue; -static const struct input_device_id *input_match_device(const struct input_device_id *id, +static const struct input_device_id *input_match_device(struct input_handler *handler, struct input_dev *dev) { + const struct input_device_id *id; int i; - for (; id->flags || id->driver_info; id++) { + for (id = handler->id_table; id->flags || id->driver_info; id++) { if (id->flags & INPUT_DEVICE_ID_MATCH_BUS) if (id->bustype != dev->id.bustype) @@ -756,7 +757,8 @@ static const struct input_device_id *input_match_device(const struct input_devic MATCH_BIT(ffbit, FF_MAX); MATCH_BIT(swbit, SW_MAX); - return id; + if (!handler->match || handler->match(handler, dev)) + return id; } return NULL; @@ -767,10 +769,7 @@ static int input_attach_handler(struct input_dev *dev, struct input_handler *han const struct input_device_id *id; int error; - if (handler->blacklist && input_match_device(handler->blacklist, dev)) - return -ENODEV; - - id = input_match_device(handler->id_table, dev); + id = input_match_device(handler, dev); if (!id) return -ENODEV; diff --git a/drivers/input/joydev.c b/drivers/input/joydev.c index b1bd6dd32286..63e71f2a7acc 100644 --- a/drivers/input/joydev.c +++ b/drivers/input/joydev.c @@ -775,6 +775,20 @@ static void joydev_cleanup(struct joydev *joydev) input_close_device(handle); } + +static bool joydev_match(struct input_handler *handler, struct input_dev *dev) +{ + /* Avoid touchpads and touchscreens */ + if (test_bit(EV_KEY, dev->evbit) && test_bit(BTN_TOUCH, dev->keybit)) + return false; + + /* Avoid tablets, digitisers and similar devices */ + if (test_bit(EV_KEY, dev->evbit) && test_bit(BTN_DIGI, dev->keybit)) + return false; + + return true; +} + static int joydev_connect(struct input_handler *handler, struct input_dev *dev, const struct input_device_id *id) { @@ -894,22 +908,6 @@ static void joydev_disconnect(struct input_handle *handle) put_device(&joydev->dev); } -static const struct input_device_id joydev_blacklist[] = { - { - .flags = INPUT_DEVICE_ID_MATCH_EVBIT | - INPUT_DEVICE_ID_MATCH_KEYBIT, - .evbit = { BIT_MASK(EV_KEY) }, - .keybit = { [BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH) }, - }, /* Avoid itouchpads and touchscreens */ - { - .flags = INPUT_DEVICE_ID_MATCH_EVBIT | - INPUT_DEVICE_ID_MATCH_KEYBIT, - .evbit = { BIT_MASK(EV_KEY) }, - .keybit = { [BIT_WORD(BTN_DIGI)] = BIT_MASK(BTN_DIGI) }, - }, /* Avoid tablets, digitisers and similar devices */ - { } /* Terminating entry */ -}; - static const struct input_device_id joydev_ids[] = { { .flags = INPUT_DEVICE_ID_MATCH_EVBIT | @@ -936,13 +934,13 @@ MODULE_DEVICE_TABLE(input, joydev_ids); static struct input_handler joydev_handler = { .event = joydev_event, + .match = joydev_match, .connect = joydev_connect, .disconnect = joydev_disconnect, .fops = &joydev_fops, .minor = JOYDEV_MINOR_BASE, .name = "joydev", .id_table = joydev_ids, - .blacklist = joydev_blacklist, }; static int __init joydev_init(void) diff --git a/include/linux/input.h b/include/linux/input.h index 6c9d3d49fa91..8dc5d724c703 100644 --- a/include/linux/input.h +++ b/include/linux/input.h @@ -1200,6 +1200,8 @@ struct input_handle; * it may not sleep * @filter: similar to @event; separates normal event handlers from * "filters". + * @match: called after comparing device's id with handler's id_table + * to perform fine-grained matching between device and handler * @connect: called when attaching a handler to an input device * @disconnect: disconnects a handler from input device * @start: starts handler for given handle. This function is called by @@ -1211,8 +1213,6 @@ struct input_handle; * @name: name of the handler, to be shown in /proc/bus/input/handlers * @id_table: pointer to a table of input_device_ids this driver can * handle - * @blacklist: pointer to a table of input_device_ids this driver should - * ignore even if they match @id_table * @h_list: list of input handles associated with the handler * @node: for placing the driver onto input_handler_list * @@ -1235,6 +1235,7 @@ struct input_handler { void (*event)(struct input_handle *handle, unsigned int type, unsigned int code, int value); bool (*filter)(struct input_handle *handle, unsigned int type, unsigned int code, int value); + bool (*match)(struct input_handler *handler, struct input_dev *dev); int (*connect)(struct input_handler *handler, struct input_dev *dev, const struct input_device_id *id); void (*disconnect)(struct input_handle *handle); void (*start)(struct input_handle *handle); @@ -1244,7 +1245,6 @@ struct input_handler { const char *name; const struct input_device_id *id_table; - const struct input_device_id *blacklist; struct list_head h_list; struct list_head node; -- cgit v1.2.3 From daf8a96b2d4a5d4d1d288831be43457c84c55a2f Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Thu, 4 Feb 2010 00:30:39 -0800 Subject: Input: uinput - mark as non-seekable Seeking does not make sense for uinput so let's use nonseekable_open to mark the device non-seekable. Signed-off-by: Dmitry Torokhov --- drivers/input/misc/uinput.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/input') diff --git a/drivers/input/misc/uinput.c b/drivers/input/misc/uinput.c index 18206e18d1b1..1477466076ad 100644 --- a/drivers/input/misc/uinput.c +++ b/drivers/input/misc/uinput.c @@ -290,6 +290,7 @@ static int uinput_open(struct inode *inode, struct file *file) newdev->state = UIST_NEW_DEVICE; file->private_data = newdev; + nonseekable_open(inode, file); return 0; } -- cgit v1.2.3 From 3d7bbd4575cfb23e6ef7368fff1f7d7e198b7930 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Thu, 4 Feb 2010 00:30:42 -0800 Subject: Input: mark input interfaces as non-seekable Seeking does not make sense for input interfaces such as evdev and joydev so let's use nonseekable_open to mark them non-seekable. Signed-off-by: Dmitry Torokhov --- drivers/input/evdev.c | 2 ++ drivers/input/joydev.c | 2 ++ 2 files changed, 4 insertions(+) (limited to 'drivers/input') diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c index 258c639571b5..9f9816baeb97 100644 --- a/drivers/input/evdev.c +++ b/drivers/input/evdev.c @@ -278,6 +278,8 @@ static int evdev_open(struct inode *inode, struct file *file) goto err_free_client; file->private_data = client; + nonseekable_open(inode, file); + return 0; err_free_client: diff --git a/drivers/input/joydev.c b/drivers/input/joydev.c index 63e71f2a7acc..c52bec4d0530 100644 --- a/drivers/input/joydev.c +++ b/drivers/input/joydev.c @@ -286,6 +286,8 @@ static int joydev_open(struct inode *inode, struct file *file) goto err_free_client; file->private_data = client; + nonseekable_open(inode, file); + return 0; err_free_client: -- cgit v1.2.3 From 9e3af04f8787315f63f55b191bb9a06741dbf183 Mon Sep 17 00:00:00 2001 From: Mika Westerberg Date: Thu, 4 Feb 2010 00:48:00 -0800 Subject: Input: gpio-keys - add support for disabling gpios through sysfs Now gpio-keys input driver exports 4 new attributes to userland through sysfs: /sys/devices/platform/gpio-keys/keys [ro] /sys/devices/platform/gpio-keys/switches [ro] /sys/devices/platform/gpio-keys/disabled_keys [rw] /sys/devices/platform/gpio-keys/disables_switches [rw] With these attributes, userland program can read which keys and switches can be disabled and then disable/enable them as needed. Keys and switches are exported as stringified bitmap of codes (keycodes or switch codes). For example keys 15, 89, 100, 101, 102 are exported as: '15,89,100-102'. Description of the attributes: keys - bitmap of keys which can be disabled switches - bitmap of switches which can be disabled disabled_keys - bitmap of currently disabled keys (bit 1 means disabled, 0 enabled) disabled_switches - bitmap of currently disabled switches (bit 1 means disabled, 0 enabled) Signed-off-by: Mika Westerberg Signed-off-by: Dmitry Torokhov --- drivers/input/keyboard/gpio_keys.c | 318 +++++++++++++++++++++++++++++++++++-- include/linux/gpio_keys.h | 1 + 2 files changed, 308 insertions(+), 11 deletions(-) (limited to 'drivers/input') diff --git a/drivers/input/keyboard/gpio_keys.c b/drivers/input/keyboard/gpio_keys.c index 1aff3b76effd..2b708aa85553 100644 --- a/drivers/input/keyboard/gpio_keys.c +++ b/drivers/input/keyboard/gpio_keys.c @@ -30,13 +30,289 @@ struct gpio_button_data { struct input_dev *input; struct timer_list timer; struct work_struct work; + bool disabled; }; struct gpio_keys_drvdata { struct input_dev *input; + struct mutex disable_lock; + unsigned int n_buttons; struct gpio_button_data data[0]; }; +/* + * SYSFS interface for enabling/disabling keys and switches: + * + * There are 4 attributes under /sys/devices/platform/gpio-keys/ + * keys [ro] - bitmap of keys (EV_KEY) which can be + * disabled + * switches [ro] - bitmap of switches (EV_SW) which can be + * disabled + * disabled_keys [rw] - bitmap of keys currently disabled + * disabled_switches [rw] - bitmap of switches currently disabled + * + * Userland can change these values and hence disable event generation + * for each key (or switch). Disabling a key means its interrupt line + * is disabled. + * + * For example, if we have following switches set up as gpio-keys: + * SW_DOCK = 5 + * SW_CAMERA_LENS_COVER = 9 + * SW_KEYPAD_SLIDE = 10 + * SW_FRONT_PROXIMITY = 11 + * This is read from switches: + * 11-9,5 + * Next we want to disable proximity (11) and dock (5), we write: + * 11,5 + * to file disabled_switches. Now proximity and dock IRQs are disabled. + * This can be verified by reading the file disabled_switches: + * 11,5 + * If we now want to enable proximity (11) switch we write: + * 5 + * to disabled_switches. + * + * We can disable only those keys which don't allow sharing the irq. + */ + +/** + * get_n_events_by_type() - returns maximum number of events per @type + * @type: type of button (%EV_KEY, %EV_SW) + * + * Return value of this function can be used to allocate bitmap + * large enough to hold all bits for given type. + */ +static inline int get_n_events_by_type(int type) +{ + BUG_ON(type != EV_SW && type != EV_KEY); + + return (type == EV_KEY) ? KEY_CNT : SW_CNT; +} + +/** + * gpio_keys_disable_button() - disables given GPIO button + * @bdata: button data for button to be disabled + * + * Disables button pointed by @bdata. This is done by masking + * IRQ line. After this function is called, button won't generate + * input events anymore. Note that one can only disable buttons + * that don't share IRQs. + * + * Make sure that @bdata->disable_lock is locked when entering + * this function to avoid races when concurrent threads are + * disabling buttons at the same time. + */ +static void gpio_keys_disable_button(struct gpio_button_data *bdata) +{ + if (!bdata->disabled) { + /* + * Disable IRQ and possible debouncing timer. + */ + disable_irq(gpio_to_irq(bdata->button->gpio)); + if (bdata->button->debounce_interval) + del_timer_sync(&bdata->timer); + + bdata->disabled = true; + } +} + +/** + * gpio_keys_enable_button() - enables given GPIO button + * @bdata: button data for button to be disabled + * + * Enables given button pointed by @bdata. + * + * Make sure that @bdata->disable_lock is locked when entering + * this function to avoid races with concurrent threads trying + * to enable the same button at the same time. + */ +static void gpio_keys_enable_button(struct gpio_button_data *bdata) +{ + if (bdata->disabled) { + enable_irq(gpio_to_irq(bdata->button->gpio)); + bdata->disabled = false; + } +} + +/** + * gpio_keys_attr_show_helper() - fill in stringified bitmap of buttons + * @ddata: pointer to drvdata + * @buf: buffer where stringified bitmap is written + * @type: button type (%EV_KEY, %EV_SW) + * @only_disabled: does caller want only those buttons that are + * currently disabled or all buttons that can be + * disabled + * + * This function writes buttons that can be disabled to @buf. If + * @only_disabled is true, then @buf contains only those buttons + * that are currently disabled. Returns 0 on success or negative + * errno on failure. + */ +static ssize_t gpio_keys_attr_show_helper(struct gpio_keys_drvdata *ddata, + char *buf, unsigned int type, + bool only_disabled) +{ + int n_events = get_n_events_by_type(type); + unsigned long *bits; + ssize_t ret; + int i; + + bits = kcalloc(BITS_TO_LONGS(n_events), sizeof(*bits), GFP_KERNEL); + if (!bits) + return -ENOMEM; + + for (i = 0; i < ddata->n_buttons; i++) { + struct gpio_button_data *bdata = &ddata->data[i]; + + if (bdata->button->type != type) + continue; + + if (only_disabled && !bdata->disabled) + continue; + + __set_bit(bdata->button->code, bits); + } + + ret = bitmap_scnlistprintf(buf, PAGE_SIZE - 2, bits, n_events); + buf[ret++] = '\n'; + buf[ret] = '\0'; + + kfree(bits); + + return ret; +} + +/** + * gpio_keys_attr_store_helper() - enable/disable buttons based on given bitmap + * @ddata: pointer to drvdata + * @buf: buffer from userspace that contains stringified bitmap + * @type: button type (%EV_KEY, %EV_SW) + * + * This function parses stringified bitmap from @buf and disables/enables + * GPIO buttons accordinly. Returns 0 on success and negative error + * on failure. + */ +static ssize_t gpio_keys_attr_store_helper(struct gpio_keys_drvdata *ddata, + const char *buf, unsigned int type) +{ + int n_events = get_n_events_by_type(type); + unsigned long *bits; + ssize_t error; + int i; + + bits = kcalloc(BITS_TO_LONGS(n_events), sizeof(*bits), GFP_KERNEL); + if (!bits) + return -ENOMEM; + + error = bitmap_parselist(buf, bits, n_events); + if (error) + goto out; + + /* First validate */ + for (i = 0; i < ddata->n_buttons; i++) { + struct gpio_button_data *bdata = &ddata->data[i]; + + if (bdata->button->type != type) + continue; + + if (test_bit(bdata->button->code, bits) && + !bdata->button->can_disable) { + error = -EINVAL; + goto out; + } + } + + mutex_lock(&ddata->disable_lock); + + for (i = 0; i < ddata->n_buttons; i++) { + struct gpio_button_data *bdata = &ddata->data[i]; + + if (bdata->button->type != type) + continue; + + if (test_bit(bdata->button->code, bits)) + gpio_keys_disable_button(bdata); + else + gpio_keys_enable_button(bdata); + } + + mutex_unlock(&ddata->disable_lock); + +out: + kfree(bits); + return error; +} + +#define ATTR_SHOW_FN(name, type, only_disabled) \ +static ssize_t gpio_keys_show_##name(struct device *dev, \ + struct device_attribute *attr, \ + char *buf) \ +{ \ + struct platform_device *pdev = to_platform_device(dev); \ + struct gpio_keys_drvdata *ddata = platform_get_drvdata(pdev); \ + \ + return gpio_keys_attr_show_helper(ddata, buf, \ + type, only_disabled); \ +} + +ATTR_SHOW_FN(keys, EV_KEY, false); +ATTR_SHOW_FN(switches, EV_SW, false); +ATTR_SHOW_FN(disabled_keys, EV_KEY, true); +ATTR_SHOW_FN(disabled_switches, EV_SW, true); + +/* + * ATTRIBUTES: + * + * /sys/devices/platform/gpio-keys/keys [ro] + * /sys/devices/platform/gpio-keys/switches [ro] + */ +static DEVICE_ATTR(keys, S_IRUGO, gpio_keys_show_keys, NULL); +static DEVICE_ATTR(switches, S_IRUGO, gpio_keys_show_switches, NULL); + +#define ATTR_STORE_FN(name, type) \ +static ssize_t gpio_keys_store_##name(struct device *dev, \ + struct device_attribute *attr, \ + const char *buf, \ + size_t count) \ +{ \ + struct platform_device *pdev = to_platform_device(dev); \ + struct gpio_keys_drvdata *ddata = platform_get_drvdata(pdev); \ + ssize_t error; \ + \ + error = gpio_keys_attr_store_helper(ddata, buf, type); \ + if (error) \ + return error; \ + \ + return count; \ +} + +ATTR_STORE_FN(disabled_keys, EV_KEY); +ATTR_STORE_FN(disabled_switches, EV_SW); + +/* + * ATTRIBUTES: + * + * /sys/devices/platform/gpio-keys/disabled_keys [rw] + * /sys/devices/platform/gpio-keys/disables_switches [rw] + */ +static DEVICE_ATTR(disabled_keys, S_IWUSR | S_IRUGO, + gpio_keys_show_disabled_keys, + gpio_keys_store_disabled_keys); +static DEVICE_ATTR(disabled_switches, S_IWUSR | S_IRUGO, + gpio_keys_show_disabled_switches, + gpio_keys_store_disabled_switches); + +static struct attribute *gpio_keys_attrs[] = { + &dev_attr_keys.attr, + &dev_attr_switches.attr, + &dev_attr_disabled_keys.attr, + &dev_attr_disabled_switches.attr, + NULL, +}; + +static struct attribute_group gpio_keys_attr_group = { + .attrs = gpio_keys_attrs, +}; + static void gpio_keys_report_event(struct gpio_button_data *bdata) { struct gpio_keys_button *button = bdata->button; @@ -79,11 +355,13 @@ static irqreturn_t gpio_keys_isr(int irq, void *dev_id) return IRQ_HANDLED; } -static int __devinit gpio_keys_setup_key(struct device *dev, +static int __devinit gpio_keys_setup_key(struct platform_device *pdev, struct gpio_button_data *bdata, struct gpio_keys_button *button) { char *desc = button->desc ? button->desc : "gpio_keys"; + struct device *dev = &pdev->dev; + unsigned long irqflags; int irq, error; setup_timer(&bdata->timer, gpio_keys_timer, (unsigned long)bdata); @@ -112,10 +390,15 @@ static int __devinit gpio_keys_setup_key(struct device *dev, goto fail3; } - error = request_irq(irq, gpio_keys_isr, - IRQF_SHARED | - IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, - desc, bdata); + irqflags = IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING; + /* + * If platform has specified that the button can be disabled, + * we don't want it to share the interrupt line. + */ + if (!button->can_disable) + irqflags |= IRQF_SHARED; + + error = request_irq(irq, gpio_keys_isr, irqflags, desc, bdata); if (error) { dev_err(dev, "Unable to claim irq %d; error %d\n", irq, error); @@ -149,6 +432,10 @@ static int __devinit gpio_keys_probe(struct platform_device *pdev) goto fail1; } + ddata->input = input; + ddata->n_buttons = pdata->nbuttons; + mutex_init(&ddata->disable_lock); + platform_set_drvdata(pdev, ddata); input->name = pdev->name; @@ -164,8 +451,6 @@ static int __devinit gpio_keys_probe(struct platform_device *pdev) if (pdata->rep) __set_bit(EV_REP, input->evbit); - ddata->input = input; - for (i = 0; i < pdata->nbuttons; i++) { struct gpio_keys_button *button = &pdata->buttons[i]; struct gpio_button_data *bdata = &ddata->data[i]; @@ -174,7 +459,7 @@ static int __devinit gpio_keys_probe(struct platform_device *pdev) bdata->input = input; bdata->button = button; - error = gpio_keys_setup_key(dev, bdata, button); + error = gpio_keys_setup_key(pdev, bdata, button); if (error) goto fail2; @@ -184,13 +469,20 @@ static int __devinit gpio_keys_probe(struct platform_device *pdev) input_set_capability(input, type, button->code); } - error = input_register_device(input); + error = sysfs_create_group(&pdev->dev.kobj, &gpio_keys_attr_group); if (error) { - dev_err(dev, "Unable to register input device, " - "error: %d\n", error); + dev_err(dev, "Unable to export keys/switches, error: %d\n", + error); goto fail2; } + error = input_register_device(input); + if (error) { + dev_err(dev, "Unable to register input device, error: %d\n", + error); + goto fail3; + } + /* get current state of buttons */ for (i = 0; i < pdata->nbuttons; i++) gpio_keys_report_event(&ddata->data[i]); @@ -200,6 +492,8 @@ static int __devinit gpio_keys_probe(struct platform_device *pdev) return 0; + fail3: + sysfs_remove_group(&pdev->dev.kobj, &gpio_keys_attr_group); fail2: while (--i >= 0) { free_irq(gpio_to_irq(pdata->buttons[i].gpio), &ddata->data[i]); @@ -224,6 +518,8 @@ static int __devexit gpio_keys_remove(struct platform_device *pdev) struct input_dev *input = ddata->input; int i; + sysfs_remove_group(&pdev->dev.kobj, &gpio_keys_attr_group); + device_init_wakeup(&pdev->dev, 0); for (i = 0; i < pdata->nbuttons; i++) { diff --git a/include/linux/gpio_keys.h b/include/linux/gpio_keys.h index 1289fa7623ca..cd0b3f30f48e 100644 --- a/include/linux/gpio_keys.h +++ b/include/linux/gpio_keys.h @@ -10,6 +10,7 @@ struct gpio_keys_button { int type; /* input event type (EV_KEY, EV_SW) */ int wakeup; /* configure the button as a wake-up source */ int debounce_interval; /* debounce ticks interval in msecs */ + bool can_disable; }; struct gpio_keys_platform_data { -- cgit v1.2.3 From c9404c9c392d557a4687c4cbda022b03cb787ce9 Mon Sep 17 00:00:00 2001 From: Adam Buchbinder Date: Fri, 18 Dec 2009 15:40:42 -0500 Subject: Fix misspelling of "should" and "shouldn't" in comments. Some comments misspell "should" or "shouldn't"; this fixes them. No code changes. Signed-off-by: Adam Buchbinder Signed-off-by: Jiri Kosina --- arch/x86/kernel/ptrace.c | 2 +- drivers/ata/libata-core.c | 2 +- drivers/gpu/drm/radeon/atombios.h | 2 +- drivers/ieee1394/pcilynx.c | 2 +- drivers/input/tablet/aiptek.c | 2 +- drivers/mmc/card/sdio_uart.c | 2 +- drivers/scsi/lpfc/lpfc_scsi.c | 4 ++-- drivers/video/sstfb.c | 2 +- fs/locks.c | 2 +- kernel/audit.c | 2 +- mm/slub.c | 2 +- 11 files changed, 12 insertions(+), 12 deletions(-) (limited to 'drivers/input') diff --git a/arch/x86/kernel/ptrace.c b/arch/x86/kernel/ptrace.c index 017d937639fe..118428085ea2 100644 --- a/arch/x86/kernel/ptrace.c +++ b/arch/x86/kernel/ptrace.c @@ -604,7 +604,7 @@ ptrace_modify_breakpoint(struct perf_event *bp, int len, int type, struct perf_event_attr attr; /* - * We shoud have at least an inactive breakpoint at this + * We should have at least an inactive breakpoint at this * slot. It means the user is writing dr7 without having * written the address register first */ diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 6728328f3bea..698ef474767e 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -2232,7 +2232,7 @@ retry: * Some drives were very specific about that exact sequence. * * Note that ATA4 says lba is mandatory so the second check - * shoud never trigger. + * should never trigger. */ if (ata_id_major_version(id) < 4 || !ata_id_has_lba(id)) { err_mask = ata_dev_init_params(dev, id[3], id[6]); diff --git a/drivers/gpu/drm/radeon/atombios.h b/drivers/gpu/drm/radeon/atombios.h index 91ad0d1c1b17..2a88029f6a1e 100644 --- a/drivers/gpu/drm/radeon/atombios.h +++ b/drivers/gpu/drm/radeon/atombios.h @@ -2275,7 +2275,7 @@ typedef struct _ATOM_LCD_RTS_RECORD { UCHAR ucRTSValue; } ATOM_LCD_RTS_RECORD; -/* !! If the record below exits, it shoud always be the first record for easy use in command table!!! */ +/* !! If the record below exits, it should always be the first record for easy use in command table!!! */ typedef struct _ATOM_LCD_MODE_CONTROL_CAP { UCHAR ucRecordType; USHORT usLCDCap; diff --git a/drivers/ieee1394/pcilynx.c b/drivers/ieee1394/pcilynx.c index 9555fd253865..bf47fee79808 100644 --- a/drivers/ieee1394/pcilynx.c +++ b/drivers/ieee1394/pcilynx.c @@ -1452,7 +1452,7 @@ static int __devinit add_card(struct pci_dev *dev, PRINT(KERN_ERR, lynx->id, "unable to read bus info block from i2c"); } else { PRINT(KERN_INFO, lynx->id, "got bus info block from serial eeprom"); - /* FIXME: probably we shoud rewrite the max_rec, max_ROM(1394a), + /* FIXME: probably we should rewrite the max_rec, max_ROM(1394a), * generation(1394a) and link_spd(1394a) field and recalculate * the CRC */ diff --git a/drivers/input/tablet/aiptek.c b/drivers/input/tablet/aiptek.c index 7d005a3616d7..4be039d7dcad 100644 --- a/drivers/input/tablet/aiptek.c +++ b/drivers/input/tablet/aiptek.c @@ -362,7 +362,7 @@ static const int macroKeyEvents[] = { }; /*********************************************************************** - * Map values to strings and back. Every map shoudl have the following + * Map values to strings and back. Every map should have the following * as its last element: { NULL, AIPTEK_INVALID_VALUE }. */ #define AIPTEK_INVALID_VALUE -1 diff --git a/drivers/mmc/card/sdio_uart.c b/drivers/mmc/card/sdio_uart.c index f53755533e7e..a4e37758be41 100644 --- a/drivers/mmc/card/sdio_uart.c +++ b/drivers/mmc/card/sdio_uart.c @@ -581,7 +581,7 @@ static int uart_carrier_raised(struct tty_port *tport) struct sdio_uart_port *port = container_of(tport, struct sdio_uart_port, port); unsigned int ret = sdio_uart_claim_func(port); - if (ret) /* Missing hardware shoudn't block for carrier */ + if (ret) /* Missing hardware shouldn't block for carrier */ return 1; ret = sdio_uart_get_mctrl(port); sdio_uart_release_func(port); diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c index a246410ce9df..28c6bfd3e82e 100644 --- a/drivers/scsi/lpfc/lpfc_scsi.c +++ b/drivers/scsi/lpfc/lpfc_scsi.c @@ -1574,7 +1574,7 @@ lpfc_bg_scsi_prep_dma_buf(struct lpfc_hba *phba, case LPFC_PG_TYPE_NO_DIF: num_bde = lpfc_bg_setup_bpl(phba, scsi_cmnd, bpl, datasegcnt); - /* we shoud have 2 or more entries in buffer list */ + /* we should have 2 or more entries in buffer list */ if (num_bde < 2) goto err; break; @@ -1611,7 +1611,7 @@ lpfc_bg_scsi_prep_dma_buf(struct lpfc_hba *phba, num_bde = lpfc_bg_setup_bpl_prot(phba, scsi_cmnd, bpl, datasegcnt, protsegcnt); - /* we shoud have 3 or more entries in buffer list */ + /* we should have 3 or more entries in buffer list */ if (num_bde < 3) goto err; break; diff --git a/drivers/video/sstfb.c b/drivers/video/sstfb.c index 609d0a521ca2..79840f11fecb 100644 --- a/drivers/video/sstfb.c +++ b/drivers/video/sstfb.c @@ -1102,7 +1102,7 @@ static void sst_set_vidmod_ics(struct fb_info *info, const int bpp) * detect dac type * prerequisite : write to FbiInitx enabled, video and fbi and pci fifo reset, * dram refresh disabled, FbiInit remaped. - * TODO: mmh.. maybe i shoud put the "prerequisite" in the func ... + * TODO: mmh.. maybe i should put the "prerequisite" in the func ... */ diff --git a/fs/locks.c b/fs/locks.c index a8794f233bc9..cde572db112f 100644 --- a/fs/locks.c +++ b/fs/locks.c @@ -1454,7 +1454,7 @@ EXPORT_SYMBOL(generic_setlease); * leases held by processes on this node. * * There is also no break_lease method; filesystems that - * handle their own leases shoud break leases themselves from the + * handle their own leases should break leases themselves from the * filesystem's open, create, and (on truncate) setattr methods. * * Warning: the only current setlease methods exist only to disable diff --git a/kernel/audit.c b/kernel/audit.c index 5feed232be9d..78f7f86aa238 100644 --- a/kernel/audit.c +++ b/kernel/audit.c @@ -398,7 +398,7 @@ static void kauditd_send_skb(struct sk_buff *skb) skb_get(skb); err = netlink_unicast(audit_sock, skb, audit_nlk_pid, 0); if (err < 0) { - BUG_ON(err != -ECONNREFUSED); /* Shoudn't happen */ + BUG_ON(err != -ECONNREFUSED); /* Shouldn't happen */ printk(KERN_ERR "audit: *NO* daemon at audit_pid=%d\n", audit_pid); audit_log_lost("auditd dissapeared\n"); audit_pid = 0; diff --git a/mm/slub.c b/mm/slub.c index 8d71aaf888d7..00e0961b11fe 100644 --- a/mm/slub.c +++ b/mm/slub.c @@ -3086,7 +3086,7 @@ static void slab_mem_offline_callback(void *arg) /* * if n->nr_slabs > 0, slabs still exist on the node * that is going down. We were unable to free them, - * and offline_pages() function shoudn't call this + * and offline_pages() function shouldn't call this * callback. So, we must fail. */ BUG_ON(slabs_node(s, offline_node)); -- cgit v1.2.3 From 0747e3bc54b43faaa88ab0b37eb5b6f50972965b Mon Sep 17 00:00:00 2001 From: Stefan Weil Date: Thu, 7 Jan 2010 00:44:08 +0100 Subject: Fix spelling of 'platform' in log messages Replace platfrom -> platform. Signed-off-by: Stefan Weil Signed-off-by: Jiri Kosina --- drivers/input/serio/i8042.c | 2 +- drivers/net/davinci_emac.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/input') diff --git a/drivers/input/serio/i8042.c b/drivers/input/serio/i8042.c index d84a36e545f6..33f3541aaf96 100644 --- a/drivers/input/serio/i8042.c +++ b/drivers/input/serio/i8042.c @@ -430,7 +430,7 @@ static bool i8042_filter(unsigned char data, unsigned char str, } if (i8042_platform_filter && i8042_platform_filter(data, str, serio)) { - dbg("Filtered out by platfrom filter\n"); + dbg("Filtered out by platform filter\n"); return true; } diff --git a/drivers/net/davinci_emac.c b/drivers/net/davinci_emac.c index 33c4fe26178c..ea49d6ec4cba 100644 --- a/drivers/net/davinci_emac.c +++ b/drivers/net/davinci_emac.c @@ -2651,7 +2651,7 @@ static int __devinit davinci_emac_probe(struct platform_device *pdev) pdata = pdev->dev.platform_data; if (!pdata) { - printk(KERN_ERR "DaVinci EMAC: No platfrom data\n"); + printk(KERN_ERR "DaVinci EMAC: No platform data\n"); return -ENODEV; } -- cgit v1.2.3 From 32974ad4907cdde6c9de612cd1b2ee0568fb9409 Mon Sep 17 00:00:00 2001 From: Tony Luck Date: Mon, 8 Feb 2010 10:42:17 -0800 Subject: [IA64] Remove COMPAT_IA32 support This has been broken since May 2008 when Al Viro killed altroot support. Since nobody has complained, it would appear that there are no users of this code (A plausible theory since the main OSVs that support ia64 prefer to use the IA32-EL software emulation). Signed-off-by: Tony Luck --- arch/ia64/Kconfig | 17 - arch/ia64/Makefile | 1 - arch/ia64/configs/bigsur_defconfig | 2 - arch/ia64/configs/generic_defconfig | 2 - arch/ia64/configs/gensparse_defconfig | 2 - arch/ia64/configs/sim_defconfig | 2 - arch/ia64/configs/tiger_defconfig | 1 - arch/ia64/configs/xen_domu_defconfig | 2 - arch/ia64/configs/zx1_defconfig | 2 - arch/ia64/ia32/Makefile | 11 - arch/ia64/ia32/audit.c | 42 - arch/ia64/ia32/binfmt_elf32.c | 245 --- arch/ia64/ia32/elfcore32.h | 148 -- arch/ia64/ia32/ia32_entry.S | 468 ------ arch/ia64/ia32/ia32_ldt.c | 146 -- arch/ia64/ia32/ia32_signal.c | 1010 ------------ arch/ia64/ia32/ia32_support.c | 253 --- arch/ia64/ia32/ia32_traps.c | 156 -- arch/ia64/ia32/ia32priv.h | 532 ------- arch/ia64/ia32/sys_ia32.c | 2765 --------------------------------- arch/ia64/include/asm/ia32.h | 40 - arch/ia64/include/asm/processor.h | 46 - arch/ia64/include/asm/syscall.h | 81 - arch/ia64/include/asm/system.h | 11 +- arch/ia64/include/asm/unistd.h | 14 - arch/ia64/kernel/audit.c | 21 - arch/ia64/kernel/entry.S | 39 - arch/ia64/kernel/ivt.S | 114 -- arch/ia64/kernel/process.c | 55 +- arch/ia64/kernel/ptrace.c | 14 +- arch/ia64/kernel/setup.c | 5 - arch/ia64/kernel/signal.c | 54 +- arch/ia64/kernel/smpboot.c | 5 - arch/ia64/kernel/traps.c | 9 - arch/ia64/mm/init.c | 5 - arch/ia64/xen/hypercall.S | 5 - arch/ia64/xen/xen_pv_ops.c | 16 - drivers/input/input-compat.h | 2 - 38 files changed, 20 insertions(+), 6323 deletions(-) delete mode 100644 arch/ia64/ia32/Makefile delete mode 100644 arch/ia64/ia32/audit.c delete mode 100644 arch/ia64/ia32/binfmt_elf32.c delete mode 100644 arch/ia64/ia32/elfcore32.h delete mode 100644 arch/ia64/ia32/ia32_entry.S delete mode 100644 arch/ia64/ia32/ia32_ldt.c delete mode 100644 arch/ia64/ia32/ia32_signal.c delete mode 100644 arch/ia64/ia32/ia32_support.c delete mode 100644 arch/ia64/ia32/ia32_traps.c delete mode 100644 arch/ia64/ia32/ia32priv.h delete mode 100644 arch/ia64/ia32/sys_ia32.c delete mode 100644 arch/ia64/include/asm/ia32.h (limited to 'drivers/input') diff --git a/arch/ia64/Kconfig b/arch/ia64/Kconfig index 2d7f56a98e0f..9a50d7dd2a0b 100644 --- a/arch/ia64/Kconfig +++ b/arch/ia64/Kconfig @@ -499,23 +499,6 @@ config ARCH_PROC_KCORE_TEXT def_bool y depends on PROC_KCORE -config IA32_SUPPORT - bool "Support for Linux/x86 binaries" - help - IA-64 processors can execute IA-32 (X86) instructions. By - saying Y here, the kernel will include IA-32 system call - emulation support which makes it possible to transparently - run IA-32 Linux binaries on an IA-64 Linux system. - If in doubt, say Y. - -config COMPAT - bool - depends on IA32_SUPPORT - default y - -config COMPAT_FOR_U64_ALIGNMENT - def_bool COMPAT - config IA64_MCA_RECOVERY tristate "MCA recovery from errors other than TLB." diff --git a/arch/ia64/Makefile b/arch/ia64/Makefile index 475e2725fbde..8ae0d2604ce1 100644 --- a/arch/ia64/Makefile +++ b/arch/ia64/Makefile @@ -46,7 +46,6 @@ head-y := arch/ia64/kernel/head.o arch/ia64/kernel/init_task.o libs-y += arch/ia64/lib/ core-y += arch/ia64/kernel/ arch/ia64/mm/ -core-$(CONFIG_IA32_SUPPORT) += arch/ia64/ia32/ core-$(CONFIG_IA64_DIG) += arch/ia64/dig/ core-$(CONFIG_IA64_DIG_VTD) += arch/ia64/dig/ core-$(CONFIG_IA64_GENERIC) += arch/ia64/dig/ diff --git a/arch/ia64/configs/bigsur_defconfig b/arch/ia64/configs/bigsur_defconfig index ace41096b47b..312b12094a1d 100644 --- a/arch/ia64/configs/bigsur_defconfig +++ b/arch/ia64/configs/bigsur_defconfig @@ -131,8 +131,6 @@ CONFIG_ARCH_DISCONTIGMEM_ENABLE=y CONFIG_ARCH_FLATMEM_ENABLE=y CONFIG_ARCH_SPARSEMEM_ENABLE=y # CONFIG_VIRTUAL_MEM_MAP is not set -CONFIG_IA32_SUPPORT=y -CONFIG_COMPAT=y # CONFIG_IA64_MCA_RECOVERY is not set CONFIG_PERFMON=y CONFIG_IA64_PALINFO=y diff --git a/arch/ia64/configs/generic_defconfig b/arch/ia64/configs/generic_defconfig index 75645495c2dd..6a4cc506fb5f 100644 --- a/arch/ia64/configs/generic_defconfig +++ b/arch/ia64/configs/generic_defconfig @@ -205,8 +205,6 @@ CONFIG_VIRTUAL_MEM_MAP=y CONFIG_HOLES_IN_ZONE=y CONFIG_HAVE_ARCH_EARLY_PFN_TO_NID=y CONFIG_HAVE_ARCH_NODEDATA_EXTENSION=y -CONFIG_IA32_SUPPORT=y -CONFIG_COMPAT=y CONFIG_COMPAT_FOR_U64_ALIGNMENT=y CONFIG_IA64_MCA_RECOVERY=y CONFIG_PERFMON=y diff --git a/arch/ia64/configs/gensparse_defconfig b/arch/ia64/configs/gensparse_defconfig index e86fbd39c795..2dc185b0f9a3 100644 --- a/arch/ia64/configs/gensparse_defconfig +++ b/arch/ia64/configs/gensparse_defconfig @@ -139,8 +139,6 @@ CONFIG_ARCH_SPARSEMEM_ENABLE=y CONFIG_ARCH_DISCONTIGMEM_DEFAULT=y CONFIG_NUMA=y CONFIG_HAVE_ARCH_EARLY_PFN_TO_NID=y -CONFIG_IA32_SUPPORT=y -CONFIG_COMPAT=y CONFIG_IA64_MCA_RECOVERY=y CONFIG_PERFMON=y CONFIG_IA64_PALINFO=y diff --git a/arch/ia64/configs/sim_defconfig b/arch/ia64/configs/sim_defconfig index 546a772f438e..21a23cdfd41c 100644 --- a/arch/ia64/configs/sim_defconfig +++ b/arch/ia64/configs/sim_defconfig @@ -130,8 +130,6 @@ CONFIG_ARCH_DISCONTIGMEM_ENABLE=y CONFIG_ARCH_FLATMEM_ENABLE=y CONFIG_ARCH_SPARSEMEM_ENABLE=y # CONFIG_VIRTUAL_MEM_MAP is not set -CONFIG_IA32_SUPPORT=y -CONFIG_COMPAT=y # CONFIG_IA64_MCA_RECOVERY is not set # CONFIG_PERFMON is not set CONFIG_IA64_PALINFO=m diff --git a/arch/ia64/configs/tiger_defconfig b/arch/ia64/configs/tiger_defconfig index c522edf23c62..c5a5ea9d54ae 100644 --- a/arch/ia64/configs/tiger_defconfig +++ b/arch/ia64/configs/tiger_defconfig @@ -154,7 +154,6 @@ CONFIG_ARCH_SPARSEMEM_ENABLE=y CONFIG_ARCH_POPULATES_NODE_MAP=y CONFIG_VIRTUAL_MEM_MAP=y CONFIG_HOLES_IN_ZONE=y -# CONFIG_IA32_SUPPORT is not set CONFIG_IA64_MCA_RECOVERY=y CONFIG_PERFMON=y CONFIG_IA64_PALINFO=y diff --git a/arch/ia64/configs/xen_domu_defconfig b/arch/ia64/configs/xen_domu_defconfig index 0bb0714dc19d..c67eafc4bb38 100644 --- a/arch/ia64/configs/xen_domu_defconfig +++ b/arch/ia64/configs/xen_domu_defconfig @@ -200,8 +200,6 @@ CONFIG_ARCH_SPARSEMEM_ENABLE=y CONFIG_ARCH_POPULATES_NODE_MAP=y CONFIG_VIRTUAL_MEM_MAP=y CONFIG_HOLES_IN_ZONE=y -# CONFIG_IA32_SUPPORT is not set -# CONFIG_COMPAT_FOR_U64_ALIGNMENT is not set CONFIG_IA64_MCA_RECOVERY=y CONFIG_PERFMON=y CONFIG_IA64_PALINFO=y diff --git a/arch/ia64/configs/zx1_defconfig b/arch/ia64/configs/zx1_defconfig index 514f0635dafe..3cec65b534c2 100644 --- a/arch/ia64/configs/zx1_defconfig +++ b/arch/ia64/configs/zx1_defconfig @@ -150,8 +150,6 @@ CONFIG_ARCH_DISCONTIGMEM_DEFAULT=y CONFIG_ARCH_POPULATES_NODE_MAP=y CONFIG_VIRTUAL_MEM_MAP=y CONFIG_HOLES_IN_ZONE=y -CONFIG_IA32_SUPPORT=y -CONFIG_COMPAT=y CONFIG_IA64_MCA_RECOVERY=y CONFIG_PERFMON=y CONFIG_IA64_PALINFO=y diff --git a/arch/ia64/ia32/Makefile b/arch/ia64/ia32/Makefile deleted file mode 100644 index baad8c7699c0..000000000000 --- a/arch/ia64/ia32/Makefile +++ /dev/null @@ -1,11 +0,0 @@ -# -# Makefile for the ia32 kernel emulation subsystem. -# - -obj-y := ia32_entry.o sys_ia32.o ia32_signal.o \ - ia32_support.o ia32_traps.o binfmt_elf32.o ia32_ldt.o -obj-$(CONFIG_AUDIT) += audit.o - -# Don't let GCC uses f16-f31 so that save_ia32_fpstate_live() and -# restore_ia32_fpstate_live() can be sure the live register contain user-level state. -CFLAGS_ia32_signal.o += -mfixed-range=f16-f31 diff --git a/arch/ia64/ia32/audit.c b/arch/ia64/ia32/audit.c deleted file mode 100644 index 5c93ddd1e42d..000000000000 --- a/arch/ia64/ia32/audit.c +++ /dev/null @@ -1,42 +0,0 @@ -#include "../../x86/include/asm/unistd_32.h" - -unsigned ia32_dir_class[] = { -#include -~0U -}; - -unsigned ia32_chattr_class[] = { -#include -~0U -}; - -unsigned ia32_write_class[] = { -#include -~0U -}; - -unsigned ia32_read_class[] = { -#include -~0U -}; - -unsigned ia32_signal_class[] = { -#include -~0U -}; - -int ia32_classify_syscall(unsigned syscall) -{ - switch(syscall) { - case __NR_open: - return 2; - case __NR_openat: - return 3; - case __NR_socketcall: - return 4; - case __NR_execve: - return 5; - default: - return 1; - } -} diff --git a/arch/ia64/ia32/binfmt_elf32.c b/arch/ia64/ia32/binfmt_elf32.c deleted file mode 100644 index c69552bf893e..000000000000 --- a/arch/ia64/ia32/binfmt_elf32.c +++ /dev/null @@ -1,245 +0,0 @@ -/* - * IA-32 ELF support. - * - * Copyright (C) 1999 Arun Sharma - * Copyright (C) 2001 Hewlett-Packard Co - * David Mosberger-Tang - * - * 06/16/00 A. Mallick initialize csd/ssd/tssd/cflg for ia32_load_state - * 04/13/01 D. Mosberger dropped saving tssd in ar.k1---it's not needed - * 09/14/01 D. Mosberger fixed memory management for gdt/tss page - */ - -#include -#include -#include - -#include -#include - -#include "ia32priv.h" -#include "elfcore32.h" - -/* Override some function names */ -#undef start_thread -#define start_thread ia32_start_thread -#define elf_format elf32_format -#define init_elf_binfmt init_elf32_binfmt -#define exit_elf_binfmt exit_elf32_binfmt - -#undef CLOCKS_PER_SEC -#define CLOCKS_PER_SEC IA32_CLOCKS_PER_SEC - -extern void ia64_elf32_init (struct pt_regs *regs); - -static void elf32_set_personality (void); - -static unsigned long __attribute ((unused)) -randomize_stack_top(unsigned long stack_top); - -#define setup_arg_pages(bprm,tos,exec) ia32_setup_arg_pages(bprm,exec) -#define elf_map elf32_map - -#undef SET_PERSONALITY -#define SET_PERSONALITY(ex) elf32_set_personality() - -#define elf_read_implies_exec(ex, have_pt_gnu_stack) (!(have_pt_gnu_stack)) - -/* Ugly but avoids duplication */ -#include "../../../fs/binfmt_elf.c" - -extern struct page *ia32_shared_page[]; -extern unsigned long *ia32_gdt; -extern struct page *ia32_gate_page; - -int -ia32_install_shared_page (struct vm_area_struct *vma, struct vm_fault *vmf) -{ - vmf->page = ia32_shared_page[smp_processor_id()]; - get_page(vmf->page); - return 0; -} - -int -ia32_install_gate_page (struct vm_area_struct *vma, struct vm_fault *vmf) -{ - vmf->page = ia32_gate_page; - get_page(vmf->page); - return 0; -} - - -static const struct vm_operations_struct ia32_shared_page_vm_ops = { - .fault = ia32_install_shared_page -}; - -static const struct vm_operations_struct ia32_gate_page_vm_ops = { - .fault = ia32_install_gate_page -}; - -void -ia64_elf32_init (struct pt_regs *regs) -{ - struct vm_area_struct *vma; - - /* - * Map GDT below 4GB, where the processor can find it. We need to map - * it with privilege level 3 because the IVE uses non-privileged accesses to these - * tables. IA-32 segmentation is used to protect against IA-32 accesses to them. - */ - vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL); - if (vma) { - vma->vm_mm = current->mm; - vma->vm_start = IA32_GDT_OFFSET; - vma->vm_end = vma->vm_start + PAGE_SIZE; - vma->vm_page_prot = PAGE_SHARED; - vma->vm_flags = VM_READ|VM_MAYREAD|VM_RESERVED; - vma->vm_ops = &ia32_shared_page_vm_ops; - down_write(¤t->mm->mmap_sem); - { - if (insert_vm_struct(current->mm, vma)) { - kmem_cache_free(vm_area_cachep, vma); - up_write(¤t->mm->mmap_sem); - BUG(); - } - } - up_write(¤t->mm->mmap_sem); - } - - /* - * When user stack is not executable, push sigreturn code to stack makes - * segmentation fault raised when returning to kernel. So now sigreturn - * code is locked in specific gate page, which is pointed by pretcode - * when setup_frame_ia32 - */ - vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL); - if (vma) { - vma->vm_mm = current->mm; - vma->vm_start = IA32_GATE_OFFSET; - vma->vm_end = vma->vm_start + PAGE_SIZE; - vma->vm_page_prot = PAGE_COPY_EXEC; - vma->vm_flags = VM_READ | VM_MAYREAD | VM_EXEC - | VM_MAYEXEC | VM_RESERVED; - vma->vm_ops = &ia32_gate_page_vm_ops; - down_write(¤t->mm->mmap_sem); - { - if (insert_vm_struct(current->mm, vma)) { - kmem_cache_free(vm_area_cachep, vma); - up_write(¤t->mm->mmap_sem); - BUG(); - } - } - up_write(¤t->mm->mmap_sem); - } - - /* - * Install LDT as anonymous memory. This gives us all-zero segment descriptors - * until a task modifies them via modify_ldt(). - */ - vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL); - if (vma) { - vma->vm_mm = current->mm; - vma->vm_start = IA32_LDT_OFFSET; - vma->vm_end = vma->vm_start + PAGE_ALIGN(IA32_LDT_ENTRIES*IA32_LDT_ENTRY_SIZE); - vma->vm_page_prot = PAGE_SHARED; - vma->vm_flags = VM_READ|VM_WRITE|VM_MAYREAD|VM_MAYWRITE; - down_write(¤t->mm->mmap_sem); - { - if (insert_vm_struct(current->mm, vma)) { - kmem_cache_free(vm_area_cachep, vma); - up_write(¤t->mm->mmap_sem); - BUG(); - } - } - up_write(¤t->mm->mmap_sem); - } - - ia64_psr(regs)->ac = 0; /* turn off alignment checking */ - regs->loadrs = 0; - /* - * According to the ABI %edx points to an `atexit' handler. Since we don't have - * one we'll set it to 0 and initialize all the other registers just to make - * things more deterministic, ala the i386 implementation. - */ - regs->r8 = 0; /* %eax */ - regs->r11 = 0; /* %ebx */ - regs->r9 = 0; /* %ecx */ - regs->r10 = 0; /* %edx */ - regs->r13 = 0; /* %ebp */ - regs->r14 = 0; /* %esi */ - regs->r15 = 0; /* %edi */ - - current->thread.eflag = IA32_EFLAG; - current->thread.fsr = IA32_FSR_DEFAULT; - current->thread.fcr = IA32_FCR_DEFAULT; - current->thread.fir = 0; - current->thread.fdr = 0; - - /* - * Setup GDTD. Note: GDTD is the descrambled version of the pseudo-descriptor - * format defined by Figure 3-11 "Pseudo-Descriptor Format" in the IA-32 - * architecture manual. Also note that the only fields that are not ignored are - * `base', `limit', 'G', `P' (must be 1) and `S' (must be 0). - */ - regs->r31 = IA32_SEG_UNSCRAMBLE(IA32_SEG_DESCRIPTOR(IA32_GDT_OFFSET, IA32_PAGE_SIZE - 1, - 0, 0, 0, 1, 0, 0, 0)); - /* Setup the segment selectors */ - regs->r16 = (__USER_DS << 16) | __USER_DS; /* ES == DS, GS, FS are zero */ - regs->r17 = (__USER_DS << 16) | __USER_CS; /* SS, CS; ia32_load_state() sets TSS and LDT */ - - ia32_load_segment_descriptors(current); - ia32_load_state(current); -} - -/* - * Undo the override of setup_arg_pages() without this ia32_setup_arg_pages() - * will suffer infinite self recursion. - */ -#undef setup_arg_pages - -int -ia32_setup_arg_pages (struct linux_binprm *bprm, int executable_stack) -{ - int ret; - - ret = setup_arg_pages(bprm, IA32_STACK_TOP, executable_stack); - if (!ret) { - /* - * Can't do it in ia64_elf32_init(). Needs to be done before - * calls to elf32_map() - */ - current->thread.ppl = ia32_init_pp_list(); - } - - return ret; -} - -static void -elf32_set_personality (void) -{ - set_personality(PER_LINUX32); - current->thread.map_base = IA32_PAGE_OFFSET/3; -} - -static unsigned long -elf32_map(struct file *filep, unsigned long addr, struct elf_phdr *eppnt, - int prot, int type, unsigned long unused) -{ - unsigned long pgoff = (eppnt->p_vaddr) & ~IA32_PAGE_MASK; - - return ia32_do_mmap(filep, (addr & IA32_PAGE_MASK), eppnt->p_filesz + pgoff, prot, type, - eppnt->p_offset - pgoff); -} - -#define cpu_uses_ia32el() (local_cpu_data->family > 0x1f) - -static int __init check_elf32_binfmt(void) -{ - if (cpu_uses_ia32el()) { - printk("Please use IA-32 EL for executing IA-32 binaries\n"); - unregister_binfmt(&elf_format); - } - return 0; -} - -module_init(check_elf32_binfmt) diff --git a/arch/ia64/ia32/elfcore32.h b/arch/ia64/ia32/elfcore32.h deleted file mode 100644 index 657725742617..000000000000 --- a/arch/ia64/ia32/elfcore32.h +++ /dev/null @@ -1,148 +0,0 @@ -/* - * IA-32 ELF core dump support. - * - * Copyright (C) 2003 Arun Sharma - * - * Derived from the x86_64 version - */ -#ifndef _ELFCORE32_H_ -#define _ELFCORE32_H_ - -#include -#include - -/* Override elfcore.h */ -#define _LINUX_ELFCORE_H 1 -typedef unsigned int elf_greg_t; - -#define ELF_NGREG (sizeof (struct user_regs_struct32) / sizeof(elf_greg_t)) -typedef elf_greg_t elf_gregset_t[ELF_NGREG]; - -typedef struct ia32_user_i387_struct elf_fpregset_t; -typedef struct ia32_user_fxsr_struct elf_fpxregset_t; - -struct elf_siginfo -{ - int si_signo; /* signal number */ - int si_code; /* extra code */ - int si_errno; /* errno */ -}; - -#ifdef CONFIG_VIRT_CPU_ACCOUNTING -/* - * Hacks are here since types between compat_timeval (= pair of s32) and - * ia64-native timeval (= pair of s64) are not compatible, at least a file - * arch/ia64/ia32/../../../fs/binfmt_elf.c will get warnings from compiler on - * use of cputime_to_timeval(), which usually an alias of jiffies_to_timeval(). - */ -#define cputime_to_timeval(a,b) \ - do { (b)->tv_usec = 0; (b)->tv_sec = (a)/NSEC_PER_SEC; } while(0) -#else -#define jiffies_to_timeval(a,b) \ - do { (b)->tv_usec = 0; (b)->tv_sec = (a)/HZ; } while(0) -#endif - -struct elf_prstatus -{ - struct elf_siginfo pr_info; /* Info associated with signal */ - short pr_cursig; /* Current signal */ - unsigned int pr_sigpend; /* Set of pending signals */ - unsigned int pr_sighold; /* Set of held signals */ - pid_t pr_pid; - pid_t pr_ppid; - pid_t pr_pgrp; - pid_t pr_sid; - struct compat_timeval pr_utime; /* User time */ - struct compat_timeval pr_stime; /* System time */ - struct compat_timeval pr_cutime; /* Cumulative user time */ - struct compat_timeval pr_cstime; /* Cumulative system time */ - elf_gregset_t pr_reg; /* GP registers */ - int pr_fpvalid; /* True if math co-processor being used. */ -}; - -#define ELF_PRARGSZ (80) /* Number of chars for args */ - -struct elf_prpsinfo -{ - char pr_state; /* numeric process state */ - char pr_sname; /* char for pr_state */ - char pr_zomb; /* zombie */ - char pr_nice; /* nice val */ - unsigned int pr_flag; /* flags */ - __u16 pr_uid; - __u16 pr_gid; - pid_t pr_pid, pr_ppid, pr_pgrp, pr_sid; - /* Lots missing */ - char pr_fname[16]; /* filename of executable */ - char pr_psargs[ELF_PRARGSZ]; /* initial part of arg list */ -}; - -#define ELF_CORE_COPY_REGS(pr_reg, regs) \ - pr_reg[0] = regs->r11; \ - pr_reg[1] = regs->r9; \ - pr_reg[2] = regs->r10; \ - pr_reg[3] = regs->r14; \ - pr_reg[4] = regs->r15; \ - pr_reg[5] = regs->r13; \ - pr_reg[6] = regs->r8; \ - pr_reg[7] = regs->r16 & 0xffff; \ - pr_reg[8] = (regs->r16 >> 16) & 0xffff; \ - pr_reg[9] = (regs->r16 >> 32) & 0xffff; \ - pr_reg[10] = (regs->r16 >> 48) & 0xffff; \ - pr_reg[11] = regs->r1; \ - pr_reg[12] = regs->cr_iip; \ - pr_reg[13] = regs->r17 & 0xffff; \ - pr_reg[14] = ia64_getreg(_IA64_REG_AR_EFLAG); \ - pr_reg[15] = regs->r12; \ - pr_reg[16] = (regs->r17 >> 16) & 0xffff; - -static inline void elf_core_copy_regs(elf_gregset_t *elfregs, - struct pt_regs *regs) -{ - ELF_CORE_COPY_REGS((*elfregs), regs) -} - -static inline int elf_core_copy_task_regs(struct task_struct *t, - elf_gregset_t* elfregs) -{ - ELF_CORE_COPY_REGS((*elfregs), task_pt_regs(t)); - return 1; -} - -static inline int -elf_core_copy_task_fpregs(struct task_struct *tsk, struct pt_regs *regs, elf_fpregset_t *fpu) -{ - struct ia32_user_i387_struct *fpstate = (void*)fpu; - mm_segment_t old_fs; - - if (!tsk_used_math(tsk)) - return 0; - - old_fs = get_fs(); - set_fs(KERNEL_DS); - save_ia32_fpstate(tsk, (struct ia32_user_i387_struct __user *) fpstate); - set_fs(old_fs); - - return 1; -} - -#define ELF_CORE_COPY_XFPREGS 1 -#define ELF_CORE_XFPREG_TYPE NT_PRXFPREG -static inline int -elf_core_copy_task_xfpregs(struct task_struct *tsk, elf_fpxregset_t *xfpu) -{ - struct ia32_user_fxsr_struct *fpxstate = (void*) xfpu; - mm_segment_t old_fs; - - if (!tsk_used_math(tsk)) - return 0; - - old_fs = get_fs(); - set_fs(KERNEL_DS); - save_ia32_fpxstate(tsk, (struct ia32_user_fxsr_struct __user *) fpxstate); - set_fs(old_fs); - - return 1; -} - -#endif /* _ELFCORE32_H_ */ diff --git a/arch/ia64/ia32/ia32_entry.S b/arch/ia64/ia32/ia32_entry.S deleted file mode 100644 index 2fd7479aa216..000000000000 --- a/arch/ia64/ia32/ia32_entry.S +++ /dev/null @@ -1,468 +0,0 @@ -#include -#include -#include -#include -#include - -#include "../kernel/minstate.h" - - /* - * execve() is special because in case of success, we need to - * setup a null register window frame (in case an IA-32 process - * is exec'ing an IA-64 program). - */ -ENTRY(ia32_execve) - .prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(3) - alloc loc1=ar.pfs,3,2,4,0 - mov loc0=rp - .body - zxt4 out0=in0 // filename - ;; // stop bit between alloc and call - zxt4 out1=in1 // argv - zxt4 out2=in2 // envp - add out3=16,sp // regs - br.call.sptk.few rp=sys32_execve -1: cmp.ge p6,p0=r8,r0 - mov ar.pfs=loc1 // restore ar.pfs - ;; -(p6) mov ar.pfs=r0 // clear ar.pfs in case of success - sxt4 r8=r8 // return 64-bit result - mov rp=loc0 - br.ret.sptk.few rp -END(ia32_execve) - -ENTRY(ia32_clone) - .prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(5) - alloc r16=ar.pfs,5,2,6,0 - DO_SAVE_SWITCH_STACK - mov loc0=rp - mov loc1=r16 // save ar.pfs across do_fork - .body - zxt4 out1=in1 // newsp - mov out3=16 // stacksize (compensates for 16-byte scratch area) - adds out2=IA64_SWITCH_STACK_SIZE+16,sp // out2 = ®s - mov out0=in0 // out0 = clone_flags - zxt4 out4=in2 // out4 = parent_tidptr - zxt4 out5=in4 // out5 = child_tidptr - br.call.sptk.many rp=do_fork -.ret0: .restore sp - adds sp=IA64_SWITCH_STACK_SIZE,sp // pop the switch stack - mov ar.pfs=loc1 - mov rp=loc0 - br.ret.sptk.many rp -END(ia32_clone) - -GLOBAL_ENTRY(ia32_ret_from_clone) - PT_REGS_UNWIND_INFO(0) -{ /* - * Some versions of gas generate bad unwind info if the first instruction of a - * procedure doesn't go into the first slot of a bundle. This is a workaround. - */ - nop.m 0 - nop.i 0 - /* - * We need to call schedule_tail() to complete the scheduling process. - * Called by ia64_switch_to after do_fork()->copy_thread(). r8 contains the - * address of the previously executing task. - */ - br.call.sptk.many rp=ia64_invoke_schedule_tail -} -.ret1: - adds r2=TI_FLAGS+IA64_TASK_SIZE,r13 - ;; - ld4 r2=[r2] - ;; - mov r8=0 - and r2=_TIF_SYSCALL_TRACEAUDIT,r2 - ;; - cmp.ne p6,p0=r2,r0 -(p6) br.cond.spnt .ia32_strace_check_retval - ;; // prevent RAW on r8 -END(ia32_ret_from_clone) - // fall through -GLOBAL_ENTRY(ia32_ret_from_syscall) - PT_REGS_UNWIND_INFO(0) - - cmp.ge p6,p7=r8,r0 // syscall executed successfully? - adds r2=IA64_PT_REGS_R8_OFFSET+16,sp // r2 = &pt_regs.r8 - ;; - alloc r3=ar.pfs,0,0,0,0 // drop the syscall argument frame - st8 [r2]=r8 // store return value in slot for r8 - br.cond.sptk.many ia64_leave_kernel -END(ia32_ret_from_syscall) - - // - // Invoke a system call, but do some tracing before and after the call. - // We MUST preserve the current register frame throughout this routine - // because some system calls (such as ia64_execve) directly - // manipulate ar.pfs. - // - // Input: - // r8 = syscall number - // b6 = syscall entry point - // -GLOBAL_ENTRY(ia32_trace_syscall) - PT_REGS_UNWIND_INFO(0) - mov r3=-38 - adds r2=IA64_PT_REGS_R8_OFFSET+16,sp - ;; - st8 [r2]=r3 // initialize return code to -ENOSYS - br.call.sptk.few rp=syscall_trace_enter // give parent a chance to catch syscall args - cmp.lt p6,p0=r8,r0 // check tracehook - adds r2=IA64_PT_REGS_R8_OFFSET+16,sp // r2 = &pt_regs.r8 - ;; -(p6) st8.spill [r2]=r8 // store return value in slot for r8 -(p6) br.spnt.few .ret4 -.ret2: // Need to reload arguments (they may be changed by the tracing process) - adds r2=IA64_PT_REGS_R1_OFFSET+16,sp // r2 = &pt_regs.r1 - adds r3=IA64_PT_REGS_R13_OFFSET+16,sp // r3 = &pt_regs.r13 - mov r15=IA32_NR_syscalls - ;; - ld4 r8=[r2],IA64_PT_REGS_R9_OFFSET-IA64_PT_REGS_R1_OFFSET - movl r16=ia32_syscall_table - ;; - ld4 r33=[r2],8 // r9 == ecx - ld4 r37=[r3],16 // r13 == ebp - cmp.ltu.unc p6,p7=r8,r15 - ;; - ld4 r34=[r2],8 // r10 == edx - ld4 r36=[r3],8 // r15 == edi -(p6) shladd r16=r8,3,r16 // force ni_syscall if not valid syscall number - ;; - ld8 r16=[r16] - ;; - ld4 r32=[r2],8 // r11 == ebx - mov b6=r16 - ld4 r35=[r3],8 // r14 == esi - br.call.sptk.few rp=b6 // do the syscall -.ia32_strace_check_retval: - cmp.lt p6,p0=r8,r0 // syscall failed? - adds r2=IA64_PT_REGS_R8_OFFSET+16,sp // r2 = &pt_regs.r8 - ;; - st8.spill [r2]=r8 // store return value in slot for r8 - br.call.sptk.few rp=syscall_trace_leave // give parent a chance to catch return value -.ret4: alloc r2=ar.pfs,0,0,0,0 // drop the syscall argument frame - br.cond.sptk.many ia64_leave_kernel -END(ia32_trace_syscall) - -GLOBAL_ENTRY(sys32_vfork) - alloc r16=ar.pfs,2,2,4,0;; - mov out0=IA64_CLONE_VFORK|IA64_CLONE_VM|SIGCHLD // out0 = clone_flags - br.cond.sptk.few .fork1 // do the work -END(sys32_vfork) - -GLOBAL_ENTRY(sys32_fork) - .prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(2) - alloc r16=ar.pfs,2,2,4,0 - mov out0=SIGCHLD // out0 = clone_flags - ;; -.fork1: - mov loc0=rp - mov loc1=r16 // save ar.pfs across do_fork - DO_SAVE_SWITCH_STACK - - .body - - mov out1=0 - mov out3=0 - adds out2=IA64_SWITCH_STACK_SIZE+16,sp // out2 = ®s - br.call.sptk.few rp=do_fork -.ret5: .restore sp - adds sp=IA64_SWITCH_STACK_SIZE,sp // pop the switch stack - mov ar.pfs=loc1 - mov rp=loc0 - br.ret.sptk.many rp -END(sys32_fork) - - .rodata - .align 8 - .globl ia32_syscall_table -ia32_syscall_table: - data8 sys_ni_syscall /* 0 - old "setup(" system call*/ - data8 sys_exit - data8 sys32_fork - data8 sys_read - data8 sys_write - data8 compat_sys_open /* 5 */ - data8 sys_close - data8 sys32_waitpid - data8 sys_creat - data8 sys_link - data8 sys_unlink /* 10 */ - data8 ia32_execve - data8 sys_chdir - data8 compat_sys_time - data8 sys_mknod - data8 sys_chmod /* 15 */ - data8 sys_lchown /* 16-bit version */ - data8 sys_ni_syscall /* old break syscall holder */ - data8 sys_ni_syscall - data8 sys32_lseek - data8 sys_getpid /* 20 */ - data8 compat_sys_mount - data8 sys_oldumount - data8 sys_setuid /* 16-bit version */ - data8 sys_getuid /* 16-bit version */ - data8 compat_sys_stime /* 25 */ - data8 compat_sys_ptrace - data8 sys32_alarm - data8 sys_ni_syscall - data8 sys_pause - data8 compat_sys_utime /* 30 */ - data8 sys_ni_syscall /* old stty syscall holder */ - data8 sys_ni_syscall /* old gtty syscall holder */ - data8 sys_access - data8 sys_nice - data8 sys_ni_syscall /* 35 */ /* old ftime syscall holder */ - data8 sys_sync - data8 sys_kill - data8 sys_rename - data8 sys_mkdir - data8 sys_rmdir /* 40 */ - data8 sys_dup - data8 sys_ia64_pipe - data8 compat_sys_times - data8 sys_ni_syscall /* old prof syscall holder */ - data8 sys32_brk /* 45 */ - data8 sys_setgid /* 16-bit version */ - data8 sys_getgid /* 16-bit version */ - data8 sys32_signal - data8 sys_geteuid /* 16-bit version */ - data8 sys_getegid /* 16-bit version */ /* 50 */ - data8 sys_acct - data8 sys_umount /* recycled never used phys( */ - data8 sys_ni_syscall /* old lock syscall holder */ - data8 compat_sys_ioctl - data8 compat_sys_fcntl /* 55 */ - data8 sys_ni_syscall /* old mpx syscall holder */ - data8 sys_setpgid - data8 sys_ni_syscall /* old ulimit syscall holder */ - data8 sys_ni_syscall - data8 sys_umask /* 60 */ - data8 sys_chroot - data8 compat_sys_ustat - data8 sys_dup2 - data8 sys_getppid - data8 sys_getpgrp /* 65 */ - data8 sys_setsid - data8 sys32_sigaction - data8 sys_ni_syscall - data8 sys_ni_syscall - data8 sys_setreuid /* 16-bit version */ /* 70 */ - data8 sys_setregid /* 16-bit version */ - data8 sys32_sigsuspend - data8 compat_sys_sigpending - data8 sys_sethostname - data8 compat_sys_setrlimit /* 75 */ - data8 compat_sys_old_getrlimit - data8 compat_sys_getrusage - data8 compat_sys_gettimeofday - data8 compat_sys_settimeofday - data8 sys32_getgroups16 /* 80 */ - data8 sys32_setgroups16 - data8 sys32_old_select - data8 sys_symlink - data8 sys_ni_syscall - data8 sys_readlink /* 85 */ - data8 sys_uselib - data8 sys_swapon - data8 sys_reboot - data8 compat_sys_old_readdir - data8 sys32_mmap /* 90 */ - data8 sys32_munmap - data8 sys_truncate - data8 sys_ftruncate - data8 sys_fchmod - data8 sys_fchown /* 16-bit version */ /* 95 */ - data8 sys_getpriority - data8 sys_setpriority - data8 sys_ni_syscall /* old profil syscall holder */ - data8 compat_sys_statfs - data8 compat_sys_fstatfs /* 100 */ - data8 sys_ni_syscall /* ioperm */ - data8 compat_sys_socketcall - data8 sys_syslog - data8 compat_sys_setitimer - data8 compat_sys_getitimer /* 105 */ - data8 compat_sys_newstat - data8 compat_sys_newlstat - data8 compat_sys_newfstat - data8 sys_ni_syscall - data8 sys_ni_syscall /* iopl */ /* 110 */ - data8 sys_vhangup - data8 sys_ni_syscall /* used to be sys_idle */ - data8 sys_ni_syscall - data8 compat_sys_wait4 - data8 sys_swapoff /* 115 */ - data8 compat_sys_sysinfo - data8 sys32_ipc - data8 sys_fsync - data8 sys32_sigreturn - data8 ia32_clone /* 120 */ - data8 sys_setdomainname - data8 sys32_newuname - data8 sys32_modify_ldt - data8 compat_sys_adjtimex - data8 sys32_mprotect /* 125 */ - data8 compat_sys_sigprocmask - data8 sys_ni_syscall /* create_module */ - data8 sys_ni_syscall /* init_module */ - data8 sys_ni_syscall /* delete_module */ - data8 sys_ni_syscall /* get_kernel_syms */ /* 130 */ - data8 sys32_quotactl - data8 sys_getpgid - data8 sys_fchdir - data8 sys_ni_syscall /* sys_bdflush */ - data8 sys_sysfs /* 135 */ - data8 sys32_personality - data8 sys_ni_syscall /* for afs_syscall */ - data8 sys_setfsuid /* 16-bit version */ - data8 sys_setfsgid /* 16-bit version */ - data8 sys_llseek /* 140 */ - data8 compat_sys_getdents - data8 compat_sys_select - data8 sys_flock - data8 sys32_msync - data8 compat_sys_readv /* 145 */ - data8 compat_sys_writev - data8 sys_getsid - data8 sys_fdatasync - data8 compat_sys_sysctl - data8 sys_mlock /* 150 */ - data8 sys_munlock - data8 sys_mlockall - data8 sys_munlockall - data8 sys_sched_setparam - data8 sys_sched_getparam /* 155 */ - data8 sys_sched_setscheduler - data8 sys_sched_getscheduler - data8 sys_sched_yield - data8 sys_sched_get_priority_max - data8 sys_sched_get_priority_min /* 160 */ - data8 sys32_sched_rr_get_interval - data8 compat_sys_nanosleep - data8 sys32_mremap - data8 sys_setresuid /* 16-bit version */ - data8 sys32_getresuid16 /* 16-bit version */ /* 165 */ - data8 sys_ni_syscall /* vm86 */ - data8 sys_ni_syscall /* sys_query_module */ - data8 sys_poll - data8 sys_ni_syscall /* nfsservctl */ - data8 sys_setresgid /* 170 */ - data8 sys32_getresgid16 - data8 sys_prctl - data8 sys32_rt_sigreturn - data8 sys32_rt_sigaction - data8 sys32_rt_sigprocmask /* 175 */ - data8 sys_rt_sigpending - data8 compat_sys_rt_sigtimedwait - data8 sys32_rt_sigqueueinfo - data8 compat_sys_rt_sigsuspend - data8 sys32_pread /* 180 */ - data8 sys32_pwrite - data8 sys_chown /* 16-bit version */ - data8 sys_getcwd - data8 sys_capget - data8 sys_capset /* 185 */ - data8 sys32_sigaltstack - data8 sys32_sendfile - data8 sys_ni_syscall /* streams1 */ - data8 sys_ni_syscall /* streams2 */ - data8 sys32_vfork /* 190 */ - data8 compat_sys_getrlimit - data8 sys32_mmap2 - data8 sys32_truncate64 - data8 sys32_ftruncate64 - data8 sys32_stat64 /* 195 */ - data8 sys32_lstat64 - data8 sys32_fstat64 - data8 sys_lchown - data8 sys_getuid - data8 sys_getgid /* 200 */ - data8 sys_geteuid - data8 sys_getegid - data8 sys_setreuid - data8 sys_setregid - data8 sys_getgroups /* 205 */ - data8 sys_setgroups - data8 sys_fchown - data8 sys_setresuid - data8 sys_getresuid - data8 sys_setresgid /* 210 */ - data8 sys_getresgid - data8 sys_chown - data8 sys_setuid - data8 sys_setgid - data8 sys_setfsuid /* 215 */ - data8 sys_setfsgid - data8 sys_pivot_root - data8 sys_mincore - data8 sys_madvise - data8 compat_sys_getdents64 /* 220 */ - data8 compat_sys_fcntl64 - data8 sys_ni_syscall /* reserved for TUX */ - data8 sys_ni_syscall /* reserved for Security */ - data8 sys_gettid - data8 sys_readahead /* 225 */ - data8 sys_setxattr - data8 sys_lsetxattr - data8 sys_fsetxattr - data8 sys_getxattr - data8 sys_lgetxattr /* 230 */ - data8 sys_fgetxattr - data8 sys_listxattr - data8 sys_llistxattr - data8 sys_flistxattr - data8 sys_removexattr /* 235 */ - data8 sys_lremovexattr - data8 sys_fremovexattr - data8 sys_tkill - data8 sys_sendfile64 - data8 compat_sys_futex /* 240 */ - data8 compat_sys_sched_setaffinity - data8 compat_sys_sched_getaffinity - data8 sys32_set_thread_area - data8 sys32_get_thread_area - data8 compat_sys_io_setup /* 245 */ - data8 sys_io_destroy - data8 compat_sys_io_getevents - data8 compat_sys_io_submit - data8 sys_io_cancel - data8 sys_fadvise64 /* 250 */ - data8 sys_ni_syscall - data8 sys_exit_group - data8 sys_lookup_dcookie - data8 sys_epoll_create - data8 sys32_epoll_ctl /* 255 */ - data8 sys32_epoll_wait - data8 sys_remap_file_pages - data8 sys_set_tid_address - data8 compat_sys_timer_create - data8 compat_sys_timer_settime /* 260 */ - data8 compat_sys_timer_gettime - data8 sys_timer_getoverrun - data8 sys_timer_delete - data8 compat_sys_clock_settime - data8 compat_sys_clock_gettime /* 265 */ - data8 compat_sys_clock_getres - data8 compat_sys_clock_nanosleep - data8 compat_sys_statfs64 - data8 compat_sys_fstatfs64 - data8 sys_tgkill /* 270 */ - data8 compat_sys_utimes - data8 sys32_fadvise64_64 - data8 sys_ni_syscall - data8 sys_ni_syscall - data8 sys_ni_syscall /* 275 */ - data8 sys_ni_syscall - data8 compat_sys_mq_open - data8 sys_mq_unlink - data8 compat_sys_mq_timedsend - data8 compat_sys_mq_timedreceive /* 280 */ - data8 compat_sys_mq_notify - data8 compat_sys_mq_getsetattr - data8 sys_ni_syscall /* reserved for kexec */ - data8 compat_sys_waitid - - // guard against failures to increase IA32_NR_syscalls - .org ia32_syscall_table + 8*IA32_NR_syscalls diff --git a/arch/ia64/ia32/ia32_ldt.c b/arch/ia64/ia32/ia32_ldt.c deleted file mode 100644 index 16d51c146849..000000000000 --- a/arch/ia64/ia32/ia32_ldt.c +++ /dev/null @@ -1,146 +0,0 @@ -/* - * Copyright (C) 2001, 2004 Hewlett-Packard Co - * David Mosberger-Tang - * - * Adapted from arch/i386/kernel/ldt.c - */ - -#include -#include -#include -#include -#include -#include - -#include - -#include "ia32priv.h" - -/* - * read_ldt() is not really atomic - this is not a problem since synchronization of reads - * and writes done to the LDT has to be assured by user-space anyway. Writes are atomic, - * to protect the security checks done on new descriptors. - */ -static int -read_ldt (void __user *ptr, unsigned long bytecount) -{ - unsigned long bytes_left, n; - char __user *src, *dst; - char buf[256]; /* temporary buffer (don't overflow kernel stack!) */ - - if (bytecount > IA32_LDT_ENTRIES*IA32_LDT_ENTRY_SIZE) - bytecount = IA32_LDT_ENTRIES*IA32_LDT_ENTRY_SIZE; - - bytes_left = bytecount; - - src = (void __user *) IA32_LDT_OFFSET; - dst = ptr; - - while (bytes_left) { - n = sizeof(buf); - if (n > bytes_left) - n = bytes_left; - - /* - * We know we're reading valid memory, but we still must guard against - * running out of memory. - */ - if (__copy_from_user(buf, src, n)) - return -EFAULT; - - if (copy_to_user(dst, buf, n)) - return -EFAULT; - - src += n; - dst += n; - bytes_left -= n; - } - return bytecount; -} - -static int -read_default_ldt (void __user * ptr, unsigned long bytecount) -{ - unsigned long size; - int err; - - /* XXX fix me: should return equivalent of default_ldt[0] */ - err = 0; - size = 8; - if (size > bytecount) - size = bytecount; - - err = size; - if (clear_user(ptr, size)) - err = -EFAULT; - - return err; -} - -static int -write_ldt (void __user * ptr, unsigned long bytecount, int oldmode) -{ - struct ia32_user_desc ldt_info; - __u64 entry; - int ret; - - if (bytecount != sizeof(ldt_info)) - return -EINVAL; - if (copy_from_user(&ldt_info, ptr, sizeof(ldt_info))) - return -EFAULT; - - if (ldt_info.entry_number >= IA32_LDT_ENTRIES) - return -EINVAL; - if (ldt_info.contents == 3) { - if (oldmode) - return -EINVAL; - if (ldt_info.seg_not_present == 0) - return -EINVAL; - } - - if (ldt_info.base_addr == 0 && ldt_info.limit == 0 - && (oldmode || (ldt_info.contents == 0 && ldt_info.read_exec_only == 1 - && ldt_info.seg_32bit == 0 && ldt_info.limit_in_pages == 0 - && ldt_info.seg_not_present == 1 && ldt_info.useable == 0))) - /* allow LDTs to be cleared by the user */ - entry = 0; - else - /* we must set the "Accessed" bit as IVE doesn't emulate it */ - entry = IA32_SEG_DESCRIPTOR(ldt_info.base_addr, ldt_info.limit, - (((ldt_info.read_exec_only ^ 1) << 1) - | (ldt_info.contents << 2)) | 1, - 1, 3, ldt_info.seg_not_present ^ 1, - (oldmode ? 0 : ldt_info.useable), - ldt_info.seg_32bit, - ldt_info.limit_in_pages); - /* - * Install the new entry. We know we're accessing valid (mapped) user-level - * memory, but we still need to guard against out-of-memory, hence we must use - * put_user(). - */ - ret = __put_user(entry, (__u64 __user *) IA32_LDT_OFFSET + ldt_info.entry_number); - ia32_load_segment_descriptors(current); - return ret; -} - -asmlinkage int -sys32_modify_ldt (int func, unsigned int ptr, unsigned int bytecount) -{ - int ret = -ENOSYS; - - switch (func) { - case 0: - ret = read_ldt(compat_ptr(ptr), bytecount); - break; - case 1: - ret = write_ldt(compat_ptr(ptr), bytecount, 1); - break; - case 2: - ret = read_default_ldt(compat_ptr(ptr), bytecount); - break; - case 0x11: - ret = write_ldt(compat_ptr(ptr), bytecount, 0); - break; - } - return ret; -} diff --git a/arch/ia64/ia32/ia32_signal.c b/arch/ia64/ia32/ia32_signal.c deleted file mode 100644 index b763ca19ef17..000000000000 --- a/arch/ia64/ia32/ia32_signal.c +++ /dev/null @@ -1,1010 +0,0 @@ -/* - * IA32 Architecture-specific signal handling support. - * - * Copyright (C) 1999, 2001-2002, 2005 Hewlett-Packard Co - * David Mosberger-Tang - * Copyright (C) 1999 Arun Sharma - * Copyright (C) 2000 VA Linux Co - * Copyright (C) 2000 Don Dugger - * - * Derived from i386 and Alpha versions. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include "ia32priv.h" - -#include "../kernel/sigframe.h" - -#define A(__x) ((unsigned long)(__x)) - -#define DEBUG_SIG 0 -#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) - -#define __IA32_NR_sigreturn 119 -#define __IA32_NR_rt_sigreturn 173 - -struct sigframe_ia32 -{ - int pretcode; - int sig; - struct sigcontext_ia32 sc; - struct _fpstate_ia32 fpstate; - unsigned int extramask[_COMPAT_NSIG_WORDS-1]; - char retcode[8]; -}; - -struct rt_sigframe_ia32 -{ - int pretcode; - int sig; - int pinfo; - int puc; - compat_siginfo_t info; - struct ucontext_ia32 uc; - struct _fpstate_ia32 fpstate; - char retcode[8]; -}; - -int -copy_siginfo_from_user32 (siginfo_t *to, compat_siginfo_t __user *from) -{ - unsigned long tmp; - int err; - - if (!access_ok(VERIFY_READ, from, sizeof(compat_siginfo_t))) - return -EFAULT; - - err = __get_user(to->si_signo, &from->si_signo); - err |= __get_user(to->si_errno, &from->si_errno); - err |= __get_user(to->si_code, &from->si_code); - - if (to->si_code < 0) - err |= __copy_from_user(&to->_sifields._pad, &from->_sifields._pad, SI_PAD_SIZE); - else { - switch (to->si_code >> 16) { - case __SI_CHLD >> 16: - err |= __get_user(to->si_utime, &from->si_utime); - err |= __get_user(to->si_stime, &from->si_stime); - err |= __get_user(to->si_status, &from->si_status); - default: - err |= __get_user(to->si_pid, &from->si_pid); - err |= __get_user(to->si_uid, &from->si_uid); - break; - case __SI_FAULT >> 16: - err |= __get_user(tmp, &from->si_addr); - to->si_addr = (void __user *) tmp; - break; - case __SI_POLL >> 16: - err |= __get_user(to->si_band, &from->si_band); - err |= __get_user(to->si_fd, &from->si_fd); - break; - case __SI_RT >> 16: /* This is not generated by the kernel as of now. */ - case __SI_MESGQ >> 16: - err |= __get_user(to->si_pid, &from->si_pid); - err |= __get_user(to->si_uid, &from->si_uid); - err |= __get_user(to->si_int, &from->si_int); - break; - } - } - return err; -} - -int -copy_siginfo_to_user32 (compat_siginfo_t __user *to, siginfo_t *from) -{ - unsigned int addr; - int err; - - if (!access_ok(VERIFY_WRITE, to, sizeof(compat_siginfo_t))) - return -EFAULT; - - /* If you change siginfo_t structure, please be sure - this code is fixed accordingly. - It should never copy any pad contained in the structure - to avoid security leaks, but must copy the generic - 3 ints plus the relevant union member. - This routine must convert siginfo from 64bit to 32bit as well - at the same time. */ - err = __put_user(from->si_signo, &to->si_signo); - err |= __put_user(from->si_errno, &to->si_errno); - err |= __put_user((short)from->si_code, &to->si_code); - if (from->si_code < 0) - err |= __copy_to_user(&to->_sifields._pad, &from->_sifields._pad, SI_PAD_SIZE); - else { - switch (from->si_code >> 16) { - case __SI_CHLD >> 16: - err |= __put_user(from->si_utime, &to->si_utime); - err |= __put_user(from->si_stime, &to->si_stime); - err |= __put_user(from->si_status, &to->si_status); - default: - err |= __put_user(from->si_pid, &to->si_pid); - err |= __put_user(from->si_uid, &to->si_uid); - break; - case __SI_FAULT >> 16: - /* avoid type-checking warnings by copying _pad[0] in lieu of si_addr... */ - err |= __put_user(from->_sifields._pad[0], &to->si_addr); - break; - case __SI_POLL >> 16: - err |= __put_user(from->si_band, &to->si_band); - err |= __put_user(from->si_fd, &to->si_fd); - break; - case __SI_TIMER >> 16: - err |= __put_user(from->si_tid, &to->si_tid); - err |= __put_user(from->si_overrun, &to->si_overrun); - addr = (unsigned long) from->si_ptr; - err |= __put_user(addr, &to->si_ptr); - break; - case __SI_RT >> 16: /* Not generated by the kernel as of now. */ - case __SI_MESGQ >> 16: - err |= __put_user(from->si_uid, &to->si_uid); - err |= __put_user(from->si_pid, &to->si_pid); - addr = (unsigned long) from->si_ptr; - err |= __put_user(addr, &to->si_ptr); - break; - } - } - return err; -} - - -/* - * SAVE and RESTORE of ia32 fpstate info, from ia64 current state - * Used in exception handler to pass the fpstate to the user, and restore - * the fpstate while returning from the exception handler. - * - * fpstate info and their mapping to IA64 regs: - * fpstate REG(BITS) Attribute Comments - * cw ar.fcr(0:12) with bits 7 and 6 not used - * sw ar.fsr(0:15) - * tag ar.fsr(16:31) with odd numbered bits not used - * (read returns 0, writes ignored) - * ipoff ar.fir(0:31) - * cssel ar.fir(32:47) - * dataoff ar.fdr(0:31) - * datasel ar.fdr(32:47) - * - * _st[(0+TOS)%8] f8 - * _st[(1+TOS)%8] f9 - * _st[(2+TOS)%8] f10 - * _st[(3+TOS)%8] f11 (f8..f11 from ptregs) - * : : : (f12..f15 from live reg) - * : : : - * _st[(7+TOS)%8] f15 TOS=sw.top(bits11:13) - * - * status Same as sw RO - * magic 0 as X86_FXSR_MAGIC in ia32 - * mxcsr Bits(7:15)=ar.fcr(39:47) - * Bits(0:5) =ar.fsr(32:37) with bit 6 reserved - * _xmm[0..7] f16..f31 (live registers) - * with _xmm[0] - * Bit(64:127)=f17(0:63) - * Bit(0:63)=f16(0:63) - * All other fields unused... - */ - -static int -save_ia32_fpstate_live (struct _fpstate_ia32 __user *save) -{ - struct task_struct *tsk = current; - struct pt_regs *ptp; - struct _fpreg_ia32 *fpregp; - char buf[32]; - unsigned long fsr, fcr, fir, fdr; - unsigned long new_fsr; - unsigned long num128[2]; - unsigned long mxcsr=0; - int fp_tos, fr8_st_map; - - if (!access_ok(VERIFY_WRITE, save, sizeof(*save))) - return -EFAULT; - - /* Read in fsr, fcr, fir, fdr and copy onto fpstate */ - fsr = ia64_getreg(_IA64_REG_AR_FSR); - fcr = ia64_getreg(_IA64_REG_AR_FCR); - fir = ia64_getreg(_IA64_REG_AR_FIR); - fdr = ia64_getreg(_IA64_REG_AR_FDR); - - /* - * We need to clear the exception state before calling the signal handler. Clear - * the bits 15, bits 0-7 in fp status word. Similar to the functionality of fnclex - * instruction. - */ - new_fsr = fsr & ~0x80ff; - ia64_setreg(_IA64_REG_AR_FSR, new_fsr); - - __put_user(fcr & 0xffff, &save->cw); - __put_user(fsr & 0xffff, &save->sw); - __put_user((fsr>>16) & 0xffff, &save->tag); - __put_user(fir, &save->ipoff); - __put_user((fir>>32) & 0xffff, &save->cssel); - __put_user(fdr, &save->dataoff); - __put_user((fdr>>32) & 0xffff, &save->datasel); - __put_user(fsr & 0xffff, &save->status); - - mxcsr = ((fcr>>32) & 0xff80) | ((fsr>>32) & 0x3f); - __put_user(mxcsr & 0xffff, &save->mxcsr); - __put_user( 0, &save->magic); //#define X86_FXSR_MAGIC 0x0000 - - /* - * save f8..f11 from pt_regs - * save f12..f15 from live register set - */ - /* - * Find the location where f8 has to go in fp reg stack. This depends on - * TOP(11:13) field of sw. Other f reg continue sequentially from where f8 maps - * to. - */ - fp_tos = (fsr>>11)&0x7; - fr8_st_map = (8-fp_tos)&0x7; - ptp = task_pt_regs(tsk); - fpregp = (struct _fpreg_ia32 *)(((unsigned long)buf + 15) & ~15); - ia64f2ia32f(fpregp, &ptp->f8); - copy_to_user(&save->_st[(0+fr8_st_map)&0x7], fpregp, sizeof(struct _fpreg_ia32)); - ia64f2ia32f(fpregp, &ptp->f9); - copy_to_user(&save->_st[(1+fr8_st_map)&0x7], fpregp, sizeof(struct _fpreg_ia32)); - ia64f2ia32f(fpregp, &ptp->f10); - copy_to_user(&save->_st[(2+fr8_st_map)&0x7], fpregp, sizeof(struct _fpreg_ia32)); - ia64f2ia32f(fpregp, &ptp->f11); - copy_to_user(&save->_st[(3+fr8_st_map)&0x7], fpregp, sizeof(struct _fpreg_ia32)); - - ia64_stfe(fpregp, 12); - copy_to_user(&save->_st[(4+fr8_st_map)&0x7], fpregp, sizeof(struct _fpreg_ia32)); - ia64_stfe(fpregp, 13); - copy_to_user(&save->_st[(5+fr8_st_map)&0x7], fpregp, sizeof(struct _fpreg_ia32)); - ia64_stfe(fpregp, 14); - copy_to_user(&save->_st[(6+fr8_st_map)&0x7], fpregp, sizeof(struct _fpreg_ia32)); - ia64_stfe(fpregp, 15); - copy_to_user(&save->_st[(7+fr8_st_map)&0x7], fpregp, sizeof(struct _fpreg_ia32)); - - ia64_stf8(&num128[0], 16); - ia64_stf8(&num128[1], 17); - copy_to_user(&save->_xmm[0], num128, sizeof(struct _xmmreg_ia32)); - - ia64_stf8(&num128[0], 18); - ia64_stf8(&num128[1], 19); - copy_to_user(&save->_xmm[1], num128, sizeof(struct _xmmreg_ia32)); - - ia64_stf8(&num128[0], 20); - ia64_stf8(&num128[1], 21); - copy_to_user(&save->_xmm[2], num128, sizeof(struct _xmmreg_ia32)); - - ia64_stf8(&num128[0], 22); - ia64_stf8(&num128[1], 23); - copy_to_user(&save->_xmm[3], num128, sizeof(struct _xmmreg_ia32)); - - ia64_stf8(&num128[0], 24); - ia64_stf8(&num128[1], 25); - copy_to_user(&save->_xmm[4], num128, sizeof(struct _xmmreg_ia32)); - - ia64_stf8(&num128[0], 26); - ia64_stf8(&num128[1], 27); - copy_to_user(&save->_xmm[5], num128, sizeof(struct _xmmreg_ia32)); - - ia64_stf8(&num128[0], 28); - ia64_stf8(&num128[1], 29); - copy_to_user(&save->_xmm[6], num128, sizeof(struct _xmmreg_ia32)); - - ia64_stf8(&num128[0], 30); - ia64_stf8(&num128[1], 31); - copy_to_user(&save->_xmm[7], num128, sizeof(struct _xmmreg_ia32)); - return 0; -} - -static int -restore_ia32_fpstate_live (struct _fpstate_ia32 __user *save) -{ - struct task_struct *tsk = current; - struct pt_regs *ptp; - unsigned int lo, hi; - unsigned long num128[2]; - unsigned long num64, mxcsr; - struct _fpreg_ia32 *fpregp; - char buf[32]; - unsigned long fsr, fcr, fir, fdr; - int fp_tos, fr8_st_map; - - if (!access_ok(VERIFY_READ, save, sizeof(*save))) - return(-EFAULT); - - /* - * Updating fsr, fcr, fir, fdr. - * Just a bit more complicated than save. - * - Need to make sure that we don't write any value other than the - * specific fpstate info - * - Need to make sure that the untouched part of frs, fdr, fir, fcr - * should remain same while writing. - * So, we do a read, change specific fields and write. - */ - fsr = ia64_getreg(_IA64_REG_AR_FSR); - fcr = ia64_getreg(_IA64_REG_AR_FCR); - fir = ia64_getreg(_IA64_REG_AR_FIR); - fdr = ia64_getreg(_IA64_REG_AR_FDR); - - __get_user(mxcsr, (unsigned int __user *)&save->mxcsr); - /* setting bits 0..5 8..12 with cw and 39..47 from mxcsr */ - __get_user(lo, (unsigned int __user *)&save->cw); - num64 = mxcsr & 0xff10; - num64 = (num64 << 32) | (lo & 0x1f3f); - fcr = (fcr & (~0xff1000001f3fUL)) | num64; - - /* setting bits 0..31 with sw and tag and 32..37 from mxcsr */ - __get_user(lo, (unsigned int __user *)&save->sw); - /* set bits 15,7 (fsw.b, fsw.es) to reflect the current error status */ - if ( !(lo & 0x7f) ) - lo &= (~0x8080); - __get_user(hi, (unsigned int __user *)&save->tag); - num64 = mxcsr & 0x3f; - num64 = (num64 << 16) | (hi & 0xffff); - num64 = (num64 << 16) | (lo & 0xffff); - fsr = (fsr & (~0x3fffffffffUL)) | num64; - - /* setting bits 0..47 with cssel and ipoff */ - __get_user(lo, (unsigned int __user *)&save->ipoff); - __get_user(hi, (unsigned int __user *)&save->cssel); - num64 = hi & 0xffff; - num64 = (num64 << 32) | lo; - fir = (fir & (~0xffffffffffffUL)) | num64; - - /* setting bits 0..47 with datasel and dataoff */ - __get_user(lo, (unsigned int __user *)&save->dataoff); - __get_user(hi, (unsigned int __user *)&save->datasel); - num64 = hi & 0xffff; - num64 = (num64 << 32) | lo; - fdr = (fdr & (~0xffffffffffffUL)) | num64; - - ia64_setreg(_IA64_REG_AR_FSR, fsr); - ia64_setreg(_IA64_REG_AR_FCR, fcr); - ia64_setreg(_IA64_REG_AR_FIR, fir); - ia64_setreg(_IA64_REG_AR_FDR, fdr); - - /* - * restore f8..f11 onto pt_regs - * restore f12..f15 onto live registers - */ - /* - * Find the location where f8 has to go in fp reg stack. This depends on - * TOP(11:13) field of sw. Other f reg continue sequentially from where f8 maps - * to. - */ - fp_tos = (fsr>>11)&0x7; - fr8_st_map = (8-fp_tos)&0x7; - fpregp = (struct _fpreg_ia32 *)(((unsigned long)buf + 15) & ~15); - - ptp = task_pt_regs(tsk); - copy_from_user(fpregp, &save->_st[(0+fr8_st_map)&0x7], sizeof(struct _fpreg_ia32)); - ia32f2ia64f(&ptp->f8, fpregp); - copy_from_user(fpregp, &save->_st[(1+fr8_st_map)&0x7], sizeof(struct _fpreg_ia32)); - ia32f2ia64f(&ptp->f9, fpregp); - copy_from_user(fpregp, &save->_st[(2+fr8_st_map)&0x7], sizeof(struct _fpreg_ia32)); - ia32f2ia64f(&ptp->f10, fpregp); - copy_from_user(fpregp, &save->_st[(3+fr8_st_map)&0x7], sizeof(struct _fpreg_ia32)); - ia32f2ia64f(&ptp->f11, fpregp); - - copy_from_user(fpregp, &save->_st[(4+fr8_st_map)&0x7], sizeof(struct _fpreg_ia32)); - ia64_ldfe(12, fpregp); - copy_from_user(fpregp, &save->_st[(5+fr8_st_map)&0x7], sizeof(struct _fpreg_ia32)); - ia64_ldfe(13, fpregp); - copy_from_user(fpregp, &save->_st[(6+fr8_st_map)&0x7], sizeof(struct _fpreg_ia32)); - ia64_ldfe(14, fpregp); - copy_from_user(fpregp, &save->_st[(7+fr8_st_map)&0x7], sizeof(struct _fpreg_ia32)); - ia64_ldfe(15, fpregp); - - copy_from_user(num128, &save->_xmm[0], sizeof(struct _xmmreg_ia32)); - ia64_ldf8(16, &num128[0]); - ia64_ldf8(17, &num128[1]); - - copy_from_user(num128, &save->_xmm[1], sizeof(struct _xmmreg_ia32)); - ia64_ldf8(18, &num128[0]); - ia64_ldf8(19, &num128[1]); - - copy_from_user(num128, &save->_xmm[2], sizeof(struct _xmmreg_ia32)); - ia64_ldf8(20, &num128[0]); - ia64_ldf8(21, &num128[1]); - - copy_from_user(num128, &save->_xmm[3], sizeof(struct _xmmreg_ia32)); - ia64_ldf8(22, &num128[0]); - ia64_ldf8(23, &num128[1]); - - copy_from_user(num128, &save->_xmm[4], sizeof(struct _xmmreg_ia32)); - ia64_ldf8(24, &num128[0]); - ia64_ldf8(25, &num128[1]); - - copy_from_user(num128, &save->_xmm[5], sizeof(struct _xmmreg_ia32)); - ia64_ldf8(26, &num128[0]); - ia64_ldf8(27, &num128[1]); - - copy_from_user(num128, &save->_xmm[6], sizeof(struct _xmmreg_ia32)); - ia64_ldf8(28, &num128[0]); - ia64_ldf8(29, &num128[1]); - - copy_from_user(num128, &save->_xmm[7], sizeof(struct _xmmreg_ia32)); - ia64_ldf8(30, &num128[0]); - ia64_ldf8(31, &num128[1]); - return 0; -} - -static inline void -sigact_set_handler (struct k_sigaction *sa, unsigned int handler, unsigned int restorer) -{ - if (handler + 1 <= 2) - /* SIG_DFL, SIG_IGN, or SIG_ERR: must sign-extend to 64-bits */ - sa->sa.sa_handler = (__sighandler_t) A((int) handler); - else - sa->sa.sa_handler = (__sighandler_t) (((unsigned long) restorer << 32) | handler); -} - -asmlinkage long -sys32_sigsuspend (int history0, int history1, old_sigset_t mask) -{ - mask &= _BLOCKABLE; - spin_lock_irq(¤t->sighand->siglock); - current->saved_sigmask = current->blocked; - siginitset(¤t->blocked, mask); - recalc_sigpending(); - spin_unlock_irq(¤t->sighand->siglock); - - current->state = TASK_INTERRUPTIBLE; - schedule(); - set_restore_sigmask(); - return -ERESTARTNOHAND; -} - -asmlinkage long -sys32_signal (int sig, unsigned int handler) -{ - struct k_sigaction new_sa, old_sa; - int ret; - - sigact_set_handler(&new_sa, handler, 0); - new_sa.sa.sa_flags = SA_ONESHOT | SA_NOMASK; - sigemptyset(&new_sa.sa.sa_mask); - - ret = do_sigaction(sig, &new_sa, &old_sa); - - return ret ? ret : IA32_SA_HANDLER(&old_sa); -} - -asmlinkage long -sys32_rt_sigaction (int sig, struct sigaction32 __user *act, - struct sigaction32 __user *oact, unsigned int sigsetsize) -{ - struct k_sigaction new_ka, old_ka; - unsigned int handler, restorer; - int ret; - - /* XXX: Don't preclude handling different sized sigset_t's. */ - if (sigsetsize != sizeof(compat_sigset_t)) - return -EINVAL; - - if (act) { - ret = get_user(handler, &act->sa_handler); - ret |= get_user(new_ka.sa.sa_flags, &act->sa_flags); - ret |= get_user(restorer, &act->sa_restorer); - ret |= copy_from_user(&new_ka.sa.sa_mask, &act->sa_mask, sizeof(compat_sigset_t)); - if (ret) - return -EFAULT; - - sigact_set_handler(&new_ka, handler, restorer); - } - - ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL); - - if (!ret && oact) { - ret = put_user(IA32_SA_HANDLER(&old_ka), &oact->sa_handler); - ret |= put_user(old_ka.sa.sa_flags, &oact->sa_flags); - ret |= put_user(IA32_SA_RESTORER(&old_ka), &oact->sa_restorer); - ret |= copy_to_user(&oact->sa_mask, &old_ka.sa.sa_mask, sizeof(compat_sigset_t)); - } - return ret; -} - - -asmlinkage long -sys32_rt_sigprocmask (int how, compat_sigset_t __user *set, compat_sigset_t __user *oset, - unsigned int sigsetsize) -{ - mm_segment_t old_fs = get_fs(); - sigset_t s; - long ret; - - if (sigsetsize > sizeof(s)) - return -EINVAL; - - if (set) { - memset(&s, 0, sizeof(s)); - if (copy_from_user(&s.sig, set, sigsetsize)) - return -EFAULT; - } - set_fs(KERNEL_DS); - ret = sys_rt_sigprocmask(how, - set ? (sigset_t __user *) &s : NULL, - oset ? (sigset_t __user *) &s : NULL, sizeof(s)); - set_fs(old_fs); - if (ret) - return ret; - if (oset) { - if (copy_to_user(oset, &s.sig, sigsetsize)) - return -EFAULT; - } - return 0; -} - -asmlinkage long -sys32_rt_sigqueueinfo (int pid, int sig, compat_siginfo_t __user *uinfo) -{ - mm_segment_t old_fs = get_fs(); - siginfo_t info; - int ret; - - if (copy_siginfo_from_user32(&info, uinfo)) - return -EFAULT; - set_fs(KERNEL_DS); - ret = sys_rt_sigqueueinfo(pid, sig, (siginfo_t __user *) &info); - set_fs(old_fs); - return ret; -} - -asmlinkage long -sys32_sigaction (int sig, struct old_sigaction32 __user *act, struct old_sigaction32 __user *oact) -{ - struct k_sigaction new_ka, old_ka; - unsigned int handler, restorer; - int ret; - - if (act) { - compat_old_sigset_t mask; - - ret = get_user(handler, &act->sa_handler); - ret |= get_user(new_ka.sa.sa_flags, &act->sa_flags); - ret |= get_user(restorer, &act->sa_restorer); - ret |= get_user(mask, &act->sa_mask); - if (ret) - return ret; - - sigact_set_handler(&new_ka, handler, restorer); - siginitset(&new_ka.sa.sa_mask, mask); - } - - ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL); - - if (!ret && oact) { - ret = put_user(IA32_SA_HANDLER(&old_ka), &oact->sa_handler); - ret |= put_user(old_ka.sa.sa_flags, &oact->sa_flags); - ret |= put_user(IA32_SA_RESTORER(&old_ka), &oact->sa_restorer); - ret |= put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask); - } - - return ret; -} - -static int -setup_sigcontext_ia32 (struct sigcontext_ia32 __user *sc, struct _fpstate_ia32 __user *fpstate, - struct pt_regs *regs, unsigned long mask) -{ - int err = 0; - unsigned long flag; - - if (!access_ok(VERIFY_WRITE, sc, sizeof(*sc))) - return -EFAULT; - - err |= __put_user((regs->r16 >> 32) & 0xffff, (unsigned int __user *)&sc->fs); - err |= __put_user((regs->r16 >> 48) & 0xffff, (unsigned int __user *)&sc->gs); - err |= __put_user((regs->r16 >> 16) & 0xffff, (unsigned int __user *)&sc->es); - err |= __put_user(regs->r16 & 0xffff, (unsigned int __user *)&sc->ds); - err |= __put_user(regs->r15, &sc->edi); - err |= __put_user(regs->r14, &sc->esi); - err |= __put_user(regs->r13, &sc->ebp); - err |= __put_user(regs->r12, &sc->esp); - err |= __put_user(regs->r11, &sc->ebx); - err |= __put_user(regs->r10, &sc->edx); - err |= __put_user(regs->r9, &sc->ecx); - err |= __put_user(regs->r8, &sc->eax); -#if 0 - err |= __put_user(current->tss.trap_no, &sc->trapno); - err |= __put_user(current->tss.error_code, &sc->err); -#endif - err |= __put_user(regs->cr_iip, &sc->eip); - err |= __put_user(regs->r17 & 0xffff, (unsigned int __user *)&sc->cs); - /* - * `eflags' is in an ar register for this context - */ - flag = ia64_getreg(_IA64_REG_AR_EFLAG); - err |= __put_user((unsigned int)flag, &sc->eflags); - err |= __put_user(regs->r12, &sc->esp_at_signal); - err |= __put_user((regs->r17 >> 16) & 0xffff, (unsigned int __user *)&sc->ss); - - if ( save_ia32_fpstate_live(fpstate) < 0 ) - err = -EFAULT; - else - err |= __put_user((u32)(u64)fpstate, &sc->fpstate); - -#if 0 - tmp = save_i387(fpstate); - if (tmp < 0) - err = 1; - else - err |= __put_user(tmp ? fpstate : NULL, &sc->fpstate); - - /* non-iBCS2 extensions.. */ -#endif - err |= __put_user(mask, &sc->oldmask); -#if 0 - err |= __put_user(current->tss.cr2, &sc->cr2); -#endif - return err; -} - -static int -restore_sigcontext_ia32 (struct pt_regs *regs, struct sigcontext_ia32 __user *sc, int *peax) -{ - unsigned int err = 0; - - /* Always make any pending restarted system calls return -EINTR */ - current_thread_info()->restart_block.fn = do_no_restart_syscall; - - if (!access_ok(VERIFY_READ, sc, sizeof(*sc))) - return(-EFAULT); - -#define COPY(ia64x, ia32x) err |= __get_user(regs->ia64x, &sc->ia32x) - -#define copyseg_gs(tmp) (regs->r16 |= (unsigned long) (tmp) << 48) -#define copyseg_fs(tmp) (regs->r16 |= (unsigned long) (tmp) << 32) -#define copyseg_cs(tmp) (regs->r17 |= tmp) -#define copyseg_ss(tmp) (regs->r17 |= (unsigned long) (tmp) << 16) -#define copyseg_es(tmp) (regs->r16 |= (unsigned long) (tmp) << 16) -#define copyseg_ds(tmp) (regs->r16 |= tmp) - -#define COPY_SEG(seg) \ - { \ - unsigned short tmp; \ - err |= __get_user(tmp, &sc->seg); \ - copyseg_##seg(tmp); \ - } -#define COPY_SEG_STRICT(seg) \ - { \ - unsigned short tmp; \ - err |= __get_user(tmp, &sc->seg); \ - copyseg_##seg(tmp|3); \ - } - - /* To make COPY_SEGs easier, we zero r16, r17 */ - regs->r16 = 0; - regs->r17 = 0; - - COPY_SEG(gs); - COPY_SEG(fs); - COPY_SEG(es); - COPY_SEG(ds); - COPY(r15, edi); - COPY(r14, esi); - COPY(r13, ebp); - COPY(r12, esp); - COPY(r11, ebx); - COPY(r10, edx); - COPY(r9, ecx); - COPY(cr_iip, eip); - COPY_SEG_STRICT(cs); - COPY_SEG_STRICT(ss); - ia32_load_segment_descriptors(current); - { - unsigned int tmpflags; - unsigned long flag; - - /* - * IA32 `eflags' is not part of `pt_regs', it's in an ar register which - * is part of the thread context. Fortunately, we are executing in the - * IA32 process's context. - */ - err |= __get_user(tmpflags, &sc->eflags); - flag = ia64_getreg(_IA64_REG_AR_EFLAG); - flag &= ~0x40DD5; - flag |= (tmpflags & 0x40DD5); - ia64_setreg(_IA64_REG_AR_EFLAG, flag); - - regs->r1 = -1; /* disable syscall checks, r1 is orig_eax */ - } - - { - struct _fpstate_ia32 __user *buf = NULL; - u32 fpstate_ptr; - err |= get_user(fpstate_ptr, &(sc->fpstate)); - buf = compat_ptr(fpstate_ptr); - if (buf) { - err |= restore_ia32_fpstate_live(buf); - } - } - -#if 0 - { - struct _fpstate * buf; - err |= __get_user(buf, &sc->fpstate); - if (buf) { - if (!access_ok(VERIFY_READ, buf, sizeof(*buf))) - goto badframe; - err |= restore_i387(buf); - } - } -#endif - - err |= __get_user(*peax, &sc->eax); - return err; - -#if 0 - badframe: - return 1; -#endif -} - -/* - * Determine which stack to use.. - */ -static inline void __user * -get_sigframe (struct k_sigaction *ka, struct pt_regs * regs, size_t frame_size) -{ - unsigned long esp; - - /* Default to using normal stack (truncate off sign-extension of bit 31: */ - esp = (unsigned int) regs->r12; - - /* This is the X/Open sanctioned signal stack switching. */ - if (ka->sa.sa_flags & SA_ONSTACK) { - int onstack = sas_ss_flags(esp); - - if (onstack == 0) - esp = current->sas_ss_sp + current->sas_ss_size; - else if (onstack == SS_ONSTACK) { - /* - * If we are on the alternate signal stack and would - * overflow it, don't. Return an always-bogus address - * instead so we will die with SIGSEGV. - */ - if (!likely(on_sig_stack(esp - frame_size))) - return (void __user *) -1L; - } - } - /* Legacy stack switching not supported */ - - esp -= frame_size; - /* Align the stack pointer according to the i386 ABI, - * i.e. so that on function entry ((sp + 4) & 15) == 0. */ - esp = ((esp + 4) & -16ul) - 4; - return (void __user *) esp; -} - -static int -setup_frame_ia32 (int sig, struct k_sigaction *ka, sigset_t *set, struct pt_regs * regs) -{ - struct exec_domain *ed = current_thread_info()->exec_domain; - struct sigframe_ia32 __user *frame; - int err = 0; - - frame = get_sigframe(ka, regs, sizeof(*frame)); - - if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) - goto give_sigsegv; - - err |= __put_user((ed && ed->signal_invmap && sig < 32 - ? (int)(ed->signal_invmap[sig]) : sig), &frame->sig); - - err |= setup_sigcontext_ia32(&frame->sc, &frame->fpstate, regs, set->sig[0]); - - if (_COMPAT_NSIG_WORDS > 1) - err |= __copy_to_user(frame->extramask, (char *) &set->sig + 4, - sizeof(frame->extramask)); - - /* Set up to return from userspace. If provided, use a stub - already in userspace. */ - if (ka->sa.sa_flags & SA_RESTORER) { - unsigned int restorer = IA32_SA_RESTORER(ka); - err |= __put_user(restorer, &frame->pretcode); - } else { - /* Pointing to restorer in ia32 gate page */ - err |= __put_user(IA32_GATE_OFFSET, &frame->pretcode); - } - - /* This is popl %eax ; movl $,%eax ; int $0x80 - * and there for historical reasons only. - * See arch/i386/kernel/signal.c - */ - - err |= __put_user(0xb858, (short __user *)(frame->retcode+0)); - err |= __put_user(__IA32_NR_sigreturn, (int __user *)(frame->retcode+2)); - err |= __put_user(0x80cd, (short __user *)(frame->retcode+6)); - - if (err) - goto give_sigsegv; - - /* Set up registers for signal handler */ - regs->r12 = (unsigned long) frame; - regs->cr_iip = IA32_SA_HANDLER(ka); - - set_fs(USER_DS); - -#if 0 - regs->eflags &= ~TF_MASK; -#endif - -#if 0 - printk("SIG deliver (%s:%d): sig=%d sp=%p pc=%lx ra=%x\n", - current->comm, current->pid, sig, (void *) frame, regs->cr_iip, frame->pretcode); -#endif - - return 1; - - give_sigsegv: - force_sigsegv(sig, current); - return 0; -} - -static int -setup_rt_frame_ia32 (int sig, struct k_sigaction *ka, siginfo_t *info, - sigset_t *set, struct pt_regs * regs) -{ - struct exec_domain *ed = current_thread_info()->exec_domain; - compat_uptr_t pinfo, puc; - struct rt_sigframe_ia32 __user *frame; - int err = 0; - - frame = get_sigframe(ka, regs, sizeof(*frame)); - - if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) - goto give_sigsegv; - - err |= __put_user((ed && ed->signal_invmap - && sig < 32 ? ed->signal_invmap[sig] : sig), &frame->sig); - - pinfo = (long __user) &frame->info; - puc = (long __user) &frame->uc; - err |= __put_user(pinfo, &frame->pinfo); - err |= __put_user(puc, &frame->puc); - err |= copy_siginfo_to_user32(&frame->info, info); - - /* Create the ucontext. */ - err |= __put_user(0, &frame->uc.uc_flags); - err |= __put_user(0, &frame->uc.uc_link); - err |= __put_user(current->sas_ss_sp, &frame->uc.uc_stack.ss_sp); - err |= __put_user(sas_ss_flags(regs->r12), &frame->uc.uc_stack.ss_flags); - err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size); - err |= setup_sigcontext_ia32(&frame->uc.uc_mcontext, &frame->fpstate, regs, set->sig[0]); - err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set)); - if (err) - goto give_sigsegv; - - /* Set up to return from userspace. If provided, use a stub - already in userspace. */ - if (ka->sa.sa_flags & SA_RESTORER) { - unsigned int restorer = IA32_SA_RESTORER(ka); - err |= __put_user(restorer, &frame->pretcode); - } else { - /* Pointing to rt_restorer in ia32 gate page */ - err |= __put_user(IA32_GATE_OFFSET + 8, &frame->pretcode); - } - - /* This is movl $,%eax ; int $0x80 - * and there for historical reasons only. - * See arch/i386/kernel/signal.c - */ - - err |= __put_user(0xb8, (char __user *)(frame->retcode+0)); - err |= __put_user(__IA32_NR_rt_sigreturn, (int __user *)(frame->retcode+1)); - err |= __put_user(0x80cd, (short __user *)(frame->retcode+5)); - - if (err) - goto give_sigsegv; - - /* Set up registers for signal handler */ - regs->r12 = (unsigned long) frame; - regs->cr_iip = IA32_SA_HANDLER(ka); - - set_fs(USER_DS); - -#if 0 - regs->eflags &= ~TF_MASK; -#endif - -#if 0 - printk("SIG deliver (%s:%d): sp=%p pc=%lx ra=%x\n", - current->comm, current->pid, (void *) frame, regs->cr_iip, frame->pretcode); -#endif - - return 1; - -give_sigsegv: - force_sigsegv(sig, current); - return 0; -} - -int -ia32_setup_frame1 (int sig, struct k_sigaction *ka, siginfo_t *info, - sigset_t *set, struct pt_regs *regs) -{ - /* Set up the stack frame */ - if (ka->sa.sa_flags & SA_SIGINFO) - return setup_rt_frame_ia32(sig, ka, info, set, regs); - else - return setup_frame_ia32(sig, ka, set, regs); -} - -asmlinkage long -sys32_sigreturn (int arg0, int arg1, int arg2, int arg3, int arg4, int arg5, - int arg6, int arg7, struct pt_regs regs) -{ - unsigned long esp = (unsigned int) regs.r12; - struct sigframe_ia32 __user *frame = (struct sigframe_ia32 __user *)(esp - 8); - sigset_t set; - int eax; - - if (!access_ok(VERIFY_READ, frame, sizeof(*frame))) - goto badframe; - - if (__get_user(set.sig[0], &frame->sc.oldmask) - || (_COMPAT_NSIG_WORDS > 1 && __copy_from_user((char *) &set.sig + 4, &frame->extramask, - sizeof(frame->extramask)))) - goto badframe; - - sigdelsetmask(&set, ~_BLOCKABLE); - spin_lock_irq(¤t->sighand->siglock); - current->blocked = set; - recalc_sigpending(); - spin_unlock_irq(¤t->sighand->siglock); - - if (restore_sigcontext_ia32(®s, &frame->sc, &eax)) - goto badframe; - return eax; - - badframe: - force_sig(SIGSEGV, current); - return 0; -} - -asmlinkage long -sys32_rt_sigreturn (int arg0, int arg1, int arg2, int arg3, int arg4, - int arg5, int arg6, int arg7, struct pt_regs regs) -{ - unsigned long esp = (unsigned int) regs.r12; - struct rt_sigframe_ia32 __user *frame = (struct rt_sigframe_ia32 __user *)(esp - 4); - sigset_t set; - int eax; - - if (!access_ok(VERIFY_READ, frame, sizeof(*frame))) - goto badframe; - if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set))) - goto badframe; - - sigdelsetmask(&set, ~_BLOCKABLE); - spin_lock_irq(¤t->sighand->siglock); - current->blocked = set; - recalc_sigpending(); - spin_unlock_irq(¤t->sighand->siglock); - - if (restore_sigcontext_ia32(®s, &frame->uc.uc_mcontext, &eax)) - goto badframe; - - /* It is more difficult to avoid calling this function than to - call it and ignore errors. */ - do_sigaltstack((stack_t __user *) &frame->uc.uc_stack, NULL, esp); - - return eax; - - badframe: - force_sig(SIGSEGV, current); - return 0; -} diff --git a/arch/ia64/ia32/ia32_support.c b/arch/ia64/ia32/ia32_support.c deleted file mode 100644 index a6965ddafc46..000000000000 --- a/arch/ia64/ia32/ia32_support.c +++ /dev/null @@ -1,253 +0,0 @@ -/* - * IA32 helper functions - * - * Copyright (C) 1999 Arun Sharma - * Copyright (C) 2000 Asit K. Mallick - * Copyright (C) 2001-2002 Hewlett-Packard Co - * David Mosberger-Tang - * - * 06/16/00 A. Mallick added csd/ssd/tssd for ia32 thread context - * 02/19/01 D. Mosberger dropped tssd; it's not needed - * 09/14/01 D. Mosberger fixed memory management for gdt/tss page - * 09/29/01 D. Mosberger added ia32_load_segment_descriptors() - */ - -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#include "ia32priv.h" - -extern int die_if_kernel (char *str, struct pt_regs *regs, long err); - -struct page *ia32_shared_page[NR_CPUS]; -unsigned long *ia32_boot_gdt; -unsigned long *cpu_gdt_table[NR_CPUS]; -struct page *ia32_gate_page; - -static unsigned long -load_desc (u16 selector) -{ - unsigned long *table, limit, index; - - if (!selector) - return 0; - if (selector & IA32_SEGSEL_TI) { - table = (unsigned long *) IA32_LDT_OFFSET; - limit = IA32_LDT_ENTRIES; - } else { - table = cpu_gdt_table[smp_processor_id()]; - limit = IA32_PAGE_SIZE / sizeof(ia32_boot_gdt[0]); - } - index = selector >> IA32_SEGSEL_INDEX_SHIFT; - if (index >= limit) - return 0; - return IA32_SEG_UNSCRAMBLE(table[index]); -} - -void -ia32_load_segment_descriptors (struct task_struct *task) -{ - struct pt_regs *regs = task_pt_regs(task); - - /* Setup the segment descriptors */ - regs->r24 = load_desc(regs->r16 >> 16); /* ESD */ - regs->r27 = load_desc(regs->r16 >> 0); /* DSD */ - regs->r28 = load_desc(regs->r16 >> 32); /* FSD */ - regs->r29 = load_desc(regs->r16 >> 48); /* GSD */ - regs->ar_csd = load_desc(regs->r17 >> 0); /* CSD */ - regs->ar_ssd = load_desc(regs->r17 >> 16); /* SSD */ -} - -int -ia32_clone_tls (struct task_struct *child, struct pt_regs *childregs) -{ - struct desc_struct *desc; - struct ia32_user_desc info; - int idx; - - if (copy_from_user(&info, (void __user *)(childregs->r14 & 0xffffffff), sizeof(info))) - return -EFAULT; - if (LDT_empty(&info)) - return -EINVAL; - - idx = info.entry_number; - if (idx < GDT_ENTRY_TLS_MIN || idx > GDT_ENTRY_TLS_MAX) - return -EINVAL; - - desc = child->thread.tls_array + idx - GDT_ENTRY_TLS_MIN; - desc->a = LDT_entry_a(&info); - desc->b = LDT_entry_b(&info); - - /* XXX: can this be done in a cleaner way ? */ - load_TLS(&child->thread, smp_processor_id()); - ia32_load_segment_descriptors(child); - load_TLS(¤t->thread, smp_processor_id()); - - return 0; -} - -void -ia32_save_state (struct task_struct *t) -{ - t->thread.eflag = ia64_getreg(_IA64_REG_AR_EFLAG); - t->thread.fsr = ia64_getreg(_IA64_REG_AR_FSR); - t->thread.fcr = ia64_getreg(_IA64_REG_AR_FCR); - t->thread.fir = ia64_getreg(_IA64_REG_AR_FIR); - t->thread.fdr = ia64_getreg(_IA64_REG_AR_FDR); - ia64_set_kr(IA64_KR_IO_BASE, t->thread.old_iob); - ia64_set_kr(IA64_KR_TSSD, t->thread.old_k1); -} - -void -ia32_load_state (struct task_struct *t) -{ - unsigned long eflag, fsr, fcr, fir, fdr, tssd; - struct pt_regs *regs = task_pt_regs(t); - - eflag = t->thread.eflag; - fsr = t->thread.fsr; - fcr = t->thread.fcr; - fir = t->thread.fir; - fdr = t->thread.fdr; - tssd = load_desc(_TSS); /* TSSD */ - - ia64_setreg(_IA64_REG_AR_EFLAG, eflag); - ia64_setreg(_IA64_REG_AR_FSR, fsr); - ia64_setreg(_IA64_REG_AR_FCR, fcr); - ia64_setreg(_IA64_REG_AR_FIR, fir); - ia64_setreg(_IA64_REG_AR_FDR, fdr); - current->thread.old_iob = ia64_get_kr(IA64_KR_IO_BASE); - current->thread.old_k1 = ia64_get_kr(IA64_KR_TSSD); - ia64_set_kr(IA64_KR_IO_BASE, IA32_IOBASE); - ia64_set_kr(IA64_KR_TSSD, tssd); - - regs->r17 = (_TSS << 48) | (_LDT << 32) | (__u32) regs->r17; - regs->r30 = load_desc(_LDT); /* LDTD */ - load_TLS(&t->thread, smp_processor_id()); -} - -/* - * Setup IA32 GDT and TSS - */ -void -ia32_gdt_init (void) -{ - int cpu = smp_processor_id(); - - ia32_shared_page[cpu] = alloc_page(GFP_KERNEL); - if (!ia32_shared_page[cpu]) - panic("failed to allocate ia32_shared_page[%d]\n", cpu); - - cpu_gdt_table[cpu] = page_address(ia32_shared_page[cpu]); - - /* Copy from the boot cpu's GDT */ - memcpy(cpu_gdt_table[cpu], ia32_boot_gdt, PAGE_SIZE); -} - - -/* - * Setup IA32 GDT and TSS - */ -static void -ia32_boot_gdt_init (void) -{ - unsigned long ldt_size; - - ia32_shared_page[0] = alloc_page(GFP_KERNEL); - if (!ia32_shared_page[0]) - panic("failed to allocate ia32_shared_page[0]\n"); - - ia32_boot_gdt = page_address(ia32_shared_page[0]); - cpu_gdt_table[0] = ia32_boot_gdt; - - /* CS descriptor in IA-32 (scrambled) format */ - ia32_boot_gdt[__USER_CS >> 3] - = IA32_SEG_DESCRIPTOR(0, (IA32_GATE_END-1) >> IA32_PAGE_SHIFT, - 0xb, 1, 3, 1, 1, 1, 1); - - /* DS descriptor in IA-32 (scrambled) format */ - ia32_boot_gdt[__USER_DS >> 3] - = IA32_SEG_DESCRIPTOR(0, (IA32_GATE_END-1) >> IA32_PAGE_SHIFT, - 0x3, 1, 3, 1, 1, 1, 1); - - ldt_size = PAGE_ALIGN(IA32_LDT_ENTRIES*IA32_LDT_ENTRY_SIZE); - ia32_boot_gdt[TSS_ENTRY] = IA32_SEG_DESCRIPTOR(IA32_TSS_OFFSET, 235, - 0xb, 0, 3, 1, 1, 1, 0); - ia32_boot_gdt[LDT_ENTRY] = IA32_SEG_DESCRIPTOR(IA32_LDT_OFFSET, ldt_size - 1, - 0x2, 0, 3, 1, 1, 1, 0); -} - -static void -ia32_gate_page_init(void) -{ - unsigned long *sr; - - ia32_gate_page = alloc_page(GFP_KERNEL); - sr = page_address(ia32_gate_page); - /* This is popl %eax ; movl $,%eax ; int $0x80 */ - *sr++ = 0xb858 | (__IA32_NR_sigreturn << 16) | (0x80cdUL << 48); - - /* This is movl $,%eax ; int $0x80 */ - *sr = 0xb8 | (__IA32_NR_rt_sigreturn << 8) | (0x80cdUL << 40); -} - -void -ia32_mem_init(void) -{ - ia32_boot_gdt_init(); - ia32_gate_page_init(); -} - -/* - * Handle bad IA32 interrupt via syscall - */ -void -ia32_bad_interrupt (unsigned long int_num, struct pt_regs *regs) -{ - siginfo_t siginfo; - - if (die_if_kernel("Bad IA-32 interrupt", regs, int_num)) - return; - - siginfo.si_signo = SIGTRAP; - siginfo.si_errno = int_num; /* XXX is it OK to abuse si_errno like this? */ - siginfo.si_flags = 0; - siginfo.si_isr = 0; - siginfo.si_addr = NULL; - siginfo.si_imm = 0; - siginfo.si_code = TRAP_BRKPT; - force_sig_info(SIGTRAP, &siginfo, current); -} - -void -ia32_cpu_init (void) -{ - /* initialize global ia32 state - CR0 and CR4 */ - ia64_setreg(_IA64_REG_AR_CFLAG, (((ulong) IA32_CR4 << 32) | IA32_CR0)); -} - -static int __init -ia32_init (void) -{ -#if PAGE_SHIFT > IA32_PAGE_SHIFT - { - extern struct kmem_cache *ia64_partial_page_cachep; - - ia64_partial_page_cachep = kmem_cache_create("ia64_partial_page_cache", - sizeof(struct ia64_partial_page), - 0, SLAB_PANIC, NULL); - } -#endif - return 0; -} - -__initcall(ia32_init); diff --git a/arch/ia64/ia32/ia32_traps.c b/arch/ia64/ia32/ia32_traps.c deleted file mode 100644 index e486042672f1..000000000000 --- a/arch/ia64/ia32/ia32_traps.c +++ /dev/null @@ -1,156 +0,0 @@ -/* - * IA-32 exception handlers - * - * Copyright (C) 2000 Asit K. Mallick - * Copyright (C) 2001-2002 Hewlett-Packard Co - * David Mosberger-Tang - * - * 06/16/00 A. Mallick added siginfo for most cases (close to IA32) - * 09/29/00 D. Mosberger added ia32_intercept() - */ - -#include -#include - -#include "ia32priv.h" - -#include -#include - -int -ia32_intercept (struct pt_regs *regs, unsigned long isr) -{ - switch ((isr >> 16) & 0xff) { - case 0: /* Instruction intercept fault */ - case 4: /* Locked Data reference fault */ - case 1: /* Gate intercept trap */ - return -1; - - case 2: /* System flag trap */ - if (((isr >> 14) & 0x3) >= 2) { - /* MOV SS, POP SS instructions */ - ia64_psr(regs)->id = 1; - return 0; - } else - return -1; - } - return -1; -} - -int -ia32_exception (struct pt_regs *regs, unsigned long isr) -{ - struct siginfo siginfo; - - /* initialize these fields to avoid leaking kernel bits to user space: */ - siginfo.si_errno = 0; - siginfo.si_flags = 0; - siginfo.si_isr = 0; - siginfo.si_imm = 0; - switch ((isr >> 16) & 0xff) { - case 1: - case 2: - siginfo.si_signo = SIGTRAP; - if (isr == 0) - siginfo.si_code = TRAP_TRACE; - else if (isr & 0x4) - siginfo.si_code = TRAP_BRANCH; - else - siginfo.si_code = TRAP_BRKPT; - break; - - case 3: - siginfo.si_signo = SIGTRAP; - siginfo.si_code = TRAP_BRKPT; - break; - - case 0: /* Divide fault */ - siginfo.si_signo = SIGFPE; - siginfo.si_code = FPE_INTDIV; - break; - - case 4: /* Overflow */ - case 5: /* Bounds fault */ - siginfo.si_signo = SIGFPE; - siginfo.si_code = 0; - break; - - case 6: /* Invalid Op-code */ - siginfo.si_signo = SIGILL; - siginfo.si_code = ILL_ILLOPN; - break; - - case 7: /* FP DNA */ - case 8: /* Double Fault */ - case 9: /* Invalid TSS */ - case 11: /* Segment not present */ - case 12: /* Stack fault */ - case 13: /* General Protection Fault */ - siginfo.si_signo = SIGSEGV; - siginfo.si_code = 0; - break; - - case 16: /* Pending FP error */ - { - unsigned long fsr, fcr; - - fsr = ia64_getreg(_IA64_REG_AR_FSR); - fcr = ia64_getreg(_IA64_REG_AR_FCR); - - siginfo.si_signo = SIGFPE; - /* - * (~cwd & swd) will mask out exceptions that are not set to unmasked - * status. 0x3f is the exception bits in these regs, 0x200 is the - * C1 reg you need in case of a stack fault, 0x040 is the stack - * fault bit. We should only be taking one exception at a time, - * so if this combination doesn't produce any single exception, - * then we have a bad program that isn't synchronizing its FPU usage - * and it will suffer the consequences since we won't be able to - * fully reproduce the context of the exception - */ - siginfo.si_isr = isr; - siginfo.si_flags = __ISR_VALID; - switch(((~fcr) & (fsr & 0x3f)) | (fsr & 0x240)) { - case 0x000: - default: - siginfo.si_code = 0; - break; - case 0x001: /* Invalid Op */ - case 0x040: /* Stack Fault */ - case 0x240: /* Stack Fault | Direction */ - siginfo.si_code = FPE_FLTINV; - break; - case 0x002: /* Denormalize */ - case 0x010: /* Underflow */ - siginfo.si_code = FPE_FLTUND; - break; - case 0x004: /* Zero Divide */ - siginfo.si_code = FPE_FLTDIV; - break; - case 0x008: /* Overflow */ - siginfo.si_code = FPE_FLTOVF; - break; - case 0x020: /* Precision */ - siginfo.si_code = FPE_FLTRES; - break; - } - - break; - } - - case 17: /* Alignment check */ - siginfo.si_signo = SIGSEGV; - siginfo.si_code = BUS_ADRALN; - break; - - case 19: /* SSE Numeric error */ - siginfo.si_signo = SIGFPE; - siginfo.si_code = 0; - break; - - default: - return -1; - } - force_sig_info(siginfo.si_signo, &siginfo, current); - return 0; -} diff --git a/arch/ia64/ia32/ia32priv.h b/arch/ia64/ia32/ia32priv.h deleted file mode 100644 index 0f15349c3c6b..000000000000 --- a/arch/ia64/ia32/ia32priv.h +++ /dev/null @@ -1,532 +0,0 @@ -#ifndef _ASM_IA64_IA32_PRIV_H -#define _ASM_IA64_IA32_PRIV_H - - -#include - -#ifdef CONFIG_IA32_SUPPORT - -#include -#include -#include - -#include - -/* - * 32 bit structures for IA32 support. - */ - -#define IA32_PAGE_SIZE (1UL << IA32_PAGE_SHIFT) -#define IA32_PAGE_MASK (~(IA32_PAGE_SIZE - 1)) -#define IA32_PAGE_ALIGN(addr) (((addr) + IA32_PAGE_SIZE - 1) & IA32_PAGE_MASK) -#define IA32_CLOCKS_PER_SEC 100 /* Cast in stone for IA32 Linux */ - -/* - * partially mapped pages provide precise accounting of which 4k sub pages - * are mapped and which ones are not, thereby improving IA-32 compatibility. - */ -struct ia64_partial_page { - struct ia64_partial_page *next; /* linked list, sorted by address */ - struct rb_node pp_rb; - /* 64K is the largest "normal" page supported by ia64 ABI. So 4K*64 - * should suffice.*/ - unsigned long bitmap; - unsigned int base; -}; - -struct ia64_partial_page_list { - struct ia64_partial_page *pp_head; /* list head, points to the lowest - * addressed partial page */ - struct rb_root ppl_rb; - struct ia64_partial_page *pp_hint; /* pp_hint->next is the last - * accessed partial page */ - atomic_t pp_count; /* reference count */ -}; - -#if PAGE_SHIFT > IA32_PAGE_SHIFT -struct ia64_partial_page_list* ia32_init_pp_list (void); -#else -# define ia32_init_pp_list() 0 -#endif - -/* sigcontext.h */ -/* - * As documented in the iBCS2 standard.. - * - * The first part of "struct _fpstate" is just the - * normal i387 hardware setup, the extra "status" - * word is used to save the coprocessor status word - * before entering the handler. - */ -struct _fpreg_ia32 { - unsigned short significand[4]; - unsigned short exponent; -}; - -struct _fpxreg_ia32 { - unsigned short significand[4]; - unsigned short exponent; - unsigned short padding[3]; -}; - -struct _xmmreg_ia32 { - unsigned int element[4]; -}; - - -struct _fpstate_ia32 { - unsigned int cw, - sw, - tag, - ipoff, - cssel, - dataoff, - datasel; - struct _fpreg_ia32 _st[8]; - unsigned short status; - unsigned short magic; /* 0xffff = regular FPU data only */ - - /* FXSR FPU environment */ - unsigned int _fxsr_env[6]; /* FXSR FPU env is ignored */ - unsigned int mxcsr; - unsigned int reserved; - struct _fpxreg_ia32 _fxsr_st[8]; /* FXSR FPU reg data is ignored */ - struct _xmmreg_ia32 _xmm[8]; - unsigned int padding[56]; -}; - -struct sigcontext_ia32 { - unsigned short gs, __gsh; - unsigned short fs, __fsh; - unsigned short es, __esh; - unsigned short ds, __dsh; - unsigned int edi; - unsigned int esi; - unsigned int ebp; - unsigned int esp; - unsigned int ebx; - unsigned int edx; - unsigned int ecx; - unsigned int eax; - unsigned int trapno; - unsigned int err; - unsigned int eip; - unsigned short cs, __csh; - unsigned int eflags; - unsigned int esp_at_signal; - unsigned short ss, __ssh; - unsigned int fpstate; /* really (struct _fpstate_ia32 *) */ - unsigned int oldmask; - unsigned int cr2; -}; - -/* user.h */ -/* - * IA32 (Pentium III/4) FXSR, SSE support - * - * Provide support for the GDB 5.0+ PTRACE_{GET|SET}FPXREGS requests for - * interacting with the FXSR-format floating point environment. Floating - * point data can be accessed in the regular format in the usual manner, - * and both the standard and SIMD floating point data can be accessed via - * the new ptrace requests. In either case, changes to the FPU environment - * will be reflected in the task's state as expected. - */ -struct ia32_user_i387_struct { - int cwd; - int swd; - int twd; - int fip; - int fcs; - int foo; - int fos; - /* 8*10 bytes for each FP-reg = 80 bytes */ - struct _fpreg_ia32 st_space[8]; -}; - -struct ia32_user_fxsr_struct { - unsigned short cwd; - unsigned short swd; - unsigned short twd; - unsigned short fop; - int fip; - int fcs; - int foo; - int fos; - int mxcsr; - int reserved; - int st_space[32]; /* 8*16 bytes for each FP-reg = 128 bytes */ - int xmm_space[32]; /* 8*16 bytes for each XMM-reg = 128 bytes */ - int padding[56]; -}; - -/* signal.h */ -#define IA32_SET_SA_HANDLER(ka,handler,restorer) \ - ((ka)->sa.sa_handler = (__sighandler_t) \ - (((unsigned long)(restorer) << 32) \ - | ((handler) & 0xffffffff))) -#define IA32_SA_HANDLER(ka) ((unsigned long) (ka)->sa.sa_handler & 0xffffffff) -#define IA32_SA_RESTORER(ka) ((unsigned long) (ka)->sa.sa_handler >> 32) - -#define __IA32_NR_sigreturn 119 -#define __IA32_NR_rt_sigreturn 173 - -struct sigaction32 { - unsigned int sa_handler; /* Really a pointer, but need to deal with 32 bits */ - unsigned int sa_flags; - unsigned int sa_restorer; /* Another 32 bit pointer */ - compat_sigset_t sa_mask; /* A 32 bit mask */ -}; - -struct old_sigaction32 { - unsigned int sa_handler; /* Really a pointer, but need to deal - with 32 bits */ - compat_old_sigset_t sa_mask; /* A 32 bit mask */ - unsigned int sa_flags; - unsigned int sa_restorer; /* Another 32 bit pointer */ -}; - -typedef struct sigaltstack_ia32 { - unsigned int ss_sp; - int ss_flags; - unsigned int ss_size; -} stack_ia32_t; - -struct ucontext_ia32 { - unsigned int uc_flags; - unsigned int uc_link; - stack_ia32_t uc_stack; - struct sigcontext_ia32 uc_mcontext; - sigset_t uc_sigmask; /* mask last for extensibility */ -}; - -struct stat64 { - unsigned long long st_dev; - unsigned char __pad0[4]; - unsigned int __st_ino; - unsigned int st_mode; - unsigned int st_nlink; - unsigned int st_uid; - unsigned int st_gid; - unsigned long long st_rdev; - unsigned char __pad3[4]; - unsigned int st_size_lo; - unsigned int st_size_hi; - unsigned int st_blksize; - unsigned int st_blocks; /* Number 512-byte blocks allocated. */ - unsigned int __pad4; /* future possible st_blocks high bits */ - unsigned int st_atime; - unsigned int st_atime_nsec; - unsigned int st_mtime; - unsigned int st_mtime_nsec; - unsigned int st_ctime; - unsigned int st_ctime_nsec; - unsigned int st_ino_lo; - unsigned int st_ino_hi; -}; - -typedef struct compat_siginfo { - int si_signo; - int si_errno; - int si_code; - - union { - int _pad[((128/sizeof(int)) - 3)]; - - /* kill() */ - struct { - unsigned int _pid; /* sender's pid */ - unsigned int _uid; /* sender's uid */ - } _kill; - - /* POSIX.1b timers */ - struct { - compat_timer_t _tid; /* timer id */ - int _overrun; /* overrun count */ - char _pad[sizeof(unsigned int) - sizeof(int)]; - compat_sigval_t _sigval; /* same as below */ - int _sys_private; /* not to be passed to user */ - } _timer; - - /* POSIX.1b signals */ - struct { - unsigned int _pid; /* sender's pid */ - unsigned int _uid; /* sender's uid */ - compat_sigval_t _sigval; - } _rt; - - /* SIGCHLD */ - struct { - unsigned int _pid; /* which child */ - unsigned int _uid; /* sender's uid */ - int _status; /* exit code */ - compat_clock_t _utime; - compat_clock_t _stime; - } _sigchld; - - /* SIGILL, SIGFPE, SIGSEGV, SIGBUS */ - struct { - unsigned int _addr; /* faulting insn/memory ref. */ - } _sigfault; - - /* SIGPOLL */ - struct { - int _band; /* POLL_IN, POLL_OUT, POLL_MSG */ - int _fd; - } _sigpoll; - } _sifields; -} compat_siginfo_t; - -/* - * IA-32 ELF specific definitions for IA-64. - */ - -#define _ASM_IA64_ELF_H /* Don't include elf.h */ - -#include - -/* - * This is used to ensure we don't load something for the wrong architecture. - */ -#define elf_check_arch(x) ((x)->e_machine == EM_386) - -/* - * These are used to set parameters in the core dumps. - */ -#define ELF_CLASS ELFCLASS32 -#define ELF_DATA ELFDATA2LSB -#define ELF_ARCH EM_386 - -#define IA32_STACK_TOP IA32_PAGE_OFFSET -#define IA32_GATE_OFFSET IA32_PAGE_OFFSET -#define IA32_GATE_END IA32_PAGE_OFFSET + PAGE_SIZE - -/* - * The system segments (GDT, TSS, LDT) have to be mapped below 4GB so the IA-32 engine can - * access them. - */ -#define IA32_GDT_OFFSET (IA32_PAGE_OFFSET + PAGE_SIZE) -#define IA32_TSS_OFFSET (IA32_PAGE_OFFSET + 2*PAGE_SIZE) -#define IA32_LDT_OFFSET (IA32_PAGE_OFFSET + 3*PAGE_SIZE) - -#define ELF_EXEC_PAGESIZE IA32_PAGE_SIZE - -/* - * This is the location that an ET_DYN program is loaded if exec'ed. - * Typical use of this is to invoke "./ld.so someprog" to test out a - * new version of the loader. We need to make sure that it is out of - * the way of the program that it will "exec", and that there is - * sufficient room for the brk. - */ -#define ELF_ET_DYN_BASE (IA32_PAGE_OFFSET/3 + 0x1000000) - -void ia64_elf32_init(struct pt_regs *regs); -#define ELF_PLAT_INIT(_r, load_addr) ia64_elf32_init(_r) - -/* This macro yields a bitmask that programs can use to figure out - what instruction set this CPU supports. */ -#define ELF_HWCAP 0 - -/* This macro yields a string that ld.so will use to load - implementation specific libraries for optimization. Not terribly - relevant until we have real hardware to play with... */ -#define ELF_PLATFORM NULL - -#ifdef __KERNEL__ -# define SET_PERSONALITY(EX) \ - (current->personality = PER_LINUX) -#endif - -#define IA32_EFLAG 0x200 - -/* - * IA-32 ELF specific definitions for IA-64. - */ - -#define __USER_CS 0x23 -#define __USER_DS 0x2B - -/* - * The per-cpu GDT has 32 entries: see - */ -#define GDT_ENTRIES 32 - -#define GDT_SIZE (GDT_ENTRIES * 8) - -#define TSS_ENTRY 14 -#define LDT_ENTRY (TSS_ENTRY + 1) - -#define IA32_SEGSEL_RPL (0x3 << 0) -#define IA32_SEGSEL_TI (0x1 << 2) -#define IA32_SEGSEL_INDEX_SHIFT 3 - -#define _TSS ((unsigned long) TSS_ENTRY << IA32_SEGSEL_INDEX_SHIFT) -#define _LDT ((unsigned long) LDT_ENTRY << IA32_SEGSEL_INDEX_SHIFT) - -#define IA32_SEG_BASE 16 -#define IA32_SEG_TYPE 40 -#define IA32_SEG_SYS 44 -#define IA32_SEG_DPL 45 -#define IA32_SEG_P 47 -#define IA32_SEG_HIGH_LIMIT 48 -#define IA32_SEG_AVL 52 -#define IA32_SEG_DB 54 -#define IA32_SEG_G 55 -#define IA32_SEG_HIGH_BASE 56 - -#define IA32_SEG_DESCRIPTOR(base, limit, segtype, nonsysseg, dpl, segpresent, avl, segdb, gran) \ - (((limit) & 0xffff) \ - | (((unsigned long) (base) & 0xffffff) << IA32_SEG_BASE) \ - | ((unsigned long) (segtype) << IA32_SEG_TYPE) \ - | ((unsigned long) (nonsysseg) << IA32_SEG_SYS) \ - | ((unsigned long) (dpl) << IA32_SEG_DPL) \ - | ((unsigned long) (segpresent) << IA32_SEG_P) \ - | ((((unsigned long) (limit) >> 16) & 0xf) << IA32_SEG_HIGH_LIMIT) \ - | ((unsigned long) (avl) << IA32_SEG_AVL) \ - | ((unsigned long) (segdb) << IA32_SEG_DB) \ - | ((unsigned long) (gran) << IA32_SEG_G) \ - | ((((unsigned long) (base) >> 24) & 0xff) << IA32_SEG_HIGH_BASE)) - -#define SEG_LIM 32 -#define SEG_TYPE 52 -#define SEG_SYS 56 -#define SEG_DPL 57 -#define SEG_P 59 -#define SEG_AVL 60 -#define SEG_DB 62 -#define SEG_G 63 - -/* Unscramble an IA-32 segment descriptor into the IA-64 format. */ -#define IA32_SEG_UNSCRAMBLE(sd) \ - ( (((sd) >> IA32_SEG_BASE) & 0xffffff) | ((((sd) >> IA32_SEG_HIGH_BASE) & 0xff) << 24) \ - | ((((sd) & 0xffff) | ((((sd) >> IA32_SEG_HIGH_LIMIT) & 0xf) << 16)) << SEG_LIM) \ - | ((((sd) >> IA32_SEG_TYPE) & 0xf) << SEG_TYPE) \ - | ((((sd) >> IA32_SEG_SYS) & 0x1) << SEG_SYS) \ - | ((((sd) >> IA32_SEG_DPL) & 0x3) << SEG_DPL) \ - | ((((sd) >> IA32_SEG_P) & 0x1) << SEG_P) \ - | ((((sd) >> IA32_SEG_AVL) & 0x1) << SEG_AVL) \ - | ((((sd) >> IA32_SEG_DB) & 0x1) << SEG_DB) \ - | ((((sd) >> IA32_SEG_G) & 0x1) << SEG_G)) - -#define IA32_IOBASE 0x2000000000000000UL /* Virtual address for I/O space */ - -#define IA32_CR0 0x80000001 /* Enable PG and PE bits */ -#define IA32_CR4 0x600 /* MMXEX and FXSR on */ - -/* - * IA32 floating point control registers starting values - */ - -#define IA32_FSR_DEFAULT 0x55550000 /* set all tag bits */ -#define IA32_FCR_DEFAULT 0x17800000037fUL /* extended precision, all masks */ - -#define IA32_PTRACE_GETREGS 12 -#define IA32_PTRACE_SETREGS 13 -#define IA32_PTRACE_GETFPREGS 14 -#define IA32_PTRACE_SETFPREGS 15 -#define IA32_PTRACE_GETFPXREGS 18 -#define IA32_PTRACE_SETFPXREGS 19 - -#define ia32_start_thread(regs,new_ip,new_sp) do { \ - set_fs(USER_DS); \ - ia64_psr(regs)->cpl = 3; /* set user mode */ \ - ia64_psr(regs)->ri = 0; /* clear return slot number */ \ - ia64_psr(regs)->is = 1; /* IA-32 instruction set */ \ - regs->cr_iip = new_ip; \ - regs->ar_rsc = 0xc; /* enforced lazy mode, priv. level 3 */ \ - regs->ar_rnat = 0; \ - regs->loadrs = 0; \ - regs->r12 = new_sp; \ -} while (0) - -/* - * Local Descriptor Table (LDT) related declarations. - */ - -#define IA32_LDT_ENTRIES 8192 /* Maximum number of LDT entries supported. */ -#define IA32_LDT_ENTRY_SIZE 8 /* The size of each LDT entry. */ - -#define LDT_entry_a(info) \ - ((((info)->base_addr & 0x0000ffff) << 16) | ((info)->limit & 0x0ffff)) - -#define LDT_entry_b(info) \ - (((info)->base_addr & 0xff000000) | \ - (((info)->base_addr & 0x00ff0000) >> 16) | \ - ((info)->limit & 0xf0000) | \ - (((info)->read_exec_only ^ 1) << 9) | \ - ((info)->contents << 10) | \ - (((info)->seg_not_present ^ 1) << 15) | \ - ((info)->seg_32bit << 22) | \ - ((info)->limit_in_pages << 23) | \ - ((info)->useable << 20) | \ - 0x7100) - -#define LDT_empty(info) ( \ - (info)->base_addr == 0 && \ - (info)->limit == 0 && \ - (info)->contents == 0 && \ - (info)->read_exec_only == 1 && \ - (info)->seg_32bit == 0 && \ - (info)->limit_in_pages == 0 && \ - (info)->seg_not_present == 1 && \ - (info)->useable == 0 ) - -static inline void -load_TLS (struct thread_struct *t, unsigned int cpu) -{ - extern unsigned long *cpu_gdt_table[NR_CPUS]; - - memcpy(cpu_gdt_table[cpu] + GDT_ENTRY_TLS_MIN + 0, &t->tls_array[0], sizeof(long)); - memcpy(cpu_gdt_table[cpu] + GDT_ENTRY_TLS_MIN + 1, &t->tls_array[1], sizeof(long)); - memcpy(cpu_gdt_table[cpu] + GDT_ENTRY_TLS_MIN + 2, &t->tls_array[2], sizeof(long)); -} - -struct ia32_user_desc { - unsigned int entry_number; - unsigned int base_addr; - unsigned int limit; - unsigned int seg_32bit:1; - unsigned int contents:2; - unsigned int read_exec_only:1; - unsigned int limit_in_pages:1; - unsigned int seg_not_present:1; - unsigned int useable:1; -}; - -struct linux_binprm; - -extern void ia32_init_addr_space (struct pt_regs *regs); -extern int ia32_setup_arg_pages (struct linux_binprm *bprm, int exec_stack); -extern unsigned long ia32_do_mmap (struct file *, unsigned long, unsigned long, int, int, loff_t); -extern void ia32_load_segment_descriptors (struct task_struct *task); - -#define ia32f2ia64f(dst,src) \ -do { \ - ia64_ldfe(6,src); \ - ia64_stop(); \ - ia64_stf_spill(dst, 6); \ -} while(0) - -#define ia64f2ia32f(dst,src) \ -do { \ - ia64_ldf_fill(6, src); \ - ia64_stop(); \ - ia64_stfe(dst, 6); \ -} while(0) - -struct user_regs_struct32 { - __u32 ebx, ecx, edx, esi, edi, ebp, eax; - unsigned short ds, __ds, es, __es; - unsigned short fs, __fs, gs, __gs; - __u32 orig_eax, eip; - unsigned short cs, __cs; - __u32 eflags, esp; - unsigned short ss, __ss; -}; - -/* Prototypes for use in elfcore32.h */ -extern int save_ia32_fpstate (struct task_struct *, struct ia32_user_i387_struct __user *); -extern int save_ia32_fpxstate (struct task_struct *, struct ia32_user_fxsr_struct __user *); - -#endif /* !CONFIG_IA32_SUPPORT */ - -#endif /* _ASM_IA64_IA32_PRIV_H */ diff --git a/arch/ia64/ia32/sys_ia32.c b/arch/ia64/ia32/sys_ia32.c deleted file mode 100644 index 045b746b9808..000000000000 --- a/arch/ia64/ia32/sys_ia32.c +++ /dev/null @@ -1,2765 +0,0 @@ -/* - * sys_ia32.c: Conversion between 32bit and 64bit native syscalls. Derived from sys_sparc32.c. - * - * Copyright (C) 2000 VA Linux Co - * Copyright (C) 2000 Don Dugger - * Copyright (C) 1999 Arun Sharma - * Copyright (C) 1997,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz) - * Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu) - * Copyright (C) 2000-2003, 2005 Hewlett-Packard Co - * David Mosberger-Tang - * Copyright (C) 2004 Gordon Jin - * - * These routines maintain argument size conversion between 32bit and 64bit - * environment. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include "ia32priv.h" - -#include -#include - -#define DEBUG 0 - -#if DEBUG -# define DBG(fmt...) printk(KERN_DEBUG fmt) -#else -# define DBG(fmt...) -#endif - -#define ROUND_UP(x,a) ((__typeof__(x))(((unsigned long)(x) + ((a) - 1)) & ~((a) - 1))) - -#define OFFSET4K(a) ((a) & 0xfff) -#define PAGE_START(addr) ((addr) & PAGE_MASK) -#define MINSIGSTKSZ_IA32 2048 - -#define high2lowuid(uid) ((uid) > 65535 ? 65534 : (uid)) -#define high2lowgid(gid) ((gid) > 65535 ? 65534 : (gid)) - -/* - * Anything that modifies or inspects ia32 user virtual memory must hold this semaphore - * while doing so. - */ -/* XXX make per-mm: */ -static DEFINE_MUTEX(ia32_mmap_mutex); - -asmlinkage long -sys32_execve (char __user *name, compat_uptr_t __user *argv, compat_uptr_t __user *envp, - struct pt_regs *regs) -{ - long error; - char *filename; - unsigned long old_map_base, old_task_size, tssd; - - filename = getname(name); - error = PTR_ERR(filename); - if (IS_ERR(filename)) - return error; - - old_map_base = current->thread.map_base; - old_task_size = current->thread.task_size; - tssd = ia64_get_kr(IA64_KR_TSSD); - - /* we may be exec'ing a 64-bit process: reset map base, task-size, and io-base: */ - current->thread.map_base = DEFAULT_MAP_BASE; - current->thread.task_size = DEFAULT_TASK_SIZE; - ia64_set_kr(IA64_KR_IO_BASE, current->thread.old_iob); - ia64_set_kr(IA64_KR_TSSD, current->thread.old_k1); - - error = compat_do_execve(filename, argv, envp, regs); - putname(filename); - - if (error < 0) { - /* oops, execve failed, switch back to old values... */ - ia64_set_kr(IA64_KR_IO_BASE, IA32_IOBASE); - ia64_set_kr(IA64_KR_TSSD, tssd); - current->thread.map_base = old_map_base; - current->thread.task_size = old_task_size; - } - - return error; -} - - -#if PAGE_SHIFT > IA32_PAGE_SHIFT - - -static int -get_page_prot (struct vm_area_struct *vma, unsigned long addr) -{ - int prot = 0; - - if (!vma || vma->vm_start > addr) - return 0; - - if (vma->vm_flags & VM_READ) - prot |= PROT_READ; - if (vma->vm_flags & VM_WRITE) - prot |= PROT_WRITE; - if (vma->vm_flags & VM_EXEC) - prot |= PROT_EXEC; - return prot; -} - -/* - * Map a subpage by creating an anonymous page that contains the union of the old page and - * the subpage. - */ -static unsigned long -mmap_subpage (struct file *file, unsigned long start, unsigned long end, int prot, int flags, - loff_t off) -{ - void *page = NULL; - struct inode *inode; - unsigned long ret = 0; - struct vm_area_struct *vma = find_vma(current->mm, start); - int old_prot = get_page_prot(vma, start); - - DBG("mmap_subpage(file=%p,start=0x%lx,end=0x%lx,prot=%x,flags=%x,off=0x%llx)\n", - file, start, end, prot, flags, off); - - - /* Optimize the case where the old mmap and the new mmap are both anonymous */ - if ((old_prot & PROT_WRITE) && (flags & MAP_ANONYMOUS) && !vma->vm_file) { - if (clear_user((void __user *) start, end - start)) { - ret = -EFAULT; - goto out; - } - goto skip_mmap; - } - - page = (void *) get_zeroed_page(GFP_KERNEL); - if (!page) - return -ENOMEM; - - if (old_prot) - copy_from_user(page, (void __user *) PAGE_START(start), PAGE_SIZE); - - down_write(¤t->mm->mmap_sem); - { - ret = do_mmap(NULL, PAGE_START(start), PAGE_SIZE, prot | PROT_WRITE, - flags | MAP_FIXED | MAP_ANONYMOUS, 0); - } - up_write(¤t->mm->mmap_sem); - - if (IS_ERR((void *) ret)) - goto out; - - if (old_prot) { - /* copy back the old page contents. */ - if (offset_in_page(start)) - copy_to_user((void __user *) PAGE_START(start), page, - offset_in_page(start)); - if (offset_in_page(end)) - copy_to_user((void __user *) end, page + offset_in_page(end), - PAGE_SIZE - offset_in_page(end)); - } - - if (!(flags & MAP_ANONYMOUS)) { - /* read the file contents */ - inode = file->f_path.dentry->d_inode; - if (!inode->i_fop || !file->f_op->read - || ((*file->f_op->read)(file, (char __user *) start, end - start, &off) < 0)) - { - ret = -EINVAL; - goto out; - } - } - - skip_mmap: - if (!(prot & PROT_WRITE)) - ret = sys_mprotect(PAGE_START(start), PAGE_SIZE, prot | old_prot); - out: - if (page) - free_page((unsigned long) page); - return ret; -} - -/* SLAB cache for ia64_partial_page structures */ -struct kmem_cache *ia64_partial_page_cachep; - -/* - * init ia64_partial_page_list. - * return 0 means kmalloc fail. - */ -struct ia64_partial_page_list* -ia32_init_pp_list(void) -{ - struct ia64_partial_page_list *p; - - if ((p = kmalloc(sizeof(*p), GFP_KERNEL)) == NULL) - return p; - p->pp_head = NULL; - p->ppl_rb = RB_ROOT; - p->pp_hint = NULL; - atomic_set(&p->pp_count, 1); - return p; -} - -/* - * Search for the partial page with @start in partial page list @ppl. - * If finds the partial page, return the found partial page. - * Else, return 0 and provide @pprev, @rb_link, @rb_parent to - * be used by later __ia32_insert_pp(). - */ -static struct ia64_partial_page * -__ia32_find_pp(struct ia64_partial_page_list *ppl, unsigned int start, - struct ia64_partial_page **pprev, struct rb_node ***rb_link, - struct rb_node **rb_parent) -{ - struct ia64_partial_page *pp; - struct rb_node **__rb_link, *__rb_parent, *rb_prev; - - pp = ppl->pp_hint; - if (pp && pp->base == start) - return pp; - - __rb_link = &ppl->ppl_rb.rb_node; - rb_prev = __rb_parent = NULL; - - while (*__rb_link) { - __rb_parent = *__rb_link; - pp = rb_entry(__rb_parent, struct ia64_partial_page, pp_rb); - - if (pp->base == start) { - ppl->pp_hint = pp; - return pp; - } else if (pp->base < start) { - rb_prev = __rb_parent; - __rb_link = &__rb_parent->rb_right; - } else { - __rb_link = &__rb_parent->rb_left; - } - } - - *rb_link = __rb_link; - *rb_parent = __rb_parent; - *pprev = NULL; - if (rb_prev) - *pprev = rb_entry(rb_prev, struct ia64_partial_page, pp_rb); - return NULL; -} - -/* - * insert @pp into @ppl. - */ -static void -__ia32_insert_pp(struct ia64_partial_page_list *ppl, - struct ia64_partial_page *pp, struct ia64_partial_page *prev, - struct rb_node **rb_link, struct rb_node *rb_parent) -{ - /* link list */ - if (prev) { - pp->next = prev->next; - prev->next = pp; - } else { - ppl->pp_head = pp; - if (rb_parent) - pp->next = rb_entry(rb_parent, - struct ia64_partial_page, pp_rb); - else - pp->next = NULL; - } - - /* link rb */ - rb_link_node(&pp->pp_rb, rb_parent, rb_link); - rb_insert_color(&pp->pp_rb, &ppl->ppl_rb); - - ppl->pp_hint = pp; -} - -/* - * delete @pp from partial page list @ppl. - */ -static void -__ia32_delete_pp(struct ia64_partial_page_list *ppl, - struct ia64_partial_page *pp, struct ia64_partial_page *prev) -{ - if (prev) { - prev->next = pp->next; - if (ppl->pp_hint == pp) - ppl->pp_hint = prev; - } else { - ppl->pp_head = pp->next; - if (ppl->pp_hint == pp) - ppl->pp_hint = pp->next; - } - rb_erase(&pp->pp_rb, &ppl->ppl_rb); - kmem_cache_free(ia64_partial_page_cachep, pp); -} - -static struct ia64_partial_page * -__pp_prev(struct ia64_partial_page *pp) -{ - struct rb_node *prev = rb_prev(&pp->pp_rb); - if (prev) - return rb_entry(prev, struct ia64_partial_page, pp_rb); - else - return NULL; -} - -/* - * Delete partial pages with address between @start and @end. - * @start and @end are page aligned. - */ -static void -__ia32_delete_pp_range(unsigned int start, unsigned int end) -{ - struct ia64_partial_page *pp, *prev; - struct rb_node **rb_link, *rb_parent; - - if (start >= end) - return; - - pp = __ia32_find_pp(current->thread.ppl, start, &prev, - &rb_link, &rb_parent); - if (pp) - prev = __pp_prev(pp); - else { - if (prev) - pp = prev->next; - else - pp = current->thread.ppl->pp_head; - } - - while (pp && pp->base < end) { - struct ia64_partial_page *tmp = pp->next; - __ia32_delete_pp(current->thread.ppl, pp, prev); - pp = tmp; - } -} - -/* - * Set the range between @start and @end in bitmap. - * @start and @end should be IA32 page aligned and in the same IA64 page. - */ -static int -__ia32_set_pp(unsigned int start, unsigned int end, int flags) -{ - struct ia64_partial_page *pp, *prev; - struct rb_node ** rb_link, *rb_parent; - unsigned int pstart, start_bit, end_bit, i; - - pstart = PAGE_START(start); - start_bit = (start % PAGE_SIZE) / IA32_PAGE_SIZE; - end_bit = (end % PAGE_SIZE) / IA32_PAGE_SIZE; - if (end_bit == 0) - end_bit = PAGE_SIZE / IA32_PAGE_SIZE; - pp = __ia32_find_pp(current->thread.ppl, pstart, &prev, - &rb_link, &rb_parent); - if (pp) { - for (i = start_bit; i < end_bit; i++) - set_bit(i, &pp->bitmap); - /* - * Check: if this partial page has been set to a full page, - * then delete it. - */ - if (find_first_zero_bit(&pp->bitmap, sizeof(pp->bitmap)*8) >= - PAGE_SIZE/IA32_PAGE_SIZE) { - __ia32_delete_pp(current->thread.ppl, pp, __pp_prev(pp)); - } - return 0; - } - - /* - * MAP_FIXED may lead to overlapping mmap. - * In this case, the requested mmap area may already mmaped as a full - * page. So check vma before adding a new partial page. - */ - if (flags & MAP_FIXED) { - struct vm_area_struct *vma = find_vma(current->mm, pstart); - if (vma && vma->vm_start <= pstart) - return 0; - } - - /* new a ia64_partial_page */ - pp = kmem_cache_alloc(ia64_partial_page_cachep, GFP_KERNEL); - if (!pp) - return -ENOMEM; - pp->base = pstart; - pp->bitmap = 0; - for (i=start_bit; ibitmap)); - pp->next = NULL; - __ia32_insert_pp(current->thread.ppl, pp, prev, rb_link, rb_parent); - return 0; -} - -/* - * @start and @end should be IA32 page aligned, but don't need to be in the - * same IA64 page. Split @start and @end to make sure they're in the same IA64 - * page, then call __ia32_set_pp(). - */ -static void -ia32_set_pp(unsigned int start, unsigned int end, int flags) -{ - down_write(¤t->mm->mmap_sem); - if (flags & MAP_FIXED) { - /* - * MAP_FIXED may lead to overlapping mmap. When this happens, - * a series of complete IA64 pages results in deletion of - * old partial pages in that range. - */ - __ia32_delete_pp_range(PAGE_ALIGN(start), PAGE_START(end)); - } - - if (end < PAGE_ALIGN(start)) { - __ia32_set_pp(start, end, flags); - } else { - if (offset_in_page(start)) - __ia32_set_pp(start, PAGE_ALIGN(start), flags); - if (offset_in_page(end)) - __ia32_set_pp(PAGE_START(end), end, flags); - } - up_write(¤t->mm->mmap_sem); -} - -/* - * Unset the range between @start and @end in bitmap. - * @start and @end should be IA32 page aligned and in the same IA64 page. - * After doing that, if the bitmap is 0, then free the page and return 1, - * else return 0; - * If not find the partial page in the list, then - * If the vma exists, then the full page is set to a partial page; - * Else return -ENOMEM. - */ -static int -__ia32_unset_pp(unsigned int start, unsigned int end) -{ - struct ia64_partial_page *pp, *prev; - struct rb_node ** rb_link, *rb_parent; - unsigned int pstart, start_bit, end_bit, i; - struct vm_area_struct *vma; - - pstart = PAGE_START(start); - start_bit = (start % PAGE_SIZE) / IA32_PAGE_SIZE; - end_bit = (end % PAGE_SIZE) / IA32_PAGE_SIZE; - if (end_bit == 0) - end_bit = PAGE_SIZE / IA32_PAGE_SIZE; - - pp = __ia32_find_pp(current->thread.ppl, pstart, &prev, - &rb_link, &rb_parent); - if (pp) { - for (i = start_bit; i < end_bit; i++) - clear_bit(i, &pp->bitmap); - if (pp->bitmap == 0) { - __ia32_delete_pp(current->thread.ppl, pp, __pp_prev(pp)); - return 1; - } - return 0; - } - - vma = find_vma(current->mm, pstart); - if (!vma || vma->vm_start > pstart) { - return -ENOMEM; - } - - /* new a ia64_partial_page */ - pp = kmem_cache_alloc(ia64_partial_page_cachep, GFP_KERNEL); - if (!pp) - return -ENOMEM; - pp->base = pstart; - pp->bitmap = 0; - for (i = 0; i < start_bit; i++) - set_bit(i, &(pp->bitmap)); - for (i = end_bit; i < PAGE_SIZE / IA32_PAGE_SIZE; i++) - set_bit(i, &(pp->bitmap)); - pp->next = NULL; - __ia32_insert_pp(current->thread.ppl, pp, prev, rb_link, rb_parent); - return 0; -} - -/* - * Delete pp between PAGE_ALIGN(start) and PAGE_START(end) by calling - * __ia32_delete_pp_range(). Unset possible partial pages by calling - * __ia32_unset_pp(). - * The returned value see __ia32_unset_pp(). - */ -static int -ia32_unset_pp(unsigned int *startp, unsigned int *endp) -{ - unsigned int start = *startp, end = *endp; - int ret = 0; - - down_write(¤t->mm->mmap_sem); - - __ia32_delete_pp_range(PAGE_ALIGN(start), PAGE_START(end)); - - if (end < PAGE_ALIGN(start)) { - ret = __ia32_unset_pp(start, end); - if (ret == 1) { - *startp = PAGE_START(start); - *endp = PAGE_ALIGN(end); - } - if (ret == 0) { - /* to shortcut sys_munmap() in sys32_munmap() */ - *startp = PAGE_START(start); - *endp = PAGE_START(end); - } - } else { - if (offset_in_page(start)) { - ret = __ia32_unset_pp(start, PAGE_ALIGN(start)); - if (ret == 1) - *startp = PAGE_START(start); - if (ret == 0) - *startp = PAGE_ALIGN(start); - if (ret < 0) - goto out; - } - if (offset_in_page(end)) { - ret = __ia32_unset_pp(PAGE_START(end), end); - if (ret == 1) - *endp = PAGE_ALIGN(end); - if (ret == 0) - *endp = PAGE_START(end); - } - } - - out: - up_write(¤t->mm->mmap_sem); - return ret; -} - -/* - * Compare the range between @start and @end with bitmap in partial page. - * @start and @end should be IA32 page aligned and in the same IA64 page. - */ -static int -__ia32_compare_pp(unsigned int start, unsigned int end) -{ - struct ia64_partial_page *pp, *prev; - struct rb_node ** rb_link, *rb_parent; - unsigned int pstart, start_bit, end_bit, size; - unsigned int first_bit, next_zero_bit; /* the first range in bitmap */ - - pstart = PAGE_START(start); - - pp = __ia32_find_pp(current->thread.ppl, pstart, &prev, - &rb_link, &rb_parent); - if (!pp) - return 1; - - start_bit = (start % PAGE_SIZE) / IA32_PAGE_SIZE; - end_bit = (end % PAGE_SIZE) / IA32_PAGE_SIZE; - size = sizeof(pp->bitmap) * 8; - first_bit = find_first_bit(&pp->bitmap, size); - next_zero_bit = find_next_zero_bit(&pp->bitmap, size, first_bit); - if ((start_bit < first_bit) || (end_bit > next_zero_bit)) { - /* exceeds the first range in bitmap */ - return -ENOMEM; - } else if ((start_bit == first_bit) && (end_bit == next_zero_bit)) { - first_bit = find_next_bit(&pp->bitmap, size, next_zero_bit); - if ((next_zero_bit < first_bit) && (first_bit < size)) - return 1; /* has next range */ - else - return 0; /* no next range */ - } else - return 1; -} - -/* - * @start and @end should be IA32 page aligned, but don't need to be in the - * same IA64 page. Split @start and @end to make sure they're in the same IA64 - * page, then call __ia32_compare_pp(). - * - * Take this as example: the range is the 1st and 2nd 4K page. - * Return 0 if they fit bitmap exactly, i.e. bitmap = 00000011; - * Return 1 if the range doesn't cover whole bitmap, e.g. bitmap = 00001111; - * Return -ENOMEM if the range exceeds the bitmap, e.g. bitmap = 00000001 or - * bitmap = 00000101. - */ -static int -ia32_compare_pp(unsigned int *startp, unsigned int *endp) -{ - unsigned int start = *startp, end = *endp; - int retval = 0; - - down_write(¤t->mm->mmap_sem); - - if (end < PAGE_ALIGN(start)) { - retval = __ia32_compare_pp(start, end); - if (retval == 0) { - *startp = PAGE_START(start); - *endp = PAGE_ALIGN(end); - } - } else { - if (offset_in_page(start)) { - retval = __ia32_compare_pp(start, - PAGE_ALIGN(start)); - if (retval == 0) - *startp = PAGE_START(start); - if (retval < 0) - goto out; - } - if (offset_in_page(end)) { - retval = __ia32_compare_pp(PAGE_START(end), end); - if (retval == 0) - *endp = PAGE_ALIGN(end); - } - } - - out: - up_write(¤t->mm->mmap_sem); - return retval; -} - -static void -__ia32_drop_pp_list(struct ia64_partial_page_list *ppl) -{ - struct ia64_partial_page *pp = ppl->pp_head; - - while (pp) { - struct ia64_partial_page *next = pp->next; - kmem_cache_free(ia64_partial_page_cachep, pp); - pp = next; - } - - kfree(ppl); -} - -void -ia32_drop_ia64_partial_page_list(struct task_struct *task) -{ - struct ia64_partial_page_list* ppl = task->thread.ppl; - - if (ppl && atomic_dec_and_test(&ppl->pp_count)) - __ia32_drop_pp_list(ppl); -} - -/* - * Copy current->thread.ppl to ppl (already initialized). - */ -static int -__ia32_copy_pp_list(struct ia64_partial_page_list *ppl) -{ - struct ia64_partial_page *pp, *tmp, *prev; - struct rb_node **rb_link, *rb_parent; - - ppl->pp_head = NULL; - ppl->pp_hint = NULL; - ppl->ppl_rb = RB_ROOT; - rb_link = &ppl->ppl_rb.rb_node; - rb_parent = NULL; - prev = NULL; - - for (pp = current->thread.ppl->pp_head; pp; pp = pp->next) { - tmp = kmem_cache_alloc(ia64_partial_page_cachep, GFP_KERNEL); - if (!tmp) - return -ENOMEM; - *tmp = *pp; - __ia32_insert_pp(ppl, tmp, prev, rb_link, rb_parent); - prev = tmp; - rb_link = &tmp->pp_rb.rb_right; - rb_parent = &tmp->pp_rb; - } - return 0; -} - -int -ia32_copy_ia64_partial_page_list(struct task_struct *p, - unsigned long clone_flags) -{ - int retval = 0; - - if (clone_flags & CLONE_VM) { - atomic_inc(¤t->thread.ppl->pp_count); - p->thread.ppl = current->thread.ppl; - } else { - p->thread.ppl = ia32_init_pp_list(); - if (!p->thread.ppl) - return -ENOMEM; - down_write(¤t->mm->mmap_sem); - { - retval = __ia32_copy_pp_list(p->thread.ppl); - } - up_write(¤t->mm->mmap_sem); - } - - return retval; -} - -static unsigned long -emulate_mmap (struct file *file, unsigned long start, unsigned long len, int prot, int flags, - loff_t off) -{ - unsigned long tmp, end, pend, pstart, ret, is_congruent, fudge = 0; - struct inode *inode; - loff_t poff; - - end = start + len; - pstart = PAGE_START(start); - pend = PAGE_ALIGN(end); - - if (flags & MAP_FIXED) { - ia32_set_pp((unsigned int)start, (unsigned int)end, flags); - if (start > pstart) { - if (flags & MAP_SHARED) - printk(KERN_INFO - "%s(%d): emulate_mmap() can't share head (addr=0x%lx)\n", - current->comm, task_pid_nr(current), start); - ret = mmap_subpage(file, start, min(PAGE_ALIGN(start), end), prot, flags, - off); - if (IS_ERR((void *) ret)) - return ret; - pstart += PAGE_SIZE; - if (pstart >= pend) - goto out; /* done */ - } - if (end < pend) { - if (flags & MAP_SHARED) - printk(KERN_INFO - "%s(%d): emulate_mmap() can't share tail (end=0x%lx)\n", - current->comm, task_pid_nr(current), end); - ret = mmap_subpage(file, max(start, PAGE_START(end)), end, prot, flags, - (off + len) - offset_in_page(end)); - if (IS_ERR((void *) ret)) - return ret; - pend -= PAGE_SIZE; - if (pstart >= pend) - goto out; /* done */ - } - } else { - /* - * If a start address was specified, use it if the entire rounded out area - * is available. - */ - if (start && !pstart) - fudge = 1; /* handle case of mapping to range (0,PAGE_SIZE) */ - tmp = arch_get_unmapped_area(file, pstart - fudge, pend - pstart, 0, flags); - if (tmp != pstart) { - pstart = tmp; - start = pstart + offset_in_page(off); /* make start congruent with off */ - end = start + len; - pend = PAGE_ALIGN(end); - } - } - - poff = off + (pstart - start); /* note: (pstart - start) may be negative */ - is_congruent = (flags & MAP_ANONYMOUS) || (offset_in_page(poff) == 0); - - if ((flags & MAP_SHARED) && !is_congruent) - printk(KERN_INFO "%s(%d): emulate_mmap() can't share contents of incongruent mmap " - "(addr=0x%lx,off=0x%llx)\n", current->comm, task_pid_nr(current), start, off); - - DBG("mmap_body: mapping [0x%lx-0x%lx) %s with poff 0x%llx\n", pstart, pend, - is_congruent ? "congruent" : "not congruent", poff); - - down_write(¤t->mm->mmap_sem); - { - if (!(flags & MAP_ANONYMOUS) && is_congruent) - ret = do_mmap(file, pstart, pend - pstart, prot, flags | MAP_FIXED, poff); - else - ret = do_mmap(NULL, pstart, pend - pstart, - prot | ((flags & MAP_ANONYMOUS) ? 0 : PROT_WRITE), - flags | MAP_FIXED | MAP_ANONYMOUS, 0); - } - up_write(¤t->mm->mmap_sem); - - if (IS_ERR((void *) ret)) - return ret; - - if (!is_congruent) { - /* read the file contents */ - inode = file->f_path.dentry->d_inode; - if (!inode->i_fop || !file->f_op->read - || ((*file->f_op->read)(file, (char __user *) pstart, pend - pstart, &poff) - < 0)) - { - sys_munmap(pstart, pend - pstart); - return -EINVAL; - } - if (!(prot & PROT_WRITE) && sys_mprotect(pstart, pend - pstart, prot) < 0) - return -EINVAL; - } - - if (!(flags & MAP_FIXED)) - ia32_set_pp((unsigned int)start, (unsigned int)end, flags); -out: - return start; -} - -#endif /* PAGE_SHIFT > IA32_PAGE_SHIFT */ - -static inline unsigned int -get_prot32 (unsigned int prot) -{ - if (prot & PROT_WRITE) - /* on x86, PROT_WRITE implies PROT_READ which implies PROT_EEC */ - prot |= PROT_READ | PROT_WRITE | PROT_EXEC; - else if (prot & (PROT_READ | PROT_EXEC)) - /* on x86, there is no distinction between PROT_READ and PROT_EXEC */ - prot |= (PROT_READ | PROT_EXEC); - - return prot; -} - -unsigned long -ia32_do_mmap (struct file *file, unsigned long addr, unsigned long len, int prot, int flags, - loff_t offset) -{ - DBG("ia32_do_mmap(file=%p,addr=0x%lx,len=0x%lx,prot=%x,flags=%x,offset=0x%llx)\n", - file, addr, len, prot, flags, offset); - - if (file && (!file->f_op || !file->f_op->mmap)) - return -ENODEV; - - len = IA32_PAGE_ALIGN(len); - if (len == 0) - return addr; - - if (len > IA32_PAGE_OFFSET || addr > IA32_PAGE_OFFSET - len) - { - if (flags & MAP_FIXED) - return -ENOMEM; - else - return -EINVAL; - } - - if (OFFSET4K(offset)) - return -EINVAL; - - prot = get_prot32(prot); - - if (flags & MAP_HUGETLB) - return -ENOMEM; - -#if PAGE_SHIFT > IA32_PAGE_SHIFT - mutex_lock(&ia32_mmap_mutex); - { - addr = emulate_mmap(file, addr, len, prot, flags, offset); - } - mutex_unlock(&ia32_mmap_mutex); -#else - down_write(¤t->mm->mmap_sem); - { - addr = do_mmap(file, addr, len, prot, flags, offset); - } - up_write(¤t->mm->mmap_sem); -#endif - DBG("ia32_do_mmap: returning 0x%lx\n", addr); - return addr; -} - -/* - * Linux/i386 didn't use to be able to handle more than 4 system call parameters, so these - * system calls used a memory block for parameter passing.. - */ - -struct mmap_arg_struct { - unsigned int addr; - unsigned int len; - unsigned int prot; - unsigned int flags; - unsigned int fd; - unsigned int offset; -}; - -asmlinkage long -sys32_mmap (struct mmap_arg_struct __user *arg) -{ - struct mmap_arg_struct a; - struct file *file = NULL; - unsigned long addr; - int flags; - - if (copy_from_user(&a, arg, sizeof(a))) - return -EFAULT; - - if (OFFSET4K(a.offset)) - return -EINVAL; - - flags = a.flags; - - flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE); - if (!(flags & MAP_ANONYMOUS)) { - file = fget(a.fd); - if (!file) - return -EBADF; - } - - addr = ia32_do_mmap(file, a.addr, a.len, a.prot, flags, a.offset); - - if (file) - fput(file); - return addr; -} - -asmlinkage long -sys32_mmap2 (unsigned int addr, unsigned int len, unsigned int prot, unsigned int flags, - unsigned int fd, unsigned int pgoff) -{ - struct file *file = NULL; - unsigned long retval; - - flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE); - if (!(flags & MAP_ANONYMOUS)) { - file = fget(fd); - if (!file) - return -EBADF; - } - - retval = ia32_do_mmap(file, addr, len, prot, flags, - (unsigned long) pgoff << IA32_PAGE_SHIFT); - - if (file) - fput(file); - return retval; -} - -asmlinkage long -sys32_munmap (unsigned int start, unsigned int len) -{ - unsigned int end = start + len; - long ret; - -#if PAGE_SHIFT <= IA32_PAGE_SHIFT - ret = sys_munmap(start, end - start); -#else - if (OFFSET4K(start)) - return -EINVAL; - - end = IA32_PAGE_ALIGN(end); - if (start >= end) - return -EINVAL; - - ret = ia32_unset_pp(&start, &end); - if (ret < 0) - return ret; - - if (start >= end) - return 0; - - mutex_lock(&ia32_mmap_mutex); - ret = sys_munmap(start, end - start); - mutex_unlock(&ia32_mmap_mutex); -#endif - return ret; -} - -#if PAGE_SHIFT > IA32_PAGE_SHIFT - -/* - * When mprotect()ing a partial page, we set the permission to the union of the old - * settings and the new settings. In other words, it's only possible to make access to a - * partial page less restrictive. - */ -static long -mprotect_subpage (unsigned long address, int new_prot) -{ - int old_prot; - struct vm_area_struct *vma; - - if (new_prot == PROT_NONE) - return 0; /* optimize case where nothing changes... */ - vma = find_vma(current->mm, address); - old_prot = get_page_prot(vma, address); - return sys_mprotect(address, PAGE_SIZE, new_prot | old_prot); -} - -#endif /* PAGE_SHIFT > IA32_PAGE_SHIFT */ - -asmlinkage long -sys32_mprotect (unsigned int start, unsigned int len, int prot) -{ - unsigned int end = start + len; -#if PAGE_SHIFT > IA32_PAGE_SHIFT - long retval = 0; -#endif - - prot = get_prot32(prot); - -#if PAGE_SHIFT <= IA32_PAGE_SHIFT - return sys_mprotect(start, end - start, prot); -#else - if (OFFSET4K(start)) - return -EINVAL; - - end = IA32_PAGE_ALIGN(end); - if (end < start) - return -EINVAL; - - retval = ia32_compare_pp(&start, &end); - - if (retval < 0) - return retval; - - mutex_lock(&ia32_mmap_mutex); - { - if (offset_in_page(start)) { - /* start address is 4KB aligned but not page aligned. */ - retval = mprotect_subpage(PAGE_START(start), prot); - if (retval < 0) - goto out; - - start = PAGE_ALIGN(start); - if (start >= end) - goto out; /* retval is already zero... */ - } - - if (offset_in_page(end)) { - /* end address is 4KB aligned but not page aligned. */ - retval = mprotect_subpage(PAGE_START(end), prot); - if (retval < 0) - goto out; - - end = PAGE_START(end); - } - retval = sys_mprotect(start, end - start, prot); - } - out: - mutex_unlock(&ia32_mmap_mutex); - return retval; -#endif -} - -asmlinkage long -sys32_mremap (unsigned int addr, unsigned int old_len, unsigned int new_len, - unsigned int flags, unsigned int new_addr) -{ - long ret; - -#if PAGE_SHIFT <= IA32_PAGE_SHIFT - ret = sys_mremap(addr, old_len, new_len, flags, new_addr); -#else - unsigned int old_end, new_end; - - if (OFFSET4K(addr)) - return -EINVAL; - - old_len = IA32_PAGE_ALIGN(old_len); - new_len = IA32_PAGE_ALIGN(new_len); - old_end = addr + old_len; - new_end = addr + new_len; - - if (!new_len) - return -EINVAL; - - if ((flags & MREMAP_FIXED) && (OFFSET4K(new_addr))) - return -EINVAL; - - if (old_len >= new_len) { - ret = sys32_munmap(addr + new_len, old_len - new_len); - if (ret && old_len != new_len) - return ret; - ret = addr; - if (!(flags & MREMAP_FIXED) || (new_addr == addr)) - return ret; - old_len = new_len; - } - - addr = PAGE_START(addr); - old_len = PAGE_ALIGN(old_end) - addr; - new_len = PAGE_ALIGN(new_end) - addr; - - mutex_lock(&ia32_mmap_mutex); - ret = sys_mremap(addr, old_len, new_len, flags, new_addr); - mutex_unlock(&ia32_mmap_mutex); - - if ((ret >= 0) && (old_len < new_len)) { - /* mremap expanded successfully */ - ia32_set_pp(old_end, new_end, flags); - } -#endif - return ret; -} - -asmlinkage unsigned long -sys32_alarm (unsigned int seconds) -{ - return alarm_setitimer(seconds); -} - -struct sel_arg_struct { - unsigned int n; - unsigned int inp; - unsigned int outp; - unsigned int exp; - unsigned int tvp; -}; - -asmlinkage long -sys32_old_select (struct sel_arg_struct __user *arg) -{ - struct sel_arg_struct a; - - if (copy_from_user(&a, arg, sizeof(a))) - return -EFAULT; - return compat_sys_select(a.n, compat_ptr(a.inp), compat_ptr(a.outp), - compat_ptr(a.exp), compat_ptr(a.tvp)); -} - -#define SEMOP 1 -#define SEMGET 2 -#define SEMCTL 3 -#define SEMTIMEDOP 4 -#define MSGSND 11 -#define MSGRCV 12 -#define MSGGET 13 -#define MSGCTL 14 -#define SHMAT 21 -#define SHMDT 22 -#define SHMGET 23 -#define SHMCTL 24 - -asmlinkage long -sys32_ipc(u32 call, int first, int second, int third, u32 ptr, u32 fifth) -{ - int version; - - version = call >> 16; /* hack for backward compatibility */ - call &= 0xffff; - - switch (call) { - case SEMTIMEDOP: - if (fifth) - return compat_sys_semtimedop(first, compat_ptr(ptr), - second, compat_ptr(fifth)); - /* else fall through for normal semop() */ - case SEMOP: - /* struct sembuf is the same on 32 and 64bit :)) */ - return sys_semtimedop(first, compat_ptr(ptr), second, - NULL); - case SEMGET: - return sys_semget(first, second, third); - case SEMCTL: - return compat_sys_semctl(first, second, third, compat_ptr(ptr)); - - case MSGSND: - return compat_sys_msgsnd(first, second, third, compat_ptr(ptr)); - case MSGRCV: - return compat_sys_msgrcv(first, second, fifth, third, version, compat_ptr(ptr)); - case MSGGET: - return sys_msgget((key_t) first, second); - case MSGCTL: - return compat_sys_msgctl(first, second, compat_ptr(ptr)); - - case SHMAT: - return compat_sys_shmat(first, second, third, version, compat_ptr(ptr)); - break; - case SHMDT: - return sys_shmdt(compat_ptr(ptr)); - case SHMGET: - return sys_shmget(first, (unsigned)second, third); - case SHMCTL: - return compat_sys_shmctl(first, second, compat_ptr(ptr)); - - default: - return -ENOSYS; - } - return -EINVAL; -} - -asmlinkage long -compat_sys_wait4 (compat_pid_t pid, compat_uint_t * stat_addr, int options, - struct compat_rusage *ru); - -asmlinkage long -sys32_waitpid (int pid, unsigned int *stat_addr, int options) -{ - return compat_sys_wait4(pid, stat_addr, options, NULL); -} - -/* - * The order in which registers are stored in the ptrace regs structure - */ -#define PT_EBX 0 -#define PT_ECX 1 -#define PT_EDX 2 -#define PT_ESI 3 -#define PT_EDI 4 -#define PT_EBP 5 -#define PT_EAX 6 -#define PT_DS 7 -#define PT_ES 8 -#define PT_FS 9 -#define PT_GS 10 -#define PT_ORIG_EAX 11 -#define PT_EIP 12 -#define PT_CS 13 -#define PT_EFL 14 -#define PT_UESP 15 -#define PT_SS 16 - -static unsigned int -getreg (struct task_struct *child, int regno) -{ - struct pt_regs *child_regs; - - child_regs = task_pt_regs(child); - switch (regno / sizeof(int)) { - case PT_EBX: return child_regs->r11; - case PT_ECX: return child_regs->r9; - case PT_EDX: return child_regs->r10; - case PT_ESI: return child_regs->r14; - case PT_EDI: return child_regs->r15; - case PT_EBP: return child_regs->r13; - case PT_EAX: return child_regs->r8; - case PT_ORIG_EAX: return child_regs->r1; /* see dispatch_to_ia32_handler() */ - case PT_EIP: return child_regs->cr_iip; - case PT_UESP: return child_regs->r12; - case PT_EFL: return child->thread.eflag; - case PT_DS: case PT_ES: case PT_FS: case PT_GS: case PT_SS: - return __USER_DS; - case PT_CS: return __USER_CS; - default: - printk(KERN_ERR "ia32.getreg(): unknown register %d\n", regno); - break; - } - return 0; -} - -static void -putreg (struct task_struct *child, int regno, unsigned int value) -{ - struct pt_regs *child_regs; - - child_regs = task_pt_regs(child); - switch (regno / sizeof(int)) { - case PT_EBX: child_regs->r11 = value; break; - case PT_ECX: child_regs->r9 = value; break; - case PT_EDX: child_regs->r10 = value; break; - case PT_ESI: child_regs->r14 = value; break; - case PT_EDI: child_regs->r15 = value; break; - case PT_EBP: child_regs->r13 = value; break; - case PT_EAX: child_regs->r8 = value; break; - case PT_ORIG_EAX: child_regs->r1 = value; break; - case PT_EIP: child_regs->cr_iip = value; break; - case PT_UESP: child_regs->r12 = value; break; - case PT_EFL: child->thread.eflag = value; break; - case PT_DS: case PT_ES: case PT_FS: case PT_GS: case PT_SS: - if (value != __USER_DS) - printk(KERN_ERR - "ia32.putreg: attempt to set invalid segment register %d = %x\n", - regno, value); - break; - case PT_CS: - if (value != __USER_CS) - printk(KERN_ERR - "ia32.putreg: attempt to set invalid segment register %d = %x\n", - regno, value); - break; - default: - printk(KERN_ERR "ia32.putreg: unknown register %d\n", regno); - break; - } -} - -static void -put_fpreg (int regno, struct _fpreg_ia32 __user *reg, struct pt_regs *ptp, - struct switch_stack *swp, int tos) -{ - struct _fpreg_ia32 *f; - char buf[32]; - - f = (struct _fpreg_ia32 *)(((unsigned long)buf + 15) & ~15); - if ((regno += tos) >= 8) - regno -= 8; - switch (regno) { - case 0: - ia64f2ia32f(f, &ptp->f8); - break; - case 1: - ia64f2ia32f(f, &ptp->f9); - break; - case 2: - ia64f2ia32f(f, &ptp->f10); - break; - case 3: - ia64f2ia32f(f, &ptp->f11); - break; - case 4: - case 5: - case 6: - case 7: - ia64f2ia32f(f, &swp->f12 + (regno - 4)); - break; - } - copy_to_user(reg, f, sizeof(*reg)); -} - -static void -get_fpreg (int regno, struct _fpreg_ia32 __user *reg, struct pt_regs *ptp, - struct switch_stack *swp, int tos) -{ - - if ((regno += tos) >= 8) - regno -= 8; - switch (regno) { - case 0: - copy_from_user(&ptp->f8, reg, sizeof(*reg)); - break; - case 1: - copy_from_user(&ptp->f9, reg, sizeof(*reg)); - break; - case 2: - copy_from_user(&ptp->f10, reg, sizeof(*reg)); - break; - case 3: - copy_from_user(&ptp->f11, reg, sizeof(*reg)); - break; - case 4: - case 5: - case 6: - case 7: - copy_from_user(&swp->f12 + (regno - 4), reg, sizeof(*reg)); - break; - } - return; -} - -int -save_ia32_fpstate (struct task_struct *tsk, struct ia32_user_i387_struct __user *save) -{ - struct switch_stack *swp; - struct pt_regs *ptp; - int i, tos; - - if (!access_ok(VERIFY_WRITE, save, sizeof(*save))) - return -EFAULT; - - __put_user(tsk->thread.fcr & 0xffff, &save->cwd); - __put_user(tsk->thread.fsr & 0xffff, &save->swd); - __put_user((tsk->thread.fsr>>16) & 0xffff, &save->twd); - __put_user(tsk->thread.fir, &save->fip); - __put_user((tsk->thread.fir>>32) & 0xffff, &save->fcs); - __put_user(tsk->thread.fdr, &save->foo); - __put_user((tsk->thread.fdr>>32) & 0xffff, &save->fos); - - /* - * Stack frames start with 16-bytes of temp space - */ - swp = (struct switch_stack *)(tsk->thread.ksp + 16); - ptp = task_pt_regs(tsk); - tos = (tsk->thread.fsr >> 11) & 7; - for (i = 0; i < 8; i++) - put_fpreg(i, &save->st_space[i], ptp, swp, tos); - return 0; -} - -static int -restore_ia32_fpstate (struct task_struct *tsk, struct ia32_user_i387_struct __user *save) -{ - struct switch_stack *swp; - struct pt_regs *ptp; - int i, tos; - unsigned int fsrlo, fsrhi, num32; - - if (!access_ok(VERIFY_READ, save, sizeof(*save))) - return(-EFAULT); - - __get_user(num32, (unsigned int __user *)&save->cwd); - tsk->thread.fcr = (tsk->thread.fcr & (~0x1f3f)) | (num32 & 0x1f3f); - __get_user(fsrlo, (unsigned int __user *)&save->swd); - __get_user(fsrhi, (unsigned int __user *)&save->twd); - num32 = (fsrhi << 16) | fsrlo; - tsk->thread.fsr = (tsk->thread.fsr & (~0xffffffff)) | num32; - __get_user(num32, (unsigned int __user *)&save->fip); - tsk->thread.fir = (tsk->thread.fir & (~0xffffffff)) | num32; - __get_user(num32, (unsigned int __user *)&save->foo); - tsk->thread.fdr = (tsk->thread.fdr & (~0xffffffff)) | num32; - - /* - * Stack frames start with 16-bytes of temp space - */ - swp = (struct switch_stack *)(tsk->thread.ksp + 16); - ptp = task_pt_regs(tsk); - tos = (tsk->thread.fsr >> 11) & 7; - for (i = 0; i < 8; i++) - get_fpreg(i, &save->st_space[i], ptp, swp, tos); - return 0; -} - -int -save_ia32_fpxstate (struct task_struct *tsk, struct ia32_user_fxsr_struct __user *save) -{ - struct switch_stack *swp; - struct pt_regs *ptp; - int i, tos; - unsigned long mxcsr=0; - unsigned long num128[2]; - - if (!access_ok(VERIFY_WRITE, save, sizeof(*save))) - return -EFAULT; - - __put_user(tsk->thread.fcr & 0xffff, &save->cwd); - __put_user(tsk->thread.fsr & 0xffff, &save->swd); - __put_user((tsk->thread.fsr>>16) & 0xffff, &save->twd); - __put_user(tsk->thread.fir, &save->fip); - __put_user((tsk->thread.fir>>32) & 0xffff, &save->fcs); - __put_user(tsk->thread.fdr, &save->foo); - __put_user((tsk->thread.fdr>>32) & 0xffff, &save->fos); - - /* - * Stack frames start with 16-bytes of temp space - */ - swp = (struct switch_stack *)(tsk->thread.ksp + 16); - ptp = task_pt_regs(tsk); - tos = (tsk->thread.fsr >> 11) & 7; - for (i = 0; i < 8; i++) - put_fpreg(i, (struct _fpreg_ia32 __user *)&save->st_space[4*i], ptp, swp, tos); - - mxcsr = ((tsk->thread.fcr>>32) & 0xff80) | ((tsk->thread.fsr>>32) & 0x3f); - __put_user(mxcsr & 0xffff, &save->mxcsr); - for (i = 0; i < 8; i++) { - memcpy(&(num128[0]), &(swp->f16) + i*2, sizeof(unsigned long)); - memcpy(&(num128[1]), &(swp->f17) + i*2, sizeof(unsigned long)); - copy_to_user(&save->xmm_space[0] + 4*i, num128, sizeof(struct _xmmreg_ia32)); - } - return 0; -} - -static int -restore_ia32_fpxstate (struct task_struct *tsk, struct ia32_user_fxsr_struct __user *save) -{ - struct switch_stack *swp; - struct pt_regs *ptp; - int i, tos; - unsigned int fsrlo, fsrhi, num32; - int mxcsr; - unsigned long num64; - unsigned long num128[2]; - - if (!access_ok(VERIFY_READ, save, sizeof(*save))) - return(-EFAULT); - - __get_user(num32, (unsigned int __user *)&save->cwd); - tsk->thread.fcr = (tsk->thread.fcr & (~0x1f3f)) | (num32 & 0x1f3f); - __get_user(fsrlo, (unsigned int __user *)&save->swd); - __get_user(fsrhi, (unsigned int __user *)&save->twd); - num32 = (fsrhi << 16) | fsrlo; - tsk->thread.fsr = (tsk->thread.fsr & (~0xffffffff)) | num32; - __get_user(num32, (unsigned int __user *)&save->fip); - tsk->thread.fir = (tsk->thread.fir & (~0xffffffff)) | num32; - __get_user(num32, (unsigned int __user *)&save->foo); - tsk->thread.fdr = (tsk->thread.fdr & (~0xffffffff)) | num32; - - /* - * Stack frames start with 16-bytes of temp space - */ - swp = (struct switch_stack *)(tsk->thread.ksp + 16); - ptp = task_pt_regs(tsk); - tos = (tsk->thread.fsr >> 11) & 7; - for (i = 0; i < 8; i++) - get_fpreg(i, (struct _fpreg_ia32 __user *)&save->st_space[4*i], ptp, swp, tos); - - __get_user(mxcsr, (unsigned int __user *)&save->mxcsr); - num64 = mxcsr & 0xff10; - tsk->thread.fcr = (tsk->thread.fcr & (~0xff1000000000UL)) | (num64<<32); - num64 = mxcsr & 0x3f; - tsk->thread.fsr = (tsk->thread.fsr & (~0x3f00000000UL)) | (num64<<32); - - for (i = 0; i < 8; i++) { - copy_from_user(num128, &save->xmm_space[0] + 4*i, sizeof(struct _xmmreg_ia32)); - memcpy(&(swp->f16) + i*2, &(num128[0]), sizeof(unsigned long)); - memcpy(&(swp->f17) + i*2, &(num128[1]), sizeof(unsigned long)); - } - return 0; -} - -long compat_arch_ptrace(struct task_struct *child, compat_long_t request, - compat_ulong_t caddr, compat_ulong_t cdata) -{ - unsigned long addr = caddr; - unsigned long data = cdata; - unsigned int tmp; - long i, ret; - - switch (request) { - case PTRACE_PEEKUSR: /* read word at addr in USER area */ - ret = -EIO; - if ((addr & 3) || addr > 17*sizeof(int)) - break; - - tmp = getreg(child, addr); - if (!put_user(tmp, (unsigned int __user *) compat_ptr(data))) - ret = 0; - break; - - case PTRACE_POKEUSR: /* write word at addr in USER area */ - ret = -EIO; - if ((addr & 3) || addr > 17*sizeof(int)) - break; - - putreg(child, addr, data); - ret = 0; - break; - - case IA32_PTRACE_GETREGS: - if (!access_ok(VERIFY_WRITE, compat_ptr(data), 17*sizeof(int))) { - ret = -EIO; - break; - } - for (i = 0; i < (int) (17*sizeof(int)); i += sizeof(int) ) { - put_user(getreg(child, i), (unsigned int __user *) compat_ptr(data)); - data += sizeof(int); - } - ret = 0; - break; - - case IA32_PTRACE_SETREGS: - if (!access_ok(VERIFY_READ, compat_ptr(data), 17*sizeof(int))) { - ret = -EIO; - break; - } - for (i = 0; i < (int) (17*sizeof(int)); i += sizeof(int) ) { - get_user(tmp, (unsigned int __user *) compat_ptr(data)); - putreg(child, i, tmp); - data += sizeof(int); - } - ret = 0; - break; - - case IA32_PTRACE_GETFPREGS: - ret = save_ia32_fpstate(child, (struct ia32_user_i387_struct __user *) - compat_ptr(data)); - break; - - case IA32_PTRACE_GETFPXREGS: - ret = save_ia32_fpxstate(child, (struct ia32_user_fxsr_struct __user *) - compat_ptr(data)); - break; - - case IA32_PTRACE_SETFPREGS: - ret = restore_ia32_fpstate(child, (struct ia32_user_i387_struct __user *) - compat_ptr(data)); - break; - - case IA32_PTRACE_SETFPXREGS: - ret = restore_ia32_fpxstate(child, (struct ia32_user_fxsr_struct __user *) - compat_ptr(data)); - break; - - default: - return compat_ptrace_request(child, request, caddr, cdata); - } - return ret; -} - -typedef struct { - unsigned int ss_sp; - unsigned int ss_flags; - unsigned int ss_size; -} ia32_stack_t; - -asmlinkage long -sys32_sigaltstack (ia32_stack_t __user *uss32, ia32_stack_t __user *uoss32, - long arg2, long arg3, long arg4, long arg5, long arg6, - long arg7, struct pt_regs pt) -{ - stack_t uss, uoss; - ia32_stack_t buf32; - int ret; - mm_segment_t old_fs = get_fs(); - - if (uss32) { - if (copy_from_user(&buf32, uss32, sizeof(ia32_stack_t))) - return -EFAULT; - uss.ss_sp = (void __user *) (long) buf32.ss_sp; - uss.ss_flags = buf32.ss_flags; - /* MINSIGSTKSZ is different for ia32 vs ia64. We lie here to pass the - check and set it to the user requested value later */ - if ((buf32.ss_flags != SS_DISABLE) && (buf32.ss_size < MINSIGSTKSZ_IA32)) { - ret = -ENOMEM; - goto out; - } - uss.ss_size = MINSIGSTKSZ; - } - set_fs(KERNEL_DS); - ret = do_sigaltstack(uss32 ? (stack_t __user *) &uss : NULL, - (stack_t __user *) &uoss, pt.r12); - current->sas_ss_size = buf32.ss_size; - set_fs(old_fs); -out: - if (ret < 0) - return(ret); - if (uoss32) { - buf32.ss_sp = (long __user) uoss.ss_sp; - buf32.ss_flags = uoss.ss_flags; - buf32.ss_size = uoss.ss_size; - if (copy_to_user(uoss32, &buf32, sizeof(ia32_stack_t))) - return -EFAULT; - } - return ret; -} - -asmlinkage int -sys32_msync (unsigned int start, unsigned int len, int flags) -{ - unsigned int addr; - - if (OFFSET4K(start)) - return -EINVAL; - addr = PAGE_START(start); - return sys_msync(addr, len + (start - addr), flags); -} - -asmlinkage long -sys32_newuname (struct new_utsname __user *name) -{ - int ret = sys_newuname(name); - - if (!ret) - if (copy_to_user(name->machine, "i686\0\0\0", 8)) - ret = -EFAULT; - return ret; -} - -asmlinkage long -sys32_getresuid16 (u16 __user *ruid, u16 __user *euid, u16 __user *suid) -{ - uid_t a, b, c; - int ret; - mm_segment_t old_fs = get_fs(); - - set_fs(KERNEL_DS); - ret = sys_getresuid((uid_t __user *) &a, (uid_t __user *) &b, (uid_t __user *) &c); - set_fs(old_fs); - - if (put_user(a, ruid) || put_user(b, euid) || put_user(c, suid)) - return -EFAULT; - return ret; -} - -asmlinkage long -sys32_getresgid16 (u16 __user *rgid, u16 __user *egid, u16 __user *sgid) -{ - gid_t a, b, c; - int ret; - mm_segment_t old_fs = get_fs(); - - set_fs(KERNEL_DS); - ret = sys_getresgid((gid_t __user *) &a, (gid_t __user *) &b, (gid_t __user *) &c); - set_fs(old_fs); - - if (ret) - return ret; - - return put_user(a, rgid) | put_user(b, egid) | put_user(c, sgid); -} - -asmlinkage long -sys32_lseek (unsigned int fd, int offset, unsigned int whence) -{ - /* Sign-extension of "offset" is important here... */ - return sys_lseek(fd, offset, whence); -} - -static int -groups16_to_user(short __user *grouplist, struct group_info *group_info) -{ - int i; - short group; - - for (i = 0; i < group_info->ngroups; i++) { - group = (short)GROUP_AT(group_info, i); - if (put_user(group, grouplist+i)) - return -EFAULT; - } - - return 0; -} - -static int -groups16_from_user(struct group_info *group_info, short __user *grouplist) -{ - int i; - short group; - - for (i = 0; i < group_info->ngroups; i++) { - if (get_user(group, grouplist+i)) - return -EFAULT; - GROUP_AT(group_info, i) = (gid_t)group; - } - - return 0; -} - -asmlinkage long -sys32_getgroups16 (int gidsetsize, short __user *grouplist) -{ - const struct cred *cred = current_cred(); - int i; - - if (gidsetsize < 0) - return -EINVAL; - - i = cred->group_info->ngroups; - if (gidsetsize) { - if (i > gidsetsize) { - i = -EINVAL; - goto out; - } - if (groups16_to_user(grouplist, cred->group_info)) { - i = -EFAULT; - goto out; - } - } -out: - return i; -} - -asmlinkage long -sys32_setgroups16 (int gidsetsize, short __user *grouplist) -{ - struct group_info *group_info; - int retval; - - if (!capable(CAP_SETGID)) - return -EPERM; - if ((unsigned)gidsetsize > NGROUPS_MAX) - return -EINVAL; - - group_info = groups_alloc(gidsetsize); - if (!group_info) - return -ENOMEM; - retval = groups16_from_user(group_info, grouplist); - if (retval) { - put_group_info(group_info); - return retval; - } - - retval = set_current_groups(group_info); - put_group_info(group_info); - - return retval; -} - -asmlinkage long -sys32_truncate64 (unsigned int path, unsigned int len_lo, unsigned int len_hi) -{ - return sys_truncate(compat_ptr(path), ((unsigned long) len_hi << 32) | len_lo); -} - -asmlinkage long -sys32_ftruncate64 (int fd, unsigned int len_lo, unsigned int len_hi) -{ - return sys_ftruncate(fd, ((unsigned long) len_hi << 32) | len_lo); -} - -static int -putstat64 (struct stat64 __user *ubuf, struct kstat *kbuf) -{ - int err; - u64 hdev; - - if (clear_user(ubuf, sizeof(*ubuf))) - return -EFAULT; - - hdev = huge_encode_dev(kbuf->dev); - err = __put_user(hdev, (u32 __user*)&ubuf->st_dev); - err |= __put_user(hdev >> 32, ((u32 __user*)&ubuf->st_dev) + 1); - err |= __put_user(kbuf->ino, &ubuf->__st_ino); - err |= __put_user(kbuf->ino, &ubuf->st_ino_lo); - err |= __put_user(kbuf->ino >> 32, &ubuf->st_ino_hi); - err |= __put_user(kbuf->mode, &ubuf->st_mode); - err |= __put_user(kbuf->nlink, &ubuf->st_nlink); - err |= __put_user(kbuf->uid, &ubuf->st_uid); - err |= __put_user(kbuf->gid, &ubuf->st_gid); - hdev = huge_encode_dev(kbuf->rdev); - err = __put_user(hdev, (u32 __user*)&ubuf->st_rdev); - err |= __put_user(hdev >> 32, ((u32 __user*)&ubuf->st_rdev) + 1); - err |= __put_user(kbuf->size, &ubuf->st_size_lo); - err |= __put_user((kbuf->size >> 32), &ubuf->st_size_hi); - err |= __put_user(kbuf->atime.tv_sec, &ubuf->st_atime); - err |= __put_user(kbuf->atime.tv_nsec, &ubuf->st_atime_nsec); - err |= __put_user(kbuf->mtime.tv_sec, &ubuf->st_mtime); - err |= __put_user(kbuf->mtime.tv_nsec, &ubuf->st_mtime_nsec); - err |= __put_user(kbuf->ctime.tv_sec, &ubuf->st_ctime); - err |= __put_user(kbuf->ctime.tv_nsec, &ubuf->st_ctime_nsec); - err |= __put_user(kbuf->blksize, &ubuf->st_blksize); - err |= __put_user(kbuf->blocks, &ubuf->st_blocks); - return err; -} - -asmlinkage long -sys32_stat64 (char __user *filename, struct stat64 __user *statbuf) -{ - struct kstat s; - long ret = vfs_stat(filename, &s); - if (!ret) - ret = putstat64(statbuf, &s); - return ret; -} - -asmlinkage long -sys32_lstat64 (char __user *filename, struct stat64 __user *statbuf) -{ - struct kstat s; - long ret = vfs_lstat(filename, &s); - if (!ret) - ret = putstat64(statbuf, &s); - return ret; -} - -asmlinkage long -sys32_fstat64 (unsigned int fd, struct stat64 __user *statbuf) -{ - struct kstat s; - long ret = vfs_fstat(fd, &s); - if (!ret) - ret = putstat64(statbuf, &s); - return ret; -} - -asmlinkage long -sys32_sched_rr_get_interval (pid_t pid, struct compat_timespec __user *interval) -{ - mm_segment_t old_fs = get_fs(); - struct timespec t; - long ret; - - set_fs(KERNEL_DS); - ret = sys_sched_rr_get_interval(pid, (struct timespec __user *) &t); - set_fs(old_fs); - if (put_compat_timespec(&t, interval)) - return -EFAULT; - return ret; -} - -asmlinkage long -sys32_pread (unsigned int fd, void __user *buf, unsigned int count, u32 pos_lo, u32 pos_hi) -{ - return sys_pread64(fd, buf, count, ((unsigned long) pos_hi << 32) | pos_lo); -} - -asmlinkage long -sys32_pwrite (unsigned int fd, void __user *buf, unsigned int count, u32 pos_lo, u32 pos_hi) -{ - return sys_pwrite64(fd, buf, count, ((unsigned long) pos_hi << 32) | pos_lo); -} - -asmlinkage long -sys32_sendfile (int out_fd, int in_fd, int __user *offset, unsigned int count) -{ - mm_segment_t old_fs = get_fs(); - long ret; - off_t of; - - if (offset && get_user(of, offset)) - return -EFAULT; - - set_fs(KERNEL_DS); - ret = sys_sendfile(out_fd, in_fd, offset ? (off_t __user *) &of : NULL, count); - set_fs(old_fs); - - if (offset && put_user(of, offset)) - return -EFAULT; - - return ret; -} - -asmlinkage long -sys32_personality (unsigned int personality) -{ - long ret; - - if (current->personality == PER_LINUX32 && personality == PER_LINUX) - personality = PER_LINUX32; - ret = sys_personality(personality); - if (ret == PER_LINUX32) - ret = PER_LINUX; - return ret; -} - -asmlinkage unsigned long -sys32_brk (unsigned int brk) -{ - unsigned long ret, obrk; - struct mm_struct *mm = current->mm; - - obrk = mm->brk; - ret = sys_brk(brk); - if (ret < obrk) - clear_user(compat_ptr(ret), PAGE_ALIGN(ret) - ret); - return ret; -} - -/* Structure for ia32 emulation on ia64 */ -struct epoll_event32 -{ - u32 events; - u32 data[2]; -}; - -asmlinkage long -sys32_epoll_ctl(int epfd, int op, int fd, struct epoll_event32 __user *event) -{ - mm_segment_t old_fs = get_fs(); - struct epoll_event event64; - int error; - u32 data_halfword; - - if (!access_ok(VERIFY_READ, event, sizeof(struct epoll_event32))) - return -EFAULT; - - __get_user(event64.events, &event->events); - __get_user(data_halfword, &event->data[0]); - event64.data = data_halfword; - __get_user(data_halfword, &event->data[1]); - event64.data |= (u64)data_halfword << 32; - - set_fs(KERNEL_DS); - error = sys_epoll_ctl(epfd, op, fd, (struct epoll_event __user *) &event64); - set_fs(old_fs); - - return error; -} - -asmlinkage long -sys32_epoll_wait(int epfd, struct epoll_event32 __user * events, int maxevents, - int timeout) -{ - struct epoll_event *events64 = NULL; - mm_segment_t old_fs = get_fs(); - int numevents, size; - int evt_idx; - int do_free_pages = 0; - - if (maxevents <= 0) { - return -EINVAL; - } - - /* Verify that the area passed by the user is writeable */ - if (!access_ok(VERIFY_WRITE, events, maxevents * sizeof(struct epoll_event32))) - return -EFAULT; - - /* - * Allocate space for the intermediate copy. If the space needed - * is large enough to cause kmalloc to fail, then try again with - * __get_free_pages. - */ - size = maxevents * sizeof(struct epoll_event); - events64 = kmalloc(size, GFP_KERNEL); - if (events64 == NULL) { - events64 = (struct epoll_event *) - __get_free_pages(GFP_KERNEL, get_order(size)); - if (events64 == NULL) - return -ENOMEM; - do_free_pages = 1; - } - - /* Do the system call */ - set_fs(KERNEL_DS); /* copy_to/from_user should work on kernel mem*/ - numevents = sys_epoll_wait(epfd, (struct epoll_event __user *) events64, - maxevents, timeout); - set_fs(old_fs); - - /* Don't modify userspace memory if we're returning an error */ - if (numevents > 0) { - /* Translate the 64-bit structures back into the 32-bit - structures */ - for (evt_idx = 0; evt_idx < numevents; evt_idx++) { - __put_user(events64[evt_idx].events, - &events[evt_idx].events); - __put_user((u32)events64[evt_idx].data, - &events[evt_idx].data[0]); - __put_user((u32)(events64[evt_idx].data >> 32), - &events[evt_idx].data[1]); - } - } - - if (do_free_pages) - free_pages((unsigned long) events64, get_order(size)); - else - kfree(events64); - return numevents; -} - -/* - * Get a yet unused TLS descriptor index. - */ -static int -get_free_idx (void) -{ - struct thread_struct *t = ¤t->thread; - int idx; - - for (idx = 0; idx < GDT_ENTRY_TLS_ENTRIES; idx++) - if (desc_empty(t->tls_array + idx)) - return idx + GDT_ENTRY_TLS_MIN; - return -ESRCH; -} - -static void set_tls_desc(struct task_struct *p, int idx, - const struct ia32_user_desc *info, int n) -{ - struct thread_struct *t = &p->thread; - struct desc_struct *desc = &t->tls_array[idx - GDT_ENTRY_TLS_MIN]; - int cpu; - - /* - * We must not get preempted while modifying the TLS. - */ - cpu = get_cpu(); - - while (n-- > 0) { - if (LDT_empty(info)) { - desc->a = 0; - desc->b = 0; - } else { - desc->a = LDT_entry_a(info); - desc->b = LDT_entry_b(info); - } - - ++info; - ++desc; - } - - if (t == ¤t->thread) - load_TLS(t, cpu); - - put_cpu(); -} - -/* - * Set a given TLS descriptor: - */ -asmlinkage int -sys32_set_thread_area (struct ia32_user_desc __user *u_info) -{ - struct ia32_user_desc info; - int idx; - - if (copy_from_user(&info, u_info, sizeof(info))) - return -EFAULT; - idx = info.entry_number; - - /* - * index -1 means the kernel should try to find and allocate an empty descriptor: - */ - if (idx == -1) { - idx = get_free_idx(); - if (idx < 0) - return idx; - if (put_user(idx, &u_info->entry_number)) - return -EFAULT; - } - - if (idx < GDT_ENTRY_TLS_MIN || idx > GDT_ENTRY_TLS_MAX) - return -EINVAL; - - set_tls_desc(current, idx, &info, 1); - return 0; -} - -/* - * Get the current Thread-Local Storage area: - */ - -#define GET_BASE(desc) ( \ - (((desc)->a >> 16) & 0x0000ffff) | \ - (((desc)->b << 16) & 0x00ff0000) | \ - ( (desc)->b & 0xff000000) ) - -#define GET_LIMIT(desc) ( \ - ((desc)->a & 0x0ffff) | \ - ((desc)->b & 0xf0000) ) - -#define GET_32BIT(desc) (((desc)->b >> 22) & 1) -#define GET_CONTENTS(desc) (((desc)->b >> 10) & 3) -#define GET_WRITABLE(desc) (((desc)->b >> 9) & 1) -#define GET_LIMIT_PAGES(desc) (((desc)->b >> 23) & 1) -#define GET_PRESENT(desc) (((desc)->b >> 15) & 1) -#define GET_USEABLE(desc) (((desc)->b >> 20) & 1) - -static void fill_user_desc(struct ia32_user_desc *info, int idx, - const struct desc_struct *desc) -{ - info->entry_number = idx; - info->base_addr = GET_BASE(desc); - info->limit = GET_LIMIT(desc); - info->seg_32bit = GET_32BIT(desc); - info->contents = GET_CONTENTS(desc); - info->read_exec_only = !GET_WRITABLE(desc); - info->limit_in_pages = GET_LIMIT_PAGES(desc); - info->seg_not_present = !GET_PRESENT(desc); - info->useable = GET_USEABLE(desc); -} - -asmlinkage int -sys32_get_thread_area (struct ia32_user_desc __user *u_info) -{ - struct ia32_user_desc info; - struct desc_struct *desc; - int idx; - - if (get_user(idx, &u_info->entry_number)) - return -EFAULT; - if (idx < GDT_ENTRY_TLS_MIN || idx > GDT_ENTRY_TLS_MAX) - return -EINVAL; - - desc = current->thread.tls_array + idx - GDT_ENTRY_TLS_MIN; - fill_user_desc(&info, idx, desc); - - if (copy_to_user(u_info, &info, sizeof(info))) - return -EFAULT; - return 0; -} - -struct regset_get { - void *kbuf; - void __user *ubuf; -}; - -struct regset_set { - const void *kbuf; - const void __user *ubuf; -}; - -struct regset_getset { - struct task_struct *target; - const struct user_regset *regset; - union { - struct regset_get get; - struct regset_set set; - } u; - unsigned int pos; - unsigned int count; - int ret; -}; - -static void getfpreg(struct task_struct *task, int regno, int *val) -{ - switch (regno / sizeof(int)) { - case 0: - *val = task->thread.fcr & 0xffff; - break; - case 1: - *val = task->thread.fsr & 0xffff; - break; - case 2: - *val = (task->thread.fsr>>16) & 0xffff; - break; - case 3: - *val = task->thread.fir; - break; - case 4: - *val = (task->thread.fir>>32) & 0xffff; - break; - case 5: - *val = task->thread.fdr; - break; - case 6: - *val = (task->thread.fdr >> 32) & 0xffff; - break; - } -} - -static void setfpreg(struct task_struct *task, int regno, int val) -{ - switch (regno / sizeof(int)) { - case 0: - task->thread.fcr = (task->thread.fcr & (~0x1f3f)) - | (val & 0x1f3f); - break; - case 1: - task->thread.fsr = (task->thread.fsr & (~0xffff)) | val; - break; - case 2: - task->thread.fsr = (task->thread.fsr & (~0xffff0000)) - | (val << 16); - break; - case 3: - task->thread.fir = (task->thread.fir & (~0xffffffff)) | val; - break; - case 5: - task->thread.fdr = (task->thread.fdr & (~0xffffffff)) | val; - break; - } -} - -static void access_fpreg_ia32(int regno, void *reg, - struct pt_regs *pt, struct switch_stack *sw, - int tos, int write) -{ - void *f; - - if ((regno += tos) >= 8) - regno -= 8; - if (regno < 4) - f = &pt->f8 + regno; - else if (regno <= 7) - f = &sw->f12 + (regno - 4); - else { - printk(KERN_ERR "regno must be less than 7 \n"); - return; - } - - if (write) - memcpy(f, reg, sizeof(struct _fpreg_ia32)); - else - memcpy(reg, f, sizeof(struct _fpreg_ia32)); -} - -static void do_fpregs_get(struct unw_frame_info *info, void *arg) -{ - struct regset_getset *dst = arg; - struct task_struct *task = dst->target; - struct pt_regs *pt; - int start, end, tos; - char buf[80]; - - if (dst->count == 0 || unw_unwind_to_user(info) < 0) - return; - if (dst->pos < 7 * sizeof(int)) { - end = min((dst->pos + dst->count), - (unsigned int)(7 * sizeof(int))); - for (start = dst->pos; start < end; start += sizeof(int)) - getfpreg(task, start, (int *)(buf + start)); - dst->ret = user_regset_copyout(&dst->pos, &dst->count, - &dst->u.get.kbuf, &dst->u.get.ubuf, buf, - 0, 7 * sizeof(int)); - if (dst->ret || dst->count == 0) - return; - } - if (dst->pos < sizeof(struct ia32_user_i387_struct)) { - pt = task_pt_regs(task); - tos = (task->thread.fsr >> 11) & 7; - end = min(dst->pos + dst->count, - (unsigned int)(sizeof(struct ia32_user_i387_struct))); - start = (dst->pos - 7 * sizeof(int)) / - sizeof(struct _fpreg_ia32); - end = (end - 7 * sizeof(int)) / sizeof(struct _fpreg_ia32); - for (; start < end; start++) - access_fpreg_ia32(start, - (struct _fpreg_ia32 *)buf + start, - pt, info->sw, tos, 0); - dst->ret = user_regset_copyout(&dst->pos, &dst->count, - &dst->u.get.kbuf, &dst->u.get.ubuf, - buf, 7 * sizeof(int), - sizeof(struct ia32_user_i387_struct)); - if (dst->ret || dst->count == 0) - return; - } -} - -static void do_fpregs_set(struct unw_frame_info *info, void *arg) -{ - struct regset_getset *dst = arg; - struct task_struct *task = dst->target; - struct pt_regs *pt; - char buf[80]; - int end, start, tos; - - if (dst->count == 0 || unw_unwind_to_user(info) < 0) - return; - - if (dst->pos < 7 * sizeof(int)) { - start = dst->pos; - dst->ret = user_regset_copyin(&dst->pos, &dst->count, - &dst->u.set.kbuf, &dst->u.set.ubuf, buf, - 0, 7 * sizeof(int)); - if (dst->ret) - return; - for (; start < dst->pos; start += sizeof(int)) - setfpreg(task, start, *((int *)(buf + start))); - if (dst->count == 0) - return; - } - if (dst->pos < sizeof(struct ia32_user_i387_struct)) { - start = (dst->pos - 7 * sizeof(int)) / - sizeof(struct _fpreg_ia32); - dst->ret = user_regset_copyin(&dst->pos, &dst->count, - &dst->u.set.kbuf, &dst->u.set.ubuf, - buf, 7 * sizeof(int), - sizeof(struct ia32_user_i387_struct)); - if (dst->ret) - return; - pt = task_pt_regs(task); - tos = (task->thread.fsr >> 11) & 7; - end = (dst->pos - 7 * sizeof(int)) / sizeof(struct _fpreg_ia32); - for (; start < end; start++) - access_fpreg_ia32(start, - (struct _fpreg_ia32 *)buf + start, - pt, info->sw, tos, 1); - if (dst->count == 0) - return; - } -} - -#define OFFSET(member) ((int)(offsetof(struct ia32_user_fxsr_struct, member))) -static void getfpxreg(struct task_struct *task, int start, int end, char *buf) -{ - int min_val; - - min_val = min(end, OFFSET(fop)); - while (start < min_val) { - if (start == OFFSET(cwd)) - *((short *)buf) = task->thread.fcr & 0xffff; - else if (start == OFFSET(swd)) - *((short *)buf) = task->thread.fsr & 0xffff; - else if (start == OFFSET(twd)) - *((short *)buf) = (task->thread.fsr>>16) & 0xffff; - buf += 2; - start += 2; - } - /* skip fop element */ - if (start == OFFSET(fop)) { - start += 2; - buf += 2; - } - while (start < end) { - if (start == OFFSET(fip)) - *((int *)buf) = task->thread.fir; - else if (start == OFFSET(fcs)) - *((int *)buf) = (task->thread.fir>>32) & 0xffff; - else if (start == OFFSET(foo)) - *((int *)buf) = task->thread.fdr; - else if (start == OFFSET(fos)) - *((int *)buf) = (task->thread.fdr>>32) & 0xffff; - else if (start == OFFSET(mxcsr)) - *((int *)buf) = ((task->thread.fcr>>32) & 0xff80) - | ((task->thread.fsr>>32) & 0x3f); - buf += 4; - start += 4; - } -} - -static void setfpxreg(struct task_struct *task, int start, int end, char *buf) -{ - int min_val, num32; - short num; - unsigned long num64; - - min_val = min(end, OFFSET(fop)); - while (start < min_val) { - num = *((short *)buf); - if (start == OFFSET(cwd)) { - task->thread.fcr = (task->thread.fcr & (~0x1f3f)) - | (num & 0x1f3f); - } else if (start == OFFSET(swd)) { - task->thread.fsr = (task->thread.fsr & (~0xffff)) | num; - } else if (start == OFFSET(twd)) { - task->thread.fsr = (task->thread.fsr & (~0xffff0000)) - | (((int)num) << 16); - } - buf += 2; - start += 2; - } - /* skip fop element */ - if (start == OFFSET(fop)) { - start += 2; - buf += 2; - } - while (start < end) { - num32 = *((int *)buf); - if (start == OFFSET(fip)) - task->thread.fir = (task->thread.fir & (~0xffffffff)) - | num32; - else if (start == OFFSET(foo)) - task->thread.fdr = (task->thread.fdr & (~0xffffffff)) - | num32; - else if (start == OFFSET(mxcsr)) { - num64 = num32 & 0xff10; - task->thread.fcr = (task->thread.fcr & - (~0xff1000000000UL)) | (num64<<32); - num64 = num32 & 0x3f; - task->thread.fsr = (task->thread.fsr & - (~0x3f00000000UL)) | (num64<<32); - } - buf += 4; - start += 4; - } -} - -static void do_fpxregs_get(struct unw_frame_info *info, void *arg) -{ - struct regset_getset *dst = arg; - struct task_struct *task = dst->target; - struct pt_regs *pt; - char buf[128]; - int start, end, tos; - - if (dst->count == 0 || unw_unwind_to_user(info) < 0) - return; - if (dst->pos < OFFSET(st_space[0])) { - end = min(dst->pos + dst->count, (unsigned int)32); - getfpxreg(task, dst->pos, end, buf); - dst->ret = user_regset_copyout(&dst->pos, &dst->count, - &dst->u.get.kbuf, &dst->u.get.ubuf, buf, - 0, OFFSET(st_space[0])); - if (dst->ret || dst->count == 0) - return; - } - if (dst->pos < OFFSET(xmm_space[0])) { - pt = task_pt_regs(task); - tos = (task->thread.fsr >> 11) & 7; - end = min(dst->pos + dst->count, - (unsigned int)OFFSET(xmm_space[0])); - start = (dst->pos - OFFSET(st_space[0])) / 16; - end = (end - OFFSET(st_space[0])) / 16; - for (; start < end; start++) - access_fpreg_ia32(start, buf + 16 * start, pt, - info->sw, tos, 0); - dst->ret = user_regset_copyout(&dst->pos, &dst->count, - &dst->u.get.kbuf, &dst->u.get.ubuf, - buf, OFFSET(st_space[0]), OFFSET(xmm_space[0])); - if (dst->ret || dst->count == 0) - return; - } - if (dst->pos < OFFSET(padding[0])) - dst->ret = user_regset_copyout(&dst->pos, &dst->count, - &dst->u.get.kbuf, &dst->u.get.ubuf, - &info->sw->f16, OFFSET(xmm_space[0]), - OFFSET(padding[0])); -} - -static void do_fpxregs_set(struct unw_frame_info *info, void *arg) -{ - struct regset_getset *dst = arg; - struct task_struct *task = dst->target; - char buf[128]; - int start, end; - - if (dst->count == 0 || unw_unwind_to_user(info) < 0) - return; - - if (dst->pos < OFFSET(st_space[0])) { - start = dst->pos; - dst->ret = user_regset_copyin(&dst->pos, &dst->count, - &dst->u.set.kbuf, &dst->u.set.ubuf, - buf, 0, OFFSET(st_space[0])); - if (dst->ret) - return; - setfpxreg(task, start, dst->pos, buf); - if (dst->count == 0) - return; - } - if (dst->pos < OFFSET(xmm_space[0])) { - struct pt_regs *pt; - int tos; - pt = task_pt_regs(task); - tos = (task->thread.fsr >> 11) & 7; - start = (dst->pos - OFFSET(st_space[0])) / 16; - dst->ret = user_regset_copyin(&dst->pos, &dst->count, - &dst->u.set.kbuf, &dst->u.set.ubuf, - buf, OFFSET(st_space[0]), OFFSET(xmm_space[0])); - if (dst->ret) - return; - end = (dst->pos - OFFSET(st_space[0])) / 16; - for (; start < end; start++) - access_fpreg_ia32(start, buf + 16 * start, pt, info->sw, - tos, 1); - if (dst->count == 0) - return; - } - if (dst->pos < OFFSET(padding[0])) - dst->ret = user_regset_copyin(&dst->pos, &dst->count, - &dst->u.set.kbuf, &dst->u.set.ubuf, - &info->sw->f16, OFFSET(xmm_space[0]), - OFFSET(padding[0])); -} -#undef OFFSET - -static int do_regset_call(void (*call)(struct unw_frame_info *, void *), - struct task_struct *target, - const struct user_regset *regset, - unsigned int pos, unsigned int count, - const void *kbuf, const void __user *ubuf) -{ - struct regset_getset info = { .target = target, .regset = regset, - .pos = pos, .count = count, - .u.set = { .kbuf = kbuf, .ubuf = ubuf }, - .ret = 0 }; - - if (target == current) - unw_init_running(call, &info); - else { - struct unw_frame_info ufi; - memset(&ufi, 0, sizeof(ufi)); - unw_init_from_blocked_task(&ufi, target); - (*call)(&ufi, &info); - } - - return info.ret; -} - -static int ia32_fpregs_get(struct task_struct *target, - const struct user_regset *regset, - unsigned int pos, unsigned int count, - void *kbuf, void __user *ubuf) -{ - return do_regset_call(do_fpregs_get, target, regset, pos, count, - kbuf, ubuf); -} - -static int ia32_fpregs_set(struct task_struct *target, - const struct user_regset *regset, - unsigned int pos, unsigned int count, - const void *kbuf, const void __user *ubuf) -{ - return do_regset_call(do_fpregs_set, target, regset, pos, count, - kbuf, ubuf); -} - -static int ia32_fpxregs_get(struct task_struct *target, - const struct user_regset *regset, - unsigned int pos, unsigned int count, - void *kbuf, void __user *ubuf) -{ - return do_regset_call(do_fpxregs_get, target, regset, pos, count, - kbuf, ubuf); -} - -static int ia32_fpxregs_set(struct task_struct *target, - const struct user_regset *regset, - unsigned int pos, unsigned int count, - const void *kbuf, const void __user *ubuf) -{ - return do_regset_call(do_fpxregs_set, target, regset, pos, count, - kbuf, ubuf); -} - -static int ia32_genregs_get(struct task_struct *target, - const struct user_regset *regset, - unsigned int pos, unsigned int count, - void *kbuf, void __user *ubuf) -{ - if (kbuf) { - u32 *kp = kbuf; - while (count > 0) { - *kp++ = getreg(target, pos); - pos += 4; - count -= 4; - } - } else { - u32 __user *up = ubuf; - while (count > 0) { - if (__put_user(getreg(target, pos), up++)) - return -EFAULT; - pos += 4; - count -= 4; - } - } - return 0; -} - -static int ia32_genregs_set(struct task_struct *target, - const struct user_regset *regset, - unsigned int pos, unsigned int count, - const void *kbuf, const void __user *ubuf) -{ - int ret = 0; - - if (kbuf) { - const u32 *kp = kbuf; - while (!ret && count > 0) { - putreg(target, pos, *kp++); - pos += 4; - count -= 4; - } - } else { - const u32 __user *up = ubuf; - u32 val; - while (!ret && count > 0) { - ret = __get_user(val, up++); - if (!ret) - putreg(target, pos, val); - pos += 4; - count -= 4; - } - } - return ret; -} - -static int ia32_tls_active(struct task_struct *target, - const struct user_regset *regset) -{ - struct thread_struct *t = &target->thread; - int n = GDT_ENTRY_TLS_ENTRIES; - while (n > 0 && desc_empty(&t->tls_array[n -1])) - --n; - return n; -} - -static int ia32_tls_get(struct task_struct *target, - const struct user_regset *regset, unsigned int pos, - unsigned int count, void *kbuf, void __user *ubuf) -{ - const struct desc_struct *tls; - - if (pos > GDT_ENTRY_TLS_ENTRIES * sizeof(struct ia32_user_desc) || - (pos % sizeof(struct ia32_user_desc)) != 0 || - (count % sizeof(struct ia32_user_desc)) != 0) - return -EINVAL; - - pos /= sizeof(struct ia32_user_desc); - count /= sizeof(struct ia32_user_desc); - - tls = &target->thread.tls_array[pos]; - - if (kbuf) { - struct ia32_user_desc *info = kbuf; - while (count-- > 0) - fill_user_desc(info++, GDT_ENTRY_TLS_MIN + pos++, - tls++); - } else { - struct ia32_user_desc __user *u_info = ubuf; - while (count-- > 0) { - struct ia32_user_desc info; - fill_user_desc(&info, GDT_ENTRY_TLS_MIN + pos++, tls++); - if (__copy_to_user(u_info++, &info, sizeof(info))) - return -EFAULT; - } - } - - return 0; -} - -static int ia32_tls_set(struct task_struct *target, - const struct user_regset *regset, unsigned int pos, - unsigned int count, const void *kbuf, const void __user *ubuf) -{ - struct ia32_user_desc infobuf[GDT_ENTRY_TLS_ENTRIES]; - const struct ia32_user_desc *info; - - if (pos > GDT_ENTRY_TLS_ENTRIES * sizeof(struct ia32_user_desc) || - (pos % sizeof(struct ia32_user_desc)) != 0 || - (count % sizeof(struct ia32_user_desc)) != 0) - return -EINVAL; - - if (kbuf) - info = kbuf; - else if (__copy_from_user(infobuf, ubuf, count)) - return -EFAULT; - else - info = infobuf; - - set_tls_desc(target, - GDT_ENTRY_TLS_MIN + (pos / sizeof(struct ia32_user_desc)), - info, count / sizeof(struct ia32_user_desc)); - - return 0; -} - -/* - * This should match arch/i386/kernel/ptrace.c:native_regsets. - * XXX ioperm? vm86? - */ -static const struct user_regset ia32_regsets[] = { - { - .core_note_type = NT_PRSTATUS, - .n = sizeof(struct user_regs_struct32)/4, - .size = 4, .align = 4, - .get = ia32_genregs_get, .set = ia32_genregs_set - }, - { - .core_note_type = NT_PRFPREG, - .n = sizeof(struct ia32_user_i387_struct) / 4, - .size = 4, .align = 4, - .get = ia32_fpregs_get, .set = ia32_fpregs_set - }, - { - .core_note_type = NT_PRXFPREG, - .n = sizeof(struct ia32_user_fxsr_struct) / 4, - .size = 4, .align = 4, - .get = ia32_fpxregs_get, .set = ia32_fpxregs_set - }, - { - .core_note_type = NT_386_TLS, - .n = GDT_ENTRY_TLS_ENTRIES, - .bias = GDT_ENTRY_TLS_MIN, - .size = sizeof(struct ia32_user_desc), - .align = sizeof(struct ia32_user_desc), - .active = ia32_tls_active, - .get = ia32_tls_get, .set = ia32_tls_set, - }, -}; - -const struct user_regset_view user_ia32_view = { - .name = "i386", .e_machine = EM_386, - .regsets = ia32_regsets, .n = ARRAY_SIZE(ia32_regsets) -}; - -long sys32_fadvise64_64(int fd, __u32 offset_low, __u32 offset_high, - __u32 len_low, __u32 len_high, int advice) -{ - return sys_fadvise64_64(fd, - (((u64)offset_high)<<32) | offset_low, - (((u64)len_high)<<32) | len_low, - advice); -} - -#ifdef NOTYET /* UNTESTED FOR IA64 FROM HERE DOWN */ - -asmlinkage long sys32_setreuid(compat_uid_t ruid, compat_uid_t euid) -{ - uid_t sruid, seuid; - - sruid = (ruid == (compat_uid_t)-1) ? ((uid_t)-1) : ((uid_t)ruid); - seuid = (euid == (compat_uid_t)-1) ? ((uid_t)-1) : ((uid_t)euid); - return sys_setreuid(sruid, seuid); -} - -asmlinkage long -sys32_setresuid(compat_uid_t ruid, compat_uid_t euid, - compat_uid_t suid) -{ - uid_t sruid, seuid, ssuid; - - sruid = (ruid == (compat_uid_t)-1) ? ((uid_t)-1) : ((uid_t)ruid); - seuid = (euid == (compat_uid_t)-1) ? ((uid_t)-1) : ((uid_t)euid); - ssuid = (suid == (compat_uid_t)-1) ? ((uid_t)-1) : ((uid_t)suid); - return sys_setresuid(sruid, seuid, ssuid); -} - -asmlinkage long -sys32_setregid(compat_gid_t rgid, compat_gid_t egid) -{ - gid_t srgid, segid; - - srgid = (rgid == (compat_gid_t)-1) ? ((gid_t)-1) : ((gid_t)rgid); - segid = (egid == (compat_gid_t)-1) ? ((gid_t)-1) : ((gid_t)egid); - return sys_setregid(srgid, segid); -} - -asmlinkage long -sys32_setresgid(compat_gid_t rgid, compat_gid_t egid, - compat_gid_t sgid) -{ - gid_t srgid, segid, ssgid; - - srgid = (rgid == (compat_gid_t)-1) ? ((gid_t)-1) : ((gid_t)rgid); - segid = (egid == (compat_gid_t)-1) ? ((gid_t)-1) : ((gid_t)egid); - ssgid = (sgid == (compat_gid_t)-1) ? ((gid_t)-1) : ((gid_t)sgid); - return sys_setresgid(srgid, segid, ssgid); -} -#endif /* NOTYET */ diff --git a/arch/ia64/include/asm/ia32.h b/arch/ia64/include/asm/ia32.h deleted file mode 100644 index 2390ee145aa1..000000000000 --- a/arch/ia64/include/asm/ia32.h +++ /dev/null @@ -1,40 +0,0 @@ -#ifndef _ASM_IA64_IA32_H -#define _ASM_IA64_IA32_H - - -#include -#include - -#define IA32_NR_syscalls 285 /* length of syscall table */ -#define IA32_PAGE_SHIFT 12 /* 4KB pages */ - -#ifndef __ASSEMBLY__ - -# ifdef CONFIG_IA32_SUPPORT - -#define IA32_PAGE_OFFSET 0xc0000000 - -extern void ia32_cpu_init (void); -extern void ia32_mem_init (void); -extern void ia32_gdt_init (void); -extern int ia32_exception (struct pt_regs *regs, unsigned long isr); -extern int ia32_intercept (struct pt_regs *regs, unsigned long isr); -extern int ia32_clone_tls (struct task_struct *child, struct pt_regs *childregs); - -# endif /* !CONFIG_IA32_SUPPORT */ - -/* Declare this unconditionally, so we don't get warnings for unreachable code. */ -extern int ia32_setup_frame1 (int sig, struct k_sigaction *ka, siginfo_t *info, - sigset_t *set, struct pt_regs *regs); -#if PAGE_SHIFT > IA32_PAGE_SHIFT -extern int ia32_copy_ia64_partial_page_list(struct task_struct *, - unsigned long); -extern void ia32_drop_ia64_partial_page_list(struct task_struct *); -#else -# define ia32_copy_ia64_partial_page_list(a1, a2) 0 -# define ia32_drop_ia64_partial_page_list(a1) do { ; } while (0) -#endif - -#endif /* !__ASSEMBLY__ */ - -#endif /* _ASM_IA64_IA32_H */ diff --git a/arch/ia64/include/asm/processor.h b/arch/ia64/include/asm/processor.h index 7fa90f73f6be..348e44d08ce3 100644 --- a/arch/ia64/include/asm/processor.h +++ b/arch/ia64/include/asm/processor.h @@ -270,23 +270,6 @@ typedef struct { (int __user *) (addr)); \ }) -#ifdef CONFIG_IA32_SUPPORT -struct desc_struct { - unsigned int a, b; -}; - -#define desc_empty(desc) (!((desc)->a | (desc)->b)) -#define desc_equal(desc1, desc2) (((desc1)->a == (desc2)->a) && ((desc1)->b == (desc2)->b)) - -#define GDT_ENTRY_TLS_ENTRIES 3 -#define GDT_ENTRY_TLS_MIN 6 -#define GDT_ENTRY_TLS_MAX (GDT_ENTRY_TLS_MIN + GDT_ENTRY_TLS_ENTRIES - 1) - -#define TLS_SIZE (GDT_ENTRY_TLS_ENTRIES * 8) - -struct ia64_partial_page_list; -#endif - struct thread_struct { __u32 flags; /* various thread flags (see IA64_THREAD_*) */ /* writing on_ustack is performance-critical, so it's worth spending 8 bits on it... */ @@ -298,29 +281,6 @@ struct thread_struct { __u64 rbs_bot; /* the base address for the RBS */ int last_fph_cpu; /* CPU that may hold the contents of f32-f127 */ -#ifdef CONFIG_IA32_SUPPORT - __u64 eflag; /* IA32 EFLAGS reg */ - __u64 fsr; /* IA32 floating pt status reg */ - __u64 fcr; /* IA32 floating pt control reg */ - __u64 fir; /* IA32 fp except. instr. reg */ - __u64 fdr; /* IA32 fp except. data reg */ - __u64 old_k1; /* old value of ar.k1 */ - __u64 old_iob; /* old IOBase value */ - struct ia64_partial_page_list *ppl; /* partial page list for 4K page size issue */ - /* cached TLS descriptors. */ - struct desc_struct tls_array[GDT_ENTRY_TLS_ENTRIES]; - -# define INIT_THREAD_IA32 .eflag = 0, \ - .fsr = 0, \ - .fcr = 0x17800000037fULL, \ - .fir = 0, \ - .fdr = 0, \ - .old_k1 = 0, \ - .old_iob = 0, \ - .ppl = NULL, -#else -# define INIT_THREAD_IA32 -#endif /* CONFIG_IA32_SUPPORT */ #ifdef CONFIG_PERFMON void *pfm_context; /* pointer to detailed PMU context */ unsigned long pfm_needs_checking; /* when >0, pending perfmon work on kernel exit */ @@ -342,7 +302,6 @@ struct thread_struct { .rbs_bot = STACK_TOP - DEFAULT_USER_STACK_SIZE, \ .task_size = DEFAULT_TASK_SIZE, \ .last_fph_cpu = -1, \ - INIT_THREAD_IA32 \ INIT_THREAD_PM \ .dbr = {0, }, \ .ibr = {0, }, \ @@ -485,11 +444,6 @@ extern void __ia64_load_fpu (struct ia64_fpreg *fph); extern void ia64_save_debug_regs (unsigned long *save_area); extern void ia64_load_debug_regs (unsigned long *save_area); -#ifdef CONFIG_IA32_SUPPORT -extern void ia32_save_state (struct task_struct *task); -extern void ia32_load_state (struct task_struct *task); -#endif - #define ia64_fph_enable() do { ia64_rsm(IA64_PSR_DFH); ia64_srlz_d(); } while (0) #define ia64_fph_disable() do { ia64_ssm(IA64_PSR_DFH); ia64_srlz_d(); } while (0) diff --git a/arch/ia64/include/asm/syscall.h b/arch/ia64/include/asm/syscall.h index 2f758a42f94b..a7ff1c6ab068 100644 --- a/arch/ia64/include/asm/syscall.h +++ b/arch/ia64/include/asm/syscall.h @@ -22,33 +22,18 @@ static inline long syscall_get_nr(struct task_struct *task, if ((long)regs->cr_ifs < 0) /* Not a syscall */ return -1; -#ifdef CONFIG_IA32_SUPPORT - if (IS_IA32_PROCESS(regs)) - return regs->r1; -#endif - return regs->r15; } static inline void syscall_rollback(struct task_struct *task, struct pt_regs *regs) { -#ifdef CONFIG_IA32_SUPPORT - if (IS_IA32_PROCESS(regs)) - regs->r8 = regs->r1; -#endif - /* do nothing */ } static inline long syscall_get_error(struct task_struct *task, struct pt_regs *regs) { -#ifdef CONFIG_IA32_SUPPORT - if (IS_IA32_PROCESS(regs)) - return regs->r8; -#endif - return regs->r10 == -1 ? regs->r8:0; } @@ -62,13 +47,6 @@ static inline void syscall_set_return_value(struct task_struct *task, struct pt_regs *regs, int error, long val) { -#ifdef CONFIG_IA32_SUPPORT - if (IS_IA32_PROCESS(regs)) { - regs->r8 = (long) error ? error : val; - return; - } -#endif - if (error) { /* error < 0, but ia64 uses > 0 return value */ regs->r8 = -error; @@ -89,37 +67,6 @@ static inline void syscall_get_arguments(struct task_struct *task, { BUG_ON(i + n > 6); -#ifdef CONFIG_IA32_SUPPORT - if (IS_IA32_PROCESS(regs)) { - switch (i + n) { - case 6: - if (!n--) break; - *args++ = regs->r13; - case 5: - if (!n--) break; - *args++ = regs->r15; - case 4: - if (!n--) break; - *args++ = regs->r14; - case 3: - if (!n--) break; - *args++ = regs->r10; - case 2: - if (!n--) break; - *args++ = regs->r9; - case 1: - if (!n--) break; - *args++ = regs->r11; - case 0: - if (!n--) break; - default: - BUG(); - break; - } - - return; - } -#endif ia64_syscall_get_set_arguments(task, regs, i, n, args, 0); } @@ -130,34 +77,6 @@ static inline void syscall_set_arguments(struct task_struct *task, { BUG_ON(i + n > 6); -#ifdef CONFIG_IA32_SUPPORT - if (IS_IA32_PROCESS(regs)) { - switch (i + n) { - case 6: - if (!n--) break; - regs->r13 = *args++; - case 5: - if (!n--) break; - regs->r15 = *args++; - case 4: - if (!n--) break; - regs->r14 = *args++; - case 3: - if (!n--) break; - regs->r10 = *args++; - case 2: - if (!n--) break; - regs->r9 = *args++; - case 1: - if (!n--) break; - regs->r11 = *args++; - case 0: - if (!n--) break; - } - - return; - } -#endif ia64_syscall_get_set_arguments(task, regs, i, n, args, 1); } #endif /* _ASM_SYSCALL_H */ diff --git a/arch/ia64/include/asm/system.h b/arch/ia64/include/asm/system.h index 927a381c20ca..9f342a574ce8 100644 --- a/arch/ia64/include/asm/system.h +++ b/arch/ia64/include/asm/system.h @@ -191,15 +191,6 @@ do { \ #ifdef __KERNEL__ -#ifdef CONFIG_IA32_SUPPORT -# define IS_IA32_PROCESS(regs) (ia64_psr(regs)->is != 0) -#else -# define IS_IA32_PROCESS(regs) 0 -struct task_struct; -static inline void ia32_save_state(struct task_struct *t __attribute__((unused))){} -static inline void ia32_load_state(struct task_struct *t __attribute__((unused))){} -#endif - /* * Context switch from one thread to another. If the two threads have * different address spaces, schedule() has already taken care of @@ -233,7 +224,7 @@ extern void ia64_account_on_switch (struct task_struct *prev, struct task_struct #define IA64_HAS_EXTRA_STATE(t) \ ((t)->thread.flags & (IA64_THREAD_DBG_VALID|IA64_THREAD_PM_VALID) \ - || IS_IA32_PROCESS(task_pt_regs(t)) || PERFMON_IS_SYSWIDE()) + || PERFMON_IS_SYSWIDE()) #define __switch_to(prev,next,last) do { \ IA64_ACCOUNT_ON_SWITCH(prev, next); \ diff --git a/arch/ia64/include/asm/unistd.h b/arch/ia64/include/asm/unistd.h index 10a8f21ca9e3..bb8b0fff32b3 100644 --- a/arch/ia64/include/asm/unistd.h +++ b/arch/ia64/include/asm/unistd.h @@ -335,20 +335,6 @@ #define __ARCH_WANT_SYS_RT_SIGACTION #define __ARCH_WANT_SYS_RT_SIGSUSPEND -#ifdef CONFIG_IA32_SUPPORT -# define __ARCH_WANT_SYS_FADVISE64 -# define __ARCH_WANT_SYS_GETPGRP -# define __ARCH_WANT_SYS_LLSEEK -# define __ARCH_WANT_SYS_NICE -# define __ARCH_WANT_SYS_OLD_GETRLIMIT -# define __ARCH_WANT_SYS_OLDUMOUNT -# define __ARCH_WANT_SYS_PAUSE -# define __ARCH_WANT_SYS_SIGPENDING -# define __ARCH_WANT_SYS_SIGPROCMASK -# define __ARCH_WANT_COMPAT_SYS_RT_SIGSUSPEND -# define __ARCH_WANT_COMPAT_SYS_TIME -#endif - #if !defined(__ASSEMBLY__) && !defined(ASSEMBLER) #include diff --git a/arch/ia64/kernel/audit.c b/arch/ia64/kernel/audit.c index f3802ae89b10..96a9d18ff4c4 100644 --- a/arch/ia64/kernel/audit.c +++ b/arch/ia64/kernel/audit.c @@ -30,20 +30,11 @@ static unsigned signal_class[] = { int audit_classify_arch(int arch) { -#ifdef CONFIG_IA32_SUPPORT - if (arch == AUDIT_ARCH_I386) - return 1; -#endif return 0; } int audit_classify_syscall(int abi, unsigned syscall) { -#ifdef CONFIG_IA32_SUPPORT - extern int ia32_classify_syscall(unsigned); - if (abi == AUDIT_ARCH_I386) - return ia32_classify_syscall(syscall); -#endif switch(syscall) { case __NR_open: return 2; @@ -58,18 +49,6 @@ int audit_classify_syscall(int abi, unsigned syscall) static int __init audit_classes_init(void) { -#ifdef CONFIG_IA32_SUPPORT - extern __u32 ia32_dir_class[]; - extern __u32 ia32_write_class[]; - extern __u32 ia32_read_class[]; - extern __u32 ia32_chattr_class[]; - extern __u32 ia32_signal_class[]; - audit_register_class(AUDIT_CLASS_WRITE_32, ia32_write_class); - audit_register_class(AUDIT_CLASS_READ_32, ia32_read_class); - audit_register_class(AUDIT_CLASS_DIR_WRITE_32, ia32_dir_class); - audit_register_class(AUDIT_CLASS_CHATTR_32, ia32_chattr_class); - audit_register_class(AUDIT_CLASS_SIGNAL_32, ia32_signal_class); -#endif audit_register_class(AUDIT_CLASS_WRITE, write_class); audit_register_class(AUDIT_CLASS_READ, read_class); audit_register_class(AUDIT_CLASS_DIR_WRITE, dir_class); diff --git a/arch/ia64/kernel/entry.S b/arch/ia64/kernel/entry.S index d75b872ca4dc..9a260b317d8d 100644 --- a/arch/ia64/kernel/entry.S +++ b/arch/ia64/kernel/entry.S @@ -71,15 +71,6 @@ ENTRY(ia64_execve) add out3=16,sp // regs br.call.sptk.many rp=sys_execve .ret0: -#ifdef CONFIG_IA32_SUPPORT - /* - * Check if we're returning to ia32 mode. If so, we need to restore ia32 registers - * from pt_regs. - */ - adds r16=PT(CR_IPSR)+16,sp - ;; - ld8 r16=[r16] -#endif cmp4.ge p6,p7=r8,r0 mov ar.pfs=loc1 // restore ar.pfs sxt4 r8=r8 // return 64-bit result @@ -108,12 +99,6 @@ ENTRY(ia64_execve) ldf.fill f23=[sp]; ldf.fill f24=[sp]; mov f25=f0 ldf.fill f26=[sp]; ldf.fill f27=[sp]; mov f28=f0 ldf.fill f29=[sp]; ldf.fill f30=[sp]; mov f31=f0 -#ifdef CONFIG_IA32_SUPPORT - tbit.nz p6,p0=r16, IA64_PSR_IS_BIT - movl loc0=ia64_ret_from_ia32_execve - ;; -(p6) mov rp=loc0 -#endif br.ret.sptk.many rp END(ia64_execve) @@ -848,30 +833,6 @@ __paravirt_work_processed_syscall: br.cond.sptk.many rbs_switch // B END(__paravirt_leave_syscall) -#ifdef __IA64_ASM_PARAVIRTUALIZED_NATIVE -#ifdef CONFIG_IA32_SUPPORT -GLOBAL_ENTRY(ia64_ret_from_ia32_execve) - PT_REGS_UNWIND_INFO(0) - adds r2=PT(R8)+16,sp // r2 = &pt_regs.r8 - adds r3=PT(R10)+16,sp // r3 = &pt_regs.r10 - ;; - .mem.offset 0,0 - st8.spill [r2]=r8 // store return value in slot for r8 and set unat bit - .mem.offset 8,0 - st8.spill [r3]=r0 // clear error indication in slot for r10 and set unat bit -#ifdef CONFIG_PARAVIRT - ;; - // don't fall through, ia64_leave_kernel may be #define'd - br.cond.sptk.few ia64_leave_kernel - ;; -#endif /* CONFIG_PARAVIRT */ -END(ia64_ret_from_ia32_execve) -#ifndef CONFIG_PARAVIRT - // fall through -#endif -#endif /* CONFIG_IA32_SUPPORT */ -#endif /* __IA64_ASM_PARAVIRTUALIZED_NATIVE */ - GLOBAL_ENTRY(__paravirt_leave_kernel) PT_REGS_UNWIND_INFO(0) /* diff --git a/arch/ia64/kernel/ivt.S b/arch/ia64/kernel/ivt.S index ec9a5fdfa1b9..179fd122e837 100644 --- a/arch/ia64/kernel/ivt.S +++ b/arch/ia64/kernel/ivt.S @@ -49,7 +49,6 @@ #include #include -#include #include #include #include @@ -1386,28 +1385,6 @@ END(ia32_exception) // 0x6a00 Entry 46 (size 16 bundles) IA-32 Intercept (30,31,59,70,71) ENTRY(ia32_intercept) DBG_FAULT(46) -#ifdef CONFIG_IA32_SUPPORT - mov r31=pr - MOV_FROM_ISR(r16) - ;; - extr.u r17=r16,16,8 // get ISR.code - mov r18=ar.eflag - MOV_FROM_IIM(r19) // old eflag value - ;; - cmp.ne p6,p0=2,r17 -(p6) br.cond.spnt 1f // not a system flag fault - xor r16=r18,r19 - ;; - extr.u r17=r16,18,1 // get the eflags.ac bit - ;; - cmp.eq p6,p0=0,r17 -(p6) br.cond.spnt 1f // eflags.ac bit didn't change - ;; - mov pr=r31,-1 // restore predicate registers - RFI - -1: -#endif // CONFIG_IA32_SUPPORT FAULT(46) END(ia32_intercept) @@ -1416,12 +1393,7 @@ END(ia32_intercept) // 0x6b00 Entry 47 (size 16 bundles) IA-32 Interrupt (74) ENTRY(ia32_interrupt) DBG_FAULT(47) -#ifdef CONFIG_IA32_SUPPORT - mov r31=pr - br.sptk.many dispatch_to_ia32_handler -#else FAULT(47) -#endif END(ia32_interrupt) .org ia64_ivt+0x6c00 @@ -1715,89 +1687,3 @@ ENTRY(dispatch_illegal_op_fault) (p6) br.call.dpnt.many b6=b6 // call returns to ia64_leave_kernel br.sptk.many ia64_leave_kernel END(dispatch_illegal_op_fault) - -#ifdef CONFIG_IA32_SUPPORT - - /* - * There is no particular reason for this code to be here, other than that - * there happens to be space here that would go unused otherwise. If this - * fault ever gets "unreserved", simply moved the following code to a more - * suitable spot... - */ - - // IA32 interrupt entry point - -ENTRY(dispatch_to_ia32_handler) - SAVE_MIN - ;; - MOV_FROM_ISR(r14) - SSM_PSR_IC_AND_DEFAULT_BITS_AND_SRLZ_I(r3, r24) - // guarantee that interruption collection is on - ;; - SSM_PSR_I(p15, p15, r3) - adds r3=8,r2 // Base pointer for SAVE_REST - ;; - SAVE_REST - ;; - mov r15=0x80 - shr r14=r14,16 // Get interrupt number - ;; - cmp.ne p6,p0=r14,r15 -(p6) br.call.dpnt.many b6=non_ia32_syscall - - adds r14=IA64_PT_REGS_R8_OFFSET + 16,sp // 16 byte hole per SW conventions - adds r15=IA64_PT_REGS_R1_OFFSET + 16,sp - ;; - cmp.eq pSys,pNonSys=r0,r0 // set pSys=1, pNonSys=0 - ld8 r8=[r14] // get r8 - ;; - st8 [r15]=r8 // save original EAX in r1 (IA32 procs don't use the GP) - ;; - alloc r15=ar.pfs,0,0,6,0 // must first in an insn group - ;; - ld4 r8=[r14],8 // r8 == eax (syscall number) - mov r15=IA32_NR_syscalls - ;; - cmp.ltu.unc p6,p7=r8,r15 - ld4 out1=[r14],8 // r9 == ecx - ;; - ld4 out2=[r14],8 // r10 == edx - ;; - ld4 out0=[r14] // r11 == ebx - adds r14=(IA64_PT_REGS_R13_OFFSET) + 16,sp - ;; - ld4 out5=[r14],PT(R14)-PT(R13) // r13 == ebp - ;; - ld4 out3=[r14],PT(R15)-PT(R14) // r14 == esi - adds r2=TI_FLAGS+IA64_TASK_SIZE,r13 - ;; - ld4 out4=[r14] // r15 == edi - movl r16=ia32_syscall_table - ;; -(p6) shladd r16=r8,3,r16 // force ni_syscall if not valid syscall number - ld4 r2=[r2] // r2 = current_thread_info()->flags - ;; - ld8 r16=[r16] - and r2=_TIF_SYSCALL_TRACEAUDIT,r2 // mask trace or audit - ;; - mov b6=r16 - movl r15=ia32_ret_from_syscall - cmp.eq p8,p0=r2,r0 - ;; - mov rp=r15 -(p8) br.call.sptk.many b6=b6 - br.cond.sptk ia32_trace_syscall - -non_ia32_syscall: - alloc r15=ar.pfs,0,0,2,0 - mov out0=r14 // interrupt # - add out1=16,sp // pointer to pt_regs - ;; // avoid WAW on CFM - br.call.sptk.many rp=ia32_bad_interrupt -.ret1: movl r15=ia64_leave_kernel - ;; - mov rp=r15 - br.ret.sptk.many rp -END(dispatch_to_ia32_handler) - -#endif /* CONFIG_IA32_SUPPORT */ diff --git a/arch/ia64/kernel/process.c b/arch/ia64/kernel/process.c index 9bcec9945c12..883ecc9cfef5 100644 --- a/arch/ia64/kernel/process.c +++ b/arch/ia64/kernel/process.c @@ -33,7 +33,6 @@ #include #include #include -#include #include #include #include @@ -358,11 +357,6 @@ ia64_save_extra (struct task_struct *task) if (info & PFM_CPUINFO_SYST_WIDE) pfm_syst_wide_update_task(task, info, 0); #endif - -#ifdef CONFIG_IA32_SUPPORT - if (IS_IA32_PROCESS(task_pt_regs(task))) - ia32_save_state(task); -#endif } void @@ -383,11 +377,6 @@ ia64_load_extra (struct task_struct *task) if (info & PFM_CPUINFO_SYST_WIDE) pfm_syst_wide_update_task(task, info, 1); #endif - -#ifdef CONFIG_IA32_SUPPORT - if (IS_IA32_PROCESS(task_pt_regs(task))) - ia32_load_state(task); -#endif } /* @@ -426,7 +415,7 @@ copy_thread(unsigned long clone_flags, unsigned long user_stack_base, unsigned long user_stack_size, struct task_struct *p, struct pt_regs *regs) { - extern char ia64_ret_from_clone, ia32_ret_from_clone; + extern char ia64_ret_from_clone; struct switch_stack *child_stack, *stack; unsigned long rbs, child_rbs, rbs_size; struct pt_regs *child_ptregs; @@ -457,7 +446,7 @@ copy_thread(unsigned long clone_flags, memcpy((void *) child_rbs, (void *) rbs, rbs_size); if (likely(user_mode(child_ptregs))) { - if ((clone_flags & CLONE_SETTLS) && !IS_IA32_PROCESS(regs)) + if (clone_flags & CLONE_SETTLS) child_ptregs->r13 = regs->r16; /* see sys_clone2() in entry.S */ if (user_stack_base) { child_ptregs->r12 = user_stack_base + user_stack_size - 16; @@ -477,10 +466,7 @@ copy_thread(unsigned long clone_flags, child_ptregs->r13 = (unsigned long) p; /* set `current' pointer */ } child_stack->ar_bspstore = child_rbs + rbs_size; - if (IS_IA32_PROCESS(regs)) - child_stack->b0 = (unsigned long) &ia32_ret_from_clone; - else - child_stack->b0 = (unsigned long) &ia64_ret_from_clone; + child_stack->b0 = (unsigned long) &ia64_ret_from_clone; /* copy parts of thread_struct: */ p->thread.ksp = (unsigned long) child_stack - 16; @@ -515,22 +501,6 @@ copy_thread(unsigned long clone_flags, p->thread.flags = ((current->thread.flags & ~THREAD_FLAGS_TO_CLEAR) | THREAD_FLAGS_TO_SET); ia64_drop_fpu(p); /* don't pick up stale state from a CPU's fph */ -#ifdef CONFIG_IA32_SUPPORT - /* - * If we're cloning an IA32 task then save the IA32 extra - * state from the current task to the new task - */ - if (IS_IA32_PROCESS(task_pt_regs(current))) { - ia32_save_state(p); - if (clone_flags & CLONE_SETTLS) - retval = ia32_clone_tls(p, child_ptregs); - - /* Copy partially mapped page list */ - if (!retval) - retval = ia32_copy_ia64_partial_page_list(p, - clone_flags); - } -#endif #ifdef CONFIG_PERFMON if (current->thread.pfm_context) @@ -704,15 +674,6 @@ EXPORT_SYMBOL(kernel_thread); int kernel_thread_helper (int (*fn)(void *), void *arg) { -#ifdef CONFIG_IA32_SUPPORT - if (IS_IA32_PROCESS(task_pt_regs(current))) { - /* A kernel thread is always a 64-bit process. */ - current->thread.map_base = DEFAULT_MAP_BASE; - current->thread.task_size = DEFAULT_TASK_SIZE; - ia64_set_kr(IA64_KR_IO_BASE, current->thread.old_iob); - ia64_set_kr(IA64_KR_TSSD, current->thread.old_k1); - } -#endif return (*fn)(arg); } @@ -725,14 +686,6 @@ flush_thread (void) /* drop floating-point and debug-register state if it exists: */ current->thread.flags &= ~(IA64_THREAD_FPH_VALID | IA64_THREAD_DBG_VALID); ia64_drop_fpu(current); -#ifdef CONFIG_IA32_SUPPORT - if (IS_IA32_PROCESS(task_pt_regs(current))) { - ia32_drop_ia64_partial_page_list(current); - current->thread.task_size = IA32_PAGE_OFFSET; - set_fs(USER_DS); - memset(current->thread.tls_array, 0, sizeof(current->thread.tls_array)); - } -#endif } /* @@ -753,8 +706,6 @@ exit_thread (void) if (current->thread.flags & IA64_THREAD_DBG_VALID) pfm_release_debug_registers(current); #endif - if (IS_IA32_PROCESS(task_pt_regs(current))) - ia32_drop_ia64_partial_page_list(current); } unsigned long diff --git a/arch/ia64/kernel/ptrace.c b/arch/ia64/kernel/ptrace.c index 9daa87fdb018..b61afbbe076f 100644 --- a/arch/ia64/kernel/ptrace.c +++ b/arch/ia64/kernel/ptrace.c @@ -1250,13 +1250,8 @@ syscall_trace_enter (long arg0, long arg1, long arg2, long arg3, long syscall; int arch; - if (IS_IA32_PROCESS(®s)) { - syscall = regs.r1; - arch = AUDIT_ARCH_I386; - } else { - syscall = regs.r15; - arch = AUDIT_ARCH_IA64; - } + syscall = regs.r15; + arch = AUDIT_ARCH_IA64; audit_syscall_entry(arch, syscall, arg0, arg1, arg2, arg3); } @@ -2172,11 +2167,6 @@ static const struct user_regset_view user_ia64_view = { const struct user_regset_view *task_user_regset_view(struct task_struct *tsk) { -#ifdef CONFIG_IA32_SUPPORT - extern const struct user_regset_view user_ia32_view; - if (IS_IA32_PROCESS(task_pt_regs(tsk))) - return &user_ia32_view; -#endif return &user_ia64_view; } diff --git a/arch/ia64/kernel/setup.c b/arch/ia64/kernel/setup.c index a1ea87919777..41ae6a596b50 100644 --- a/arch/ia64/kernel/setup.c +++ b/arch/ia64/kernel/setup.c @@ -46,7 +46,6 @@ #include #include -#include #include #include #include @@ -1016,10 +1015,6 @@ cpu_init (void) ia64_mmu_init(ia64_imva(cpu_data)); ia64_mca_cpu_init(ia64_imva(cpu_data)); -#ifdef CONFIG_IA32_SUPPORT - ia32_cpu_init(); -#endif - /* Clear ITC to eliminate sched_clock() overflows in human time. */ ia64_set_itc(0); diff --git a/arch/ia64/kernel/signal.c b/arch/ia64/kernel/signal.c index e1821ca4c7df..7bdafc8788bd 100644 --- a/arch/ia64/kernel/signal.c +++ b/arch/ia64/kernel/signal.c @@ -21,7 +21,6 @@ #include #include -#include #include #include #include @@ -425,14 +424,8 @@ static long handle_signal (unsigned long sig, struct k_sigaction *ka, siginfo_t *info, sigset_t *oldset, struct sigscratch *scr) { - if (IS_IA32_PROCESS(&scr->pt)) { - /* send signal to IA-32 process */ - if (!ia32_setup_frame1(sig, ka, info, oldset, &scr->pt)) - return 0; - } else - /* send signal to IA-64 process */ - if (!setup_frame(sig, ka, info, oldset, scr)) - return 0; + if (!setup_frame(sig, ka, info, oldset, scr)) + return 0; spin_lock_irq(¤t->sighand->siglock); sigorsets(¤t->blocked, ¤t->blocked, &ka->sa.sa_mask); @@ -462,7 +455,6 @@ ia64_do_signal (struct sigscratch *scr, long in_syscall) siginfo_t info; long restart = in_syscall; long errno = scr->pt.r8; -# define ERR_CODE(c) (IS_IA32_PROCESS(&scr->pt) ? -(c) : (c)) /* * In the ia64_leave_kernel code path, we want the common case to go fast, which @@ -490,14 +482,7 @@ ia64_do_signal (struct sigscratch *scr, long in_syscall) * inferior call), thus it's important to check for restarting _after_ * get_signal_to_deliver(). */ - if (IS_IA32_PROCESS(&scr->pt)) { - if (in_syscall) { - if (errno >= 0) - restart = 0; - else - errno = -errno; - } - } else if ((long) scr->pt.r10 != -1) + if ((long) scr->pt.r10 != -1) /* * A system calls has to be restarted only if one of the error codes * ERESTARTNOHAND, ERESTARTSYS, or ERESTARTNOINTR is returned. If r10 @@ -513,22 +498,18 @@ ia64_do_signal (struct sigscratch *scr, long in_syscall) switch (errno) { case ERESTART_RESTARTBLOCK: case ERESTARTNOHAND: - scr->pt.r8 = ERR_CODE(EINTR); + scr->pt.r8 = EINTR; /* note: scr->pt.r10 is already -1 */ break; case ERESTARTSYS: if ((ka.sa.sa_flags & SA_RESTART) == 0) { - scr->pt.r8 = ERR_CODE(EINTR); + scr->pt.r8 = EINTR; /* note: scr->pt.r10 is already -1 */ break; } case ERESTARTNOINTR: - if (IS_IA32_PROCESS(&scr->pt)) { - scr->pt.r8 = scr->pt.r1; - scr->pt.cr_iip -= 2; - } else - ia64_decrement_ip(&scr->pt); + ia64_decrement_ip(&scr->pt); restart = 0; /* don't restart twice if handle_signal() fails... */ } } @@ -555,21 +536,14 @@ ia64_do_signal (struct sigscratch *scr, long in_syscall) if (errno == ERESTARTNOHAND || errno == ERESTARTSYS || errno == ERESTARTNOINTR || errno == ERESTART_RESTARTBLOCK) { - if (IS_IA32_PROCESS(&scr->pt)) { - scr->pt.r8 = scr->pt.r1; - scr->pt.cr_iip -= 2; - if (errno == ERESTART_RESTARTBLOCK) - scr->pt.r8 = 0; /* x86 version of __NR_restart_syscall */ - } else { - /* - * Note: the syscall number is in r15 which is saved in - * pt_regs so all we need to do here is adjust ip so that - * the "break" instruction gets re-executed. - */ - ia64_decrement_ip(&scr->pt); - if (errno == ERESTART_RESTARTBLOCK) - scr->pt.r15 = __NR_restart_syscall; - } + /* + * Note: the syscall number is in r15 which is saved in + * pt_regs so all we need to do here is adjust ip so that + * the "break" instruction gets re-executed. + */ + ia64_decrement_ip(&scr->pt); + if (errno == ERESTART_RESTARTBLOCK) + scr->pt.r15 = __NR_restart_syscall; } } diff --git a/arch/ia64/kernel/smpboot.c b/arch/ia64/kernel/smpboot.c index de100aa7ff03..e5230b2ff2c5 100644 --- a/arch/ia64/kernel/smpboot.c +++ b/arch/ia64/kernel/smpboot.c @@ -44,7 +44,6 @@ #include #include #include -#include #include #include #include @@ -443,10 +442,6 @@ smp_callin (void) calibrate_delay(); local_cpu_data->loops_per_jiffy = loops_per_jiffy; -#ifdef CONFIG_IA32_SUPPORT - ia32_gdt_init(); -#endif - /* * Allow the master to continue. */ diff --git a/arch/ia64/kernel/traps.c b/arch/ia64/kernel/traps.c index f0cda765e681..fd80e70018a9 100644 --- a/arch/ia64/kernel/traps.c +++ b/arch/ia64/kernel/traps.c @@ -19,7 +19,6 @@ #include #include -#include #include #include #include @@ -626,10 +625,6 @@ ia64_fault (unsigned long vector, unsigned long isr, unsigned long ifa, break; case 45: -#ifdef CONFIG_IA32_SUPPORT - if (ia32_exception(®s, isr) == 0) - return; -#endif printk(KERN_ERR "Unexpected IA-32 exception (Trap 45)\n"); printk(KERN_ERR " iip - 0x%lx, ifa - 0x%lx, isr - 0x%lx\n", iip, ifa, isr); @@ -637,10 +632,6 @@ ia64_fault (unsigned long vector, unsigned long isr, unsigned long ifa, break; case 46: -#ifdef CONFIG_IA32_SUPPORT - if (ia32_intercept(®s, isr) == 0) - return; -#endif printk(KERN_ERR "Unexpected IA-32 intercept trap (Trap 46)\n"); printk(KERN_ERR " iip - 0x%lx, ifa - 0x%lx, isr - 0x%lx, iim - 0x%lx\n", iip, ifa, isr, iim); diff --git a/arch/ia64/mm/init.c b/arch/ia64/mm/init.c index 7c0d4814a68d..ca3335ea56cc 100644 --- a/arch/ia64/mm/init.c +++ b/arch/ia64/mm/init.c @@ -22,7 +22,6 @@ #include #include -#include #include #include #include @@ -668,10 +667,6 @@ mem_init (void) fsyscall_table[i] = sys_call_table[i] | 1; } setup_gate(); - -#ifdef CONFIG_IA32_SUPPORT - ia32_mem_init(); -#endif } #ifdef CONFIG_MEMORY_HOTPLUG diff --git a/arch/ia64/xen/hypercall.S b/arch/ia64/xen/hypercall.S index e32dae444dd6..08847aa12583 100644 --- a/arch/ia64/xen/hypercall.S +++ b/arch/ia64/xen/hypercall.S @@ -58,11 +58,6 @@ __HCALL2(xen_ptcga, HYPERPRIVOP_PTC_GA) __HCALL2(xen_set_rr, HYPERPRIVOP_SET_RR) __HCALL2(xen_set_kr, HYPERPRIVOP_SET_KR) -#ifdef CONFIG_IA32_SUPPORT -__HCALL0(xen_get_eflag, HYPERPRIVOP_GET_EFLAG) -__HCALL1(xen_set_eflag, HYPERPRIVOP_SET_EFLAG) // refer SDM vol1 3.1.8 -#endif /* CONFIG_IA32_SUPPORT */ - GLOBAL_ENTRY(xen_set_rr0_to_rr4) mov r8=r32 mov r9=r33 diff --git a/arch/ia64/xen/xen_pv_ops.c b/arch/ia64/xen/xen_pv_ops.c index 5e2270a999fa..8adc6a14272a 100644 --- a/arch/ia64/xen/xen_pv_ops.c +++ b/arch/ia64/xen/xen_pv_ops.c @@ -301,11 +301,6 @@ static void xen_setreg(int regnum, unsigned long val) case _IA64_REG_AR_KR0 ... _IA64_REG_AR_KR7: xen_set_kr(regnum - _IA64_REG_AR_KR0, val); break; -#ifdef CONFIG_IA32_SUPPORT - case _IA64_REG_AR_EFLAG: - xen_set_eflag(val); - break; -#endif case _IA64_REG_AR_ITC: xen_set_itc(val); break; @@ -332,11 +327,6 @@ static unsigned long xen_getreg(int regnum) case _IA64_REG_PSR: res = xen_get_psr(); break; -#ifdef CONFIG_IA32_SUPPORT - case _IA64_REG_AR_EFLAG: - res = xen_get_eflag(); - break; -#endif case _IA64_REG_AR_ITC: res = xen_get_itc(); break; @@ -710,9 +700,6 @@ extern unsigned long xen_getreg(int regnum); __DEFINE_FUNC(getreg, __DEFINE_GET_REG(PSR, PSR) -#ifdef CONFIG_IA32_SUPPORT - __DEFINE_GET_REG(AR_EFLAG, EFLAG) -#endif /* get_itc */ "mov r2 = " __stringify(_IA64_REG_AR_ITC) "\n" @@ -789,9 +776,6 @@ __DEFINE_FUNC(setreg, ";;\n" "(p6) br.cond.spnt xen_set_itc\n" -#ifdef CONFIG_IA32_SUPPORT - __DEFINE_SET_REG(AR_EFLAG, SET_EFLAG) -#endif __DEFINE_SET_REG(CR_TPR, SET_TPR) __DEFINE_SET_REG(CR_EOI, EOI) diff --git a/drivers/input/input-compat.h b/drivers/input/input-compat.h index 47cd9eaee66a..4d8ea32e8a00 100644 --- a/drivers/input/input-compat.h +++ b/drivers/input/input-compat.h @@ -21,8 +21,6 @@ you why the ifdefs are needed? Think about it again. -AK */ #ifdef CONFIG_X86_64 # define INPUT_COMPAT_TEST is_compat_task() -#elif defined(CONFIG_IA64) -# define INPUT_COMPAT_TEST IS_IA32_PROCESS(task_pt_regs(current)) #elif defined(CONFIG_S390) # define INPUT_COMPAT_TEST test_thread_flag(TIF_31BIT) #elif defined(CONFIG_MIPS) -- cgit v1.2.3 From 3ad2f3fbb961429d2aa627465ae4829758bc7e07 Mon Sep 17 00:00:00 2001 From: Daniel Mack Date: Wed, 3 Feb 2010 08:01:28 +0800 Subject: tree-wide: Assorted spelling fixes In particular, several occurances of funny versions of 'success', 'unknown', 'therefore', 'acknowledge', 'argument', 'achieve', 'address', 'beginning', 'desirable', 'separate' and 'necessary' are fixed. Signed-off-by: Daniel Mack Cc: Joe Perches Cc: Junio C Hamano Signed-off-by: Jiri Kosina --- Documentation/DocBook/mtdnand.tmpl | 6 +++--- Documentation/DocBook/v4l/common.xml | 2 +- Documentation/DocBook/v4l/vidioc-g-parm.xml | 2 +- Documentation/arm/Samsung-S3C24XX/CPUfreq.txt | 4 ++-- Documentation/hwmon/abituguru | 2 +- Documentation/input/rotary-encoder.txt | 2 +- Documentation/networking/skfp.txt | 2 +- Documentation/s390/kvm.txt | 2 +- Documentation/scsi/ChangeLog.lpfc | 10 +++++----- Documentation/trace/ftrace.txt | 2 +- arch/arm/mach-ep93xx/micro9.c | 2 +- arch/arm/mach-nomadik/board-nhk8815.c | 2 +- arch/arm/mach-u300/core.c | 4 ++-- arch/arm/mach-u300/include/mach/debug-macro.S | 2 +- arch/arm/plat-s3c/include/plat/gpio-cfg-helpers.h | 2 +- arch/arm/plat-s3c/include/plat/regs-usb-hsotg-phy.h | 2 +- arch/arm/plat-s3c24xx/include/plat/cpu-freq-core.h | 2 +- arch/cris/arch-v10/lib/old_checksum.c | 2 +- arch/cris/arch-v32/mm/tlb.c | 2 +- arch/h8300/include/asm/io.h | 2 +- arch/ia64/sn/kernel/setup.c | 2 +- arch/m68k/atari/atakeyb.c | 2 +- arch/m68k/include/asm/io_no.h | 2 +- arch/powerpc/boot/dts/kmeter1.dts | 2 +- arch/s390/include/asm/cio.h | 2 +- arch/s390/kernel/sclp.S | 2 +- arch/sparc/kernel/leon_kernel.c | 2 +- arch/sparc/kernel/perf_event.c | 2 +- arch/x86/crypto/twofish-i586-asm_32.S | 10 +++++----- arch/x86/crypto/twofish-x86_64-asm_64.S | 20 ++++++++++---------- arch/x86/kernel/head_64.S | 2 +- arch/x86/kernel/pci-calgary_64.c | 2 +- arch/x86/kernel/tsc.c | 2 +- arch/xtensa/kernel/entry.S | 4 ++-- block/bsg.c | 2 +- drivers/acpi/dock.c | 2 +- drivers/ata/libata-sff.c | 2 +- drivers/ata/pata_acpi.c | 2 +- drivers/ata/pata_hpt3x3.c | 2 +- drivers/ata/pata_pcmcia.c | 2 +- drivers/block/drbd/drbd_int.h | 4 ++-- drivers/block/drbd/drbd_req.h | 2 +- drivers/char/agp/intel-agp.c | 2 +- drivers/char/applicom.c | 2 +- drivers/char/hvc_iseries.c | 2 +- drivers/char/hw_random/n2-drv.c | 2 +- drivers/char/ip2/i2hw.h | 2 +- drivers/char/pty.c | 2 +- drivers/char/tty_io.c | 2 +- drivers/char/vt.c | 2 +- drivers/dma/coh901318_lli.h | 2 +- drivers/gpu/drm/nouveau/nouveau_bios.c | 2 +- drivers/gpu/drm/nouveau/nouveau_drv.h | 2 +- drivers/gpu/drm/via/via_irq.c | 4 ++-- drivers/i2c/busses/i2c-pxa.c | 2 +- drivers/infiniband/hw/ehca/ehca_qes.h | 4 ++-- drivers/infiniband/hw/ehca/ehca_reqs.c | 2 +- drivers/input/misc/yealink.h | 2 +- drivers/isdn/i4l/isdn_common.c | 2 +- drivers/media/dvb/dvb-core/dvb_frontend.h | 8 ++++---- drivers/media/video/bt8xx/bttv-cards.c | 4 ++-- drivers/media/video/gspca/ov519.c | 2 +- drivers/media/video/pwc/philips.txt | 2 +- drivers/media/video/sn9c102/sn9c102_sensor.h | 2 +- drivers/media/video/tea6420.c | 2 +- drivers/mfd/sm501.c | 8 ++++---- drivers/mmc/host/mxcmmc.c | 2 +- drivers/mtd/chips/jedec_probe.c | 2 +- drivers/mtd/nand/bcm_umi_nand.c | 4 ++-- drivers/mtd/nand/mxc_nand.c | 2 +- drivers/net/atlx/atl2.h | 2 +- drivers/net/chelsio/sge.c | 2 +- drivers/net/e1000e/82571.c | 2 +- drivers/net/e1000e/lib.c | 2 +- drivers/net/igb/igb_main.c | 2 +- drivers/net/irda/sa1100_ir.c | 2 +- drivers/net/qlge/qlge_ethtool.c | 2 +- drivers/net/qlge/qlge_main.c | 2 +- drivers/net/sfc/regs.h | 2 +- drivers/net/smsc9420.c | 2 +- drivers/net/spider_net.c | 4 ++-- drivers/net/sungem.c | 2 +- drivers/net/tehuti.c | 2 +- drivers/net/tokenring/tms380tr.c | 4 ++-- drivers/net/tun.c | 2 +- drivers/net/ucc_geth.c | 2 +- drivers/net/wimax/i2400m/fw.c | 2 +- drivers/net/wimax/i2400m/i2400m.h | 2 +- drivers/net/wimax/i2400m/sdio.c | 4 ++-- drivers/net/wimax/i2400m/usb.c | 4 ++-- drivers/net/wireless/ath/ar9170/main.c | 2 +- drivers/net/wireless/iwmc3200wifi/lmac.h | 2 +- drivers/net/wireless/rt2x00/rt2500usb.c | 4 ++-- drivers/net/wireless/rt2x00/rt2800usb.c | 4 ++-- drivers/net/wireless/rt2x00/rt2x00debug.c | 2 +- drivers/net/wireless/rt2x00/rt2x00dev.c | 2 +- drivers/net/wireless/rt2x00/rt2x00queue.c | 2 +- drivers/net/wireless/rt2x00/rt61pci.c | 2 +- drivers/net/wireless/rt2x00/rt73usb.c | 6 +++--- drivers/s390/char/raw3270.c | 2 +- drivers/s390/char/sclp.c | 2 +- drivers/scsi/a100u2w.c | 2 +- drivers/scsi/initio.c | 2 +- drivers/scsi/libfc/fc_fcp.c | 2 +- drivers/scsi/lpfc/lpfc_els.c | 4 ++-- drivers/scsi/pcmcia/nsp_cs.h | 2 +- drivers/scsi/pm8001/pm8001_hwi.c | 2 +- drivers/scsi/pm8001/pm8001_sas.c | 2 +- drivers/scsi/pmcraid.h | 2 +- drivers/scsi/sd.c | 2 +- drivers/spi/spi_s3c24xx.c | 2 +- drivers/usb/musb/musb_regs.h | 2 +- drivers/usb/serial/cypress_m8.c | 2 +- drivers/video/omap/lcdc.c | 2 +- drivers/video/s1d13xxxfb.c | 4 ++-- drivers/video/sm501fb.c | 2 +- fs/affs/bitmap.c | 2 +- fs/binfmt_elf_fdpic.c | 2 +- fs/cifs/cifs_dfs_ref.c | 2 +- fs/cifs/cifssmb.c | 2 +- fs/ext4/move_extent.c | 2 +- fs/fuse/inode.c | 2 +- fs/gfs2/ops_fstype.c | 2 +- fs/jbd/transaction.c | 2 +- fs/nfsd/nfs4xdr.c | 2 +- fs/ocfs2/dlmglue.c | 2 +- fs/ocfs2/extent_map.c | 2 +- fs/reiserfs/bitmap.c | 2 +- include/linux/hil.h | 16 ++++++++-------- include/linux/lru_cache.h | 2 +- include/linux/sched.h | 2 +- include/media/davinci/vpfe_capture.h | 2 +- net/ipv4/tcp_timer.c | 2 +- net/mac80211/mesh_plink.c | 2 +- net/netfilter/nf_conntrack_sip.c | 4 ++-- net/netfilter/xt_hashlimit.c | 2 +- net/sctp/sm_sideeffect.c | 2 +- scripts/gfp-translate | 2 +- sound/pci/rme9652/hdspm.c | 2 +- sound/soc/codecs/wm8990.c | 2 +- tools/perf/util/hist.c | 2 +- 141 files changed, 192 insertions(+), 192 deletions(-) (limited to 'drivers/input') diff --git a/Documentation/DocBook/mtdnand.tmpl b/Documentation/DocBook/mtdnand.tmpl index 5e7d84b48505..133cd6c3f3c1 100644 --- a/Documentation/DocBook/mtdnand.tmpl +++ b/Documentation/DocBook/mtdnand.tmpl @@ -488,7 +488,7 @@ static void board_select_chip (struct mtd_info *mtd, int chip) The ECC bytes must be placed immidiately after the data bytes in order to make the syndrome generator work. This is contrary to the usual layout used by software ECC. The - seperation of data and out of band area is not longer + separation of data and out of band area is not longer possible. The nand driver code handles this layout and the remaining free bytes in the oob area are managed by the autoplacement code. Provide a matching oob-layout @@ -560,7 +560,7 @@ static void board_select_chip (struct mtd_info *mtd, int chip) bad blocks. They have factory marked good blocks. The marker pattern is erased when the block is erased to be reused. So in case of powerloss before writing the pattern back to the chip this block - would be lost and added to the bad blocks. Therefor we scan the + would be lost and added to the bad blocks. Therefore we scan the chip(s) when we detect them the first time for good blocks and store this information in a bad block table before erasing any of the blocks. @@ -1094,7 +1094,7 @@ in this page manufacturers specifications. This applies similar to the spare area. - Therefor NAND aware filesystems must either write in page size chunks + Therefore NAND aware filesystems must either write in page size chunks or hold a writebuffer to collect smaller writes until they sum up to pagesize. Available NAND aware filesystems: JFFS2, YAFFS. diff --git a/Documentation/DocBook/v4l/common.xml b/Documentation/DocBook/v4l/common.xml index c65f0ac9b6ee..cea23e1c4fc6 100644 --- a/Documentation/DocBook/v4l/common.xml +++ b/Documentation/DocBook/v4l/common.xml @@ -1170,7 +1170,7 @@ frames per second. If less than this number of frames is to be captured or output, applications can request frame skipping or duplicating on the driver side. This is especially useful when using the &func-read; or &func-write;, which are not augmented by timestamps -or sequence counters, and to avoid unneccessary data copying. +or sequence counters, and to avoid unnecessary data copying. Finally these ioctls can be used to determine the number of buffers used internally by a driver in read/write mode. For diff --git a/Documentation/DocBook/v4l/vidioc-g-parm.xml b/Documentation/DocBook/v4l/vidioc-g-parm.xml index 78332d365ce9..392aa9e5571e 100644 --- a/Documentation/DocBook/v4l/vidioc-g-parm.xml +++ b/Documentation/DocBook/v4l/vidioc-g-parm.xml @@ -55,7 +55,7 @@ captured or output, applications can request frame skipping or duplicating on the driver side. This is especially useful when using the read() or write(), which are not augmented by timestamps or sequence counters, and to avoid -unneccessary data copying. +unnecessary data copying. Further these ioctls can be used to determine the number of buffers used internally by a driver in read/write mode. For diff --git a/Documentation/arm/Samsung-S3C24XX/CPUfreq.txt b/Documentation/arm/Samsung-S3C24XX/CPUfreq.txt index 76b3a11e90be..fa968aa99d67 100644 --- a/Documentation/arm/Samsung-S3C24XX/CPUfreq.txt +++ b/Documentation/arm/Samsung-S3C24XX/CPUfreq.txt @@ -14,8 +14,8 @@ Introduction how the clocks are arranged. The first implementation used as single PLL to feed the ARM, memory and peripherals via a series of dividers and muxes and this is the implementation that is documented here. A - newer version where there is a seperate PLL and clock divider for the - ARM core is available as a seperate driver. + newer version where there is a separate PLL and clock divider for the + ARM core is available as a separate driver. Layout diff --git a/Documentation/hwmon/abituguru b/Documentation/hwmon/abituguru index 87ffa0f5ec70..5eb3b9d5f0d5 100644 --- a/Documentation/hwmon/abituguru +++ b/Documentation/hwmon/abituguru @@ -30,7 +30,7 @@ Supported chips: bank1_types=1,1,0,0,0,0,0,2,0,0,0,0,2,0,0,1 You may also need to specify the fan_sensors option for these boards fan_sensors=5 - 2) There is a seperate abituguru3 driver for these motherboards, + 2) There is a separate abituguru3 driver for these motherboards, the abituguru (without the 3 !) driver will not work on these motherboards (and visa versa)! diff --git a/Documentation/input/rotary-encoder.txt b/Documentation/input/rotary-encoder.txt index 3a6aec40c0b0..8b4129de1d2d 100644 --- a/Documentation/input/rotary-encoder.txt +++ b/Documentation/input/rotary-encoder.txt @@ -75,7 +75,7 @@ and the number of steps or will clamp at the maximum and zero depending on the configuration. Because GPIO to IRQ mapping is platform specific, this information must -be given in seperately to the driver. See the example below. +be given in separately to the driver. See the example below. ------------------ diff --git a/Documentation/networking/skfp.txt b/Documentation/networking/skfp.txt index abfddf81e34a..203ec66c9fb4 100644 --- a/Documentation/networking/skfp.txt +++ b/Documentation/networking/skfp.txt @@ -68,7 +68,7 @@ Compaq adapters (not tested): ======================= From v2.01 on, the driver is integrated in the linux kernel sources. -Therefor, the installation is the same as for any other adapter +Therefore, the installation is the same as for any other adapter supported by the kernel. Refer to the manual of your distribution about the installation of network adapters. diff --git a/Documentation/s390/kvm.txt b/Documentation/s390/kvm.txt index 6f5ceb0f09fc..85f3280d7ef6 100644 --- a/Documentation/s390/kvm.txt +++ b/Documentation/s390/kvm.txt @@ -102,7 +102,7 @@ args: unsigned long see also: include/linux/kvm.h This ioctl stores the state of the cpu at the guest real address given as argument, unless one of the following values defined in include/linux/kvm.h -is given as arguement: +is given as argument: KVM_S390_STORE_STATUS_NOADDR - the CPU stores its status to the save area in absolute lowcore as defined by the principles of operation KVM_S390_STORE_STATUS_PREFIXED - the CPU stores its status to the save area in diff --git a/Documentation/scsi/ChangeLog.lpfc b/Documentation/scsi/ChangeLog.lpfc index ff19a52fe004..2ffc1148eb95 100644 --- a/Documentation/scsi/ChangeLog.lpfc +++ b/Documentation/scsi/ChangeLog.lpfc @@ -989,8 +989,8 @@ Changes from 20040709 to 20040716 * Remove redundant port_cmp != 2 check in if (!port_cmp) { .... if (port_cmp != 2).... } * Clock changes: removed struct clk_data and timerList. - * Clock changes: seperate nodev_tmo and els_retry_delay into 2 - seperate timers and convert to 1 argument changed + * Clock changes: separate nodev_tmo and els_retry_delay into 2 + separate timers and convert to 1 argument changed LPFC_NODE_FARP_PEND_t to struct lpfc_node_farp_pend convert ipfarp_tmo to 1 argument convert target struct tmofunc and rtplunfunc to 1 argument * cr_count, cr_delay and @@ -1514,7 +1514,7 @@ Changes from 20040402 to 20040409 * Remove unused elxclock declaration in elx_sli.h. * Since everywhere IOCB_ENTRY is used, the return value is cast, move the cast into the macro. - * Split ioctls out into seperate files + * Split ioctls out into separate files Changes from 20040326 to 20040402 @@ -1534,7 +1534,7 @@ Changes from 20040326 to 20040402 * Unused variable cleanup * Use Linux list macros for DMABUF_t * Break up ioctls into 3 sections, dfc, util, hbaapi - rearranged code so this could be easily seperated into a + rearranged code so this could be easily separated into a differnet module later All 3 are currently turned on by defines in lpfc_ioctl.c LPFC_DFC_IOCTL, LPFC_UTIL_IOCTL, LPFC_HBAAPI_IOCTL @@ -1551,7 +1551,7 @@ Changes from 20040326 to 20040402 started by lpfc_online(). lpfc_offline() only stopped els_timeout routine. It now stops all timeout routines associated with that hba. - * Replace seperate next and prev pointers in struct + * Replace separate next and prev pointers in struct lpfc_bindlist with list_head type. In elxHBA_t, replace fc_nlpbind_start and _end with fc_nlpbind_list and use list_head macros to access it. diff --git a/Documentation/trace/ftrace.txt b/Documentation/trace/ftrace.txt index bab3040da548..03485bfbd797 100644 --- a/Documentation/trace/ftrace.txt +++ b/Documentation/trace/ftrace.txt @@ -1588,7 +1588,7 @@ module author does not need to worry about it. When tracing is enabled, kstop_machine is called to prevent races with the CPUS executing code being modified (which can -cause the CPU to do undesireable things), and the nops are +cause the CPU to do undesirable things), and the nops are patched back to calls. But this time, they do not call mcount (which is just a function stub). They now call into the ftrace infrastructure. diff --git a/arch/arm/mach-ep93xx/micro9.c b/arch/arm/mach-ep93xx/micro9.c index f3757a1c5a10..c33360e82868 100644 --- a/arch/arm/mach-ep93xx/micro9.c +++ b/arch/arm/mach-ep93xx/micro9.c @@ -28,7 +28,7 @@ * * Micro9-High has up to 64MB of 32-bit flash on CS1 * Micro9-Mid has up to 64MB of either 32-bit or 16-bit flash on CS1 - * Micro9-Lite uses a seperate MTD map driver for flash support + * Micro9-Lite uses a separate MTD map driver for flash support * Micro9-Slim has up to 64MB of either 32-bit or 16-bit flash on CS1 *************************************************************************/ static struct physmap_flash_data micro9_flash_data; diff --git a/arch/arm/mach-nomadik/board-nhk8815.c b/arch/arm/mach-nomadik/board-nhk8815.c index 9438bf6613a3..ab3712c86d2b 100644 --- a/arch/arm/mach-nomadik/board-nhk8815.c +++ b/arch/arm/mach-nomadik/board-nhk8815.c @@ -38,7 +38,7 @@ #define SRC_CR_INIT_MASK 0x00007fff #define SRC_CR_INIT_VAL 0x2aaa8000 -/* These adresses span 16MB, so use three individual pages */ +/* These addresses span 16MB, so use three individual pages */ static struct resource nhk8815_nand_resources[] = { { .name = "nand_addr", diff --git a/arch/arm/mach-u300/core.c b/arch/arm/mach-u300/core.c index 653e25be3dd8..d0cb5e940776 100644 --- a/arch/arm/mach-u300/core.c +++ b/arch/arm/mach-u300/core.c @@ -356,7 +356,7 @@ static struct resource ave_resources[] = { /* * The AVE3e requires two regions of 256MB that it considers * "invisible". The hardware will not be able to access these - * adresses, so they should never point to system RAM. + * addresses, so they should never point to system RAM. */ { .name = "AVE3e Reserved 0", @@ -571,7 +571,7 @@ static void __init u300_init_check_chip(void) /* * Some devices and their resources require reserved physical memory from * the end of the available RAM. This function traverses the list of devices - * and assigns actual adresses to these. + * and assigns actual addresses to these. */ static void __init u300_assign_physmem(void) { diff --git a/arch/arm/mach-u300/include/mach/debug-macro.S b/arch/arm/mach-u300/include/mach/debug-macro.S index f3a1cbbeeab3..d591fe13ed13 100644 --- a/arch/arm/mach-u300/include/mach/debug-macro.S +++ b/arch/arm/mach-u300/include/mach/debug-macro.S @@ -11,7 +11,7 @@ #include .macro addruart,rx - /* If we move the adress using MMU, use this. */ + /* If we move the address using MMU, use this. */ mrc p15, 0, \rx, c1, c0 tst \rx, #1 @ MMU enabled? ldreq \rx, = U300_SLOW_PER_PHYS_BASE @ MMU off, physical address diff --git a/arch/arm/plat-s3c/include/plat/gpio-cfg-helpers.h b/arch/arm/plat-s3c/include/plat/gpio-cfg-helpers.h index 652e2bbdaa20..dda19da037ad 100644 --- a/arch/arm/plat-s3c/include/plat/gpio-cfg-helpers.h +++ b/arch/arm/plat-s3c/include/plat/gpio-cfg-helpers.h @@ -78,7 +78,7 @@ extern int s3c_gpio_setcfg_s3c24xx_a(struct s3c_gpio_chip *chip, * others = Special functions (dependant on bank) * * Note, since the code to deal with the case where there are two control - * registers instead of one, we do not have a seperate set of functions for + * registers instead of one, we do not have a separate set of functions for * each case. */ extern int s3c_gpio_setcfg_s3c64xx_4bit(struct s3c_gpio_chip *chip, diff --git a/arch/arm/plat-s3c/include/plat/regs-usb-hsotg-phy.h b/arch/arm/plat-s3c/include/plat/regs-usb-hsotg-phy.h index 36a85f5000c8..a111ad871833 100644 --- a/arch/arm/plat-s3c/include/plat/regs-usb-hsotg-phy.h +++ b/arch/arm/plat-s3c/include/plat/regs-usb-hsotg-phy.h @@ -12,7 +12,7 @@ * published by the Free Software Foundation. */ -/* Note, this is a seperate header file as some of the clock framework +/* Note, this is a separate header file as some of the clock framework * needs to touch this if the clk_48m is used as the USB OHCI or other * peripheral source. */ diff --git a/arch/arm/plat-s3c24xx/include/plat/cpu-freq-core.h b/arch/arm/plat-s3c24xx/include/plat/cpu-freq-core.h index 33d421d78bad..d623235ae961 100644 --- a/arch/arm/plat-s3c24xx/include/plat/cpu-freq-core.h +++ b/arch/arm/plat-s3c24xx/include/plat/cpu-freq-core.h @@ -135,7 +135,7 @@ struct s3c_cpufreq_config { * @locktime_m: The lock-time in uS for the MPLL. * @locktime_u: The lock-time in uS for the UPLL. * @locttime_bits: The number of bits each LOCKTIME field. - * @need_pll: Set if this driver needs to change the PLL values to acheive + * @need_pll: Set if this driver needs to change the PLL values to achieve * any frequency changes. This is really only need by devices like the * S3C2410 where there is no or limited divider between the PLL and the * ARMCLK. diff --git a/arch/cris/arch-v10/lib/old_checksum.c b/arch/cris/arch-v10/lib/old_checksum.c index 1734b467efa6..8f79163f1394 100644 --- a/arch/cris/arch-v10/lib/old_checksum.c +++ b/arch/cris/arch-v10/lib/old_checksum.c @@ -77,7 +77,7 @@ __wsum csum_partial(const void *p, int len, __wsum __sum) sum += *buff++; if (endMarker > buff) - sum += *(const u8 *)buff; /* add extra byte seperately */ + sum += *(const u8 *)buff; /* add extra byte separately */ BITOFF; return (__force __wsum)sum; diff --git a/arch/cris/arch-v32/mm/tlb.c b/arch/cris/arch-v32/mm/tlb.c index 6779bcb28ab0..c030d020660a 100644 --- a/arch/cris/arch-v32/mm/tlb.c +++ b/arch/cris/arch-v32/mm/tlb.c @@ -189,7 +189,7 @@ switch_mm(struct mm_struct *prev, struct mm_struct *next, spin_unlock(&mmu_context_lock); /* - * Remember the pgd for the fault handlers. Keep a seperate + * Remember the pgd for the fault handlers. Keep a separate * copy of it because current and active_mm might be invalid * at points where * there's still a need to derefer the pgd. */ diff --git a/arch/h8300/include/asm/io.h b/arch/h8300/include/asm/io.h index 33e842f3284b..c1a8df22080f 100644 --- a/arch/h8300/include/asm/io.h +++ b/arch/h8300/include/asm/io.h @@ -25,7 +25,7 @@ * memory location directly. */ /* ++roman: The assignments to temp. vars avoid that gcc sometimes generates - * two accesses to memory, which may be undesireable for some devices. + * two accesses to memory, which may be undesirable for some devices. */ /* diff --git a/arch/ia64/sn/kernel/setup.c b/arch/ia64/sn/kernel/setup.c index ece1bf994499..c6c6d9381126 100644 --- a/arch/ia64/sn/kernel/setup.c +++ b/arch/ia64/sn/kernel/setup.c @@ -241,7 +241,7 @@ static void __cpuinit sn_check_for_wars(void) * Note: This stuff is duped here because Altix requires the PCDP to * locate a usable VGA device due to lack of proper ACPI support. Structures * could be used from drivers/firmware/pcdp.h, but it was decided that moving - * this file to a more public location just for Altix use was undesireable. + * this file to a more public location just for Altix use was undesirable. */ struct hcdp_uart_desc { diff --git a/arch/m68k/atari/atakeyb.c b/arch/m68k/atari/atakeyb.c index 4add96d13b19..5890897d28bf 100644 --- a/arch/m68k/atari/atakeyb.c +++ b/arch/m68k/atari/atakeyb.c @@ -121,7 +121,7 @@ KEYBOARD_STATE kb_state; * bytes have been lost and in which state of the packet structure we are now. * This usually causes keyboards bytes to be interpreted as mouse movements * and vice versa, which is very annoying. It seems better to throw away some - * bytes (that are usually mouse bytes) than to misinterpret them. Therefor I + * bytes (that are usually mouse bytes) than to misinterpret them. Therefore I * introduced the RESYNC state for IKBD data. In this state, the bytes up to * one that really looks like a key event (0x04..0xf2) or the start of a mouse * packet (0xf8..0xfb) are thrown away, but at most 2 bytes. This at least diff --git a/arch/m68k/include/asm/io_no.h b/arch/m68k/include/asm/io_no.h index 359065d5a9f2..6e2413e518cb 100644 --- a/arch/m68k/include/asm/io_no.h +++ b/arch/m68k/include/asm/io_no.h @@ -16,7 +16,7 @@ * memory location directly. */ /* ++roman: The assignments to temp. vars avoid that gcc sometimes generates - * two accesses to memory, which may be undesireable for some devices. + * two accesses to memory, which may be undesirable for some devices. */ /* diff --git a/arch/powerpc/boot/dts/kmeter1.dts b/arch/powerpc/boot/dts/kmeter1.dts index 65b8b4f27efe..d8b5d12fb663 100644 --- a/arch/powerpc/boot/dts/kmeter1.dts +++ b/arch/powerpc/boot/dts/kmeter1.dts @@ -490,7 +490,7 @@ compatible = "cfi-flash"; /* * The Intel P30 chip has 2 non-identical chips on - * one die, so we need to define 2 seperate regions + * one die, so we need to define 2 separate regions * that are scanned by physmap_of independantly. */ reg = <0 0x00000000 0x02000000 diff --git a/arch/s390/include/asm/cio.h b/arch/s390/include/asm/cio.h index e85679af54dd..e34347d567a6 100644 --- a/arch/s390/include/asm/cio.h +++ b/arch/s390/include/asm/cio.h @@ -20,7 +20,7 @@ /** * struct ccw1 - channel command word * @cmd_code: command code - * @flags: flags, like IDA adressing, etc. + * @flags: flags, like IDA addressing, etc. * @count: byte count * @cda: data address * diff --git a/arch/s390/kernel/sclp.S b/arch/s390/kernel/sclp.S index e27ca63076d1..27c1a2e236d1 100644 --- a/arch/s390/kernel/sclp.S +++ b/arch/s390/kernel/sclp.S @@ -221,7 +221,7 @@ _sclp_print: lh %r9,0(%r8) # update sccb length ar %r9,%r6 sth %r9,0(%r8) - ar %r7,%r6 # update current mto adress + ar %r7,%r6 # update current mto address ltr %r0,%r0 # more characters? jnz .LinitmtoS4 l %r2,.LwritedataS4-.LbaseS4(%r13)# write data diff --git a/arch/sparc/kernel/leon_kernel.c b/arch/sparc/kernel/leon_kernel.c index 87f1760c0aa2..554e0b80bcde 100644 --- a/arch/sparc/kernel/leon_kernel.c +++ b/arch/sparc/kernel/leon_kernel.c @@ -124,7 +124,7 @@ void __init leon_init_timers(irq_handler_t counter_fn) if (!(LEON3_BYPASS_LOAD_PA(&leon3_gptimer_regs->config) & (1< -/* return adress at 0 */ +/* return address at 0 */ #define in_blk 12 /* input byte array address parameter*/ #define out_blk 8 /* output byte array address parameter*/ @@ -230,8 +230,8 @@ twofish_enc_blk: push %edi mov tfm + 16(%esp), %ebp /* abuse the base pointer: set new base bointer to the crypto tfm */ - add $crypto_tfm_ctx_offset, %ebp /* ctx adress */ - mov in_blk+16(%esp),%edi /* input adress in edi */ + add $crypto_tfm_ctx_offset, %ebp /* ctx address */ + mov in_blk+16(%esp),%edi /* input address in edi */ mov (%edi), %eax mov b_offset(%edi), %ebx @@ -286,8 +286,8 @@ twofish_dec_blk: mov tfm + 16(%esp), %ebp /* abuse the base pointer: set new base bointer to the crypto tfm */ - add $crypto_tfm_ctx_offset, %ebp /* ctx adress */ - mov in_blk+16(%esp),%edi /* input adress in edi */ + add $crypto_tfm_ctx_offset, %ebp /* ctx address */ + mov in_blk+16(%esp),%edi /* input address in edi */ mov (%edi), %eax mov b_offset(%edi), %ebx diff --git a/arch/x86/crypto/twofish-x86_64-asm_64.S b/arch/x86/crypto/twofish-x86_64-asm_64.S index 35974a586615..573aa102542e 100644 --- a/arch/x86/crypto/twofish-x86_64-asm_64.S +++ b/arch/x86/crypto/twofish-x86_64-asm_64.S @@ -221,11 +221,11 @@ twofish_enc_blk: pushq R1 - /* %rdi contains the crypto tfm adress */ - /* %rsi contains the output adress */ - /* %rdx contains the input adress */ - add $crypto_tfm_ctx_offset, %rdi /* set ctx adress */ - /* ctx adress is moved to free one non-rex register + /* %rdi contains the crypto tfm address */ + /* %rsi contains the output address */ + /* %rdx contains the input address */ + add $crypto_tfm_ctx_offset, %rdi /* set ctx address */ + /* ctx address is moved to free one non-rex register as target for the 8bit high operations */ mov %rdi, %r11 @@ -274,11 +274,11 @@ twofish_enc_blk: twofish_dec_blk: pushq R1 - /* %rdi contains the crypto tfm adress */ - /* %rsi contains the output adress */ - /* %rdx contains the input adress */ - add $crypto_tfm_ctx_offset, %rdi /* set ctx adress */ - /* ctx adress is moved to free one non-rex register + /* %rdi contains the crypto tfm address */ + /* %rsi contains the output address */ + /* %rdx contains the input address */ + add $crypto_tfm_ctx_offset, %rdi /* set ctx address */ + /* ctx address is moved to free one non-rex register as target for the 8bit high operations */ mov %rdi, %r11 diff --git a/arch/x86/kernel/head_64.S b/arch/x86/kernel/head_64.S index 2d8b5035371c..3d1e6f16b7a6 100644 --- a/arch/x86/kernel/head_64.S +++ b/arch/x86/kernel/head_64.S @@ -27,7 +27,7 @@ #define GET_CR2_INTO_RCX movq %cr2, %rcx #endif -/* we are not able to switch in one step to the final KERNEL ADRESS SPACE +/* we are not able to switch in one step to the final KERNEL ADDRESS SPACE * because we need identity-mapped pages. * */ diff --git a/arch/x86/kernel/pci-calgary_64.c b/arch/x86/kernel/pci-calgary_64.c index 2bbde6078143..fb99f7edb341 100644 --- a/arch/x86/kernel/pci-calgary_64.c +++ b/arch/x86/kernel/pci-calgary_64.c @@ -1309,7 +1309,7 @@ static void calgary_init_bitmap_from_tce_table(struct iommu_table *tbl) /* * get_tce_space_from_tar(): * Function for kdump case. Get the tce tables from first kernel - * by reading the contents of the base adress register of calgary iommu + * by reading the contents of the base address register of calgary iommu */ static void __init get_tce_space_from_tar(void) { diff --git a/arch/x86/kernel/tsc.c b/arch/x86/kernel/tsc.c index 597683aa5ba0..dec8f68e3eda 100644 --- a/arch/x86/kernel/tsc.c +++ b/arch/x86/kernel/tsc.c @@ -50,7 +50,7 @@ u64 native_sched_clock(void) * unstable. We do this because unlike Time Of Day, * the scheduler clock tolerates small errors and it's * very important for it to be as fast as the platform - * can achive it. ) + * can achieve it. ) */ if (unlikely(tsc_disabled)) { /* No locking but a rare wrong value is not a big deal: */ diff --git a/arch/xtensa/kernel/entry.S b/arch/xtensa/kernel/entry.S index 80d24c485fd3..77fc9f6dc016 100644 --- a/arch/xtensa/kernel/entry.S +++ b/arch/xtensa/kernel/entry.S @@ -104,7 +104,7 @@ * excsave has been restored, and * stack pointer (a1) has been set. * - * Note: _user_exception might be at an odd adress. Don't use call0..call12 + * Note: _user_exception might be at an odd address. Don't use call0..call12 */ ENTRY(user_exception) @@ -244,7 +244,7 @@ _user_exception: * excsave has been restored, and * stack pointer (a1) has been set. * - * Note: _kernel_exception might be at an odd adress. Don't use call0..call12 + * Note: _kernel_exception might be at an odd address. Don't use call0..call12 */ ENTRY(kernel_exception) diff --git a/block/bsg.c b/block/bsg.c index a9fd2d84b53a..46597a6bd112 100644 --- a/block/bsg.c +++ b/block/bsg.c @@ -260,7 +260,7 @@ bsg_map_hdr(struct bsg_device *bd, struct sg_io_v4 *hdr, fmode_t has_write_perm, return ERR_PTR(ret); /* - * map scatter-gather elements seperately and string them to request + * map scatter-gather elements separately and string them to request */ rq = blk_get_request(q, rw, GFP_KERNEL); if (!rq) diff --git a/drivers/acpi/dock.c b/drivers/acpi/dock.c index bbc2c1315c47..d7f363f9435f 100644 --- a/drivers/acpi/dock.c +++ b/drivers/acpi/dock.c @@ -605,7 +605,7 @@ register_hotplug_dock_device(acpi_handle handle, struct acpi_dock_ops *ops, list_for_each_entry(dock_station, &dock_stations, sibling) { /* * An ATA bay can be in a dock and itself can be ejected - * seperately, so there are two 'dock stations' which need the + * separately, so there are two 'dock stations' which need the * ops */ dd = find_dock_dependent_device(dock_station, handle); diff --git a/drivers/ata/libata-sff.c b/drivers/ata/libata-sff.c index 741065c9da67..7f2c94a07c00 100644 --- a/drivers/ata/libata-sff.c +++ b/drivers/ata/libata-sff.c @@ -2258,7 +2258,7 @@ EXPORT_SYMBOL_GPL(ata_sff_postreset); * @qc: command * * Drain the FIFO and device of any stuck data following a command - * failing to complete. In some cases this is neccessary before a + * failing to complete. In some cases this is necessary before a * reset will recover the device. * */ diff --git a/drivers/ata/pata_acpi.c b/drivers/ata/pata_acpi.c index d8f35fe44421..9e33da9565d9 100644 --- a/drivers/ata/pata_acpi.c +++ b/drivers/ata/pata_acpi.c @@ -161,7 +161,7 @@ static void pacpi_set_dmamode(struct ata_port *ap, struct ata_device *adev) * * Called when the libata layer is about to issue a command. We wrap * this interface so that we can load the correct ATA timings if - * neccessary. + * necessary. */ static unsigned int pacpi_qc_issue(struct ata_queued_cmd *qc) diff --git a/drivers/ata/pata_hpt3x3.c b/drivers/ata/pata_hpt3x3.c index c86c71639a95..727a81ce4c9f 100644 --- a/drivers/ata/pata_hpt3x3.c +++ b/drivers/ata/pata_hpt3x3.c @@ -180,7 +180,7 @@ static void hpt3x3_init_chipset(struct pci_dev *dev) * @id: Entry in match table * * Perform basic initialisation. We set the device up so we access all - * ports via BAR4. This is neccessary to work around errata. + * ports via BAR4. This is necessary to work around errata. */ static int hpt3x3_init_one(struct pci_dev *pdev, const struct pci_device_id *id) diff --git a/drivers/ata/pata_pcmcia.c b/drivers/ata/pata_pcmcia.c index 1b392c9e8531..416aebb8b913 100644 --- a/drivers/ata/pata_pcmcia.c +++ b/drivers/ata/pata_pcmcia.c @@ -131,7 +131,7 @@ static unsigned int ata_data_xfer_8bit(struct ata_device *dev, * @qc: command * * Drain the FIFO and device of any stuck data following a command - * failing to complete. In some cases this is neccessary before a + * failing to complete. In some cases this is necessary before a * reset will recover the device. * */ diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h index 2bf3a6ef3684..d9301e861d9f 100644 --- a/drivers/block/drbd/drbd_int.h +++ b/drivers/block/drbd/drbd_int.h @@ -95,7 +95,7 @@ extern char usermode_helper[]; /* All EEs on the free list should have ID_VACANT (== 0) * freshly allocated EEs get !ID_VACANT (== 1) - * so if it says "cannot dereference null pointer at adress 0x00000001", + * so if it says "cannot dereference null pointer at address 0x00000001", * it is most likely one of these :( */ #define ID_IN_SYNC (4711ULL) @@ -1171,7 +1171,7 @@ extern int drbd_bitmap_io(struct drbd_conf *mdev, int (*io_fn)(struct drbd_conf /* Meta data layout We reserve a 128MB Block (4k aligned) * either at the end of the backing device - * or on a seperate meta data device. */ + * or on a separate meta data device. */ #define MD_RESERVED_SECT (128LU << 11) /* 128 MB, unit sectors */ /* The following numbers are sectors */ diff --git a/drivers/block/drbd/drbd_req.h b/drivers/block/drbd/drbd_req.h index f22c1bc8ec7e..16119d7056cc 100644 --- a/drivers/block/drbd/drbd_req.h +++ b/drivers/block/drbd/drbd_req.h @@ -57,7 +57,7 @@ * * It may me handed over to the local disk subsystem. * It may be completed by the local disk subsystem, - * either sucessfully or with io-error. + * either successfully or with io-error. * In case it is a READ request, and it failed locally, * it may be retried remotely. * diff --git a/drivers/char/agp/intel-agp.c b/drivers/char/agp/intel-agp.c index 3999a5f25f38..45a22f9bfec2 100644 --- a/drivers/char/agp/intel-agp.c +++ b/drivers/char/agp/intel-agp.c @@ -269,7 +269,7 @@ static void intel_agp_insert_sg_entries(struct agp_memory *mem, j++; } } else { - /* sg may merge pages, but we have to seperate + /* sg may merge pages, but we have to separate * per-page addr for GTT */ unsigned int len, m; diff --git a/drivers/char/applicom.c b/drivers/char/applicom.c index fe2cb2f5db17..a7424bf7eacf 100644 --- a/drivers/char/applicom.c +++ b/drivers/char/applicom.c @@ -14,7 +14,7 @@ /* et passe en argument a acinit, mais est scrute sur le bus pour s'adapter */ /* au nombre de cartes presentes sur le bus. IOCL code 6 affichait V2.4.3 */ /* F.LAFORSE 28/11/95 creation de fichiers acXX.o avec les differentes */ -/* adresses de base des cartes, IOCTL 6 plus complet */ +/* addresses de base des cartes, IOCTL 6 plus complet */ /* J.PAGET le 19/08/96 copie de la version V2.6 en V2.8.0 sans modification */ /* de code autre que le texte V2.6.1 en V2.8.0 */ /*****************************************************************************/ diff --git a/drivers/char/hvc_iseries.c b/drivers/char/hvc_iseries.c index 936d05bf37fa..0794925d8042 100644 --- a/drivers/char/hvc_iseries.c +++ b/drivers/char/hvc_iseries.c @@ -353,7 +353,7 @@ static void hvc_close_event(struct HvLpEvent *event) if (!hvlpevent_is_int(event)) { printk(KERN_WARNING - "hvc: got unexpected close acknowlegement\n"); + "hvc: got unexpected close acknowledgement\n"); return; } diff --git a/drivers/char/hw_random/n2-drv.c b/drivers/char/hw_random/n2-drv.c index 9b3e09cd41f9..10f868eefaa6 100644 --- a/drivers/char/hw_random/n2-drv.c +++ b/drivers/char/hw_random/n2-drv.c @@ -71,7 +71,7 @@ MODULE_VERSION(DRV_MODULE_VERSION); * x22 + x21 + x17 + x15 + x13 + x12 + x11 + x7 + x5 + x + 1 * * The RNG_CTL_VCO value of each noise cell must be programmed - * seperately. This is why 4 control register values must be provided + * separately. This is why 4 control register values must be provided * to the hypervisor. During a write, the hypervisor writes them all, * one at a time, to the actual RNG_CTL register. The first three * values are used to setup the desired RNG_CTL_VCO for each entropy diff --git a/drivers/char/ip2/i2hw.h b/drivers/char/ip2/i2hw.h index 8aa6e7ab8d5b..c0ba6c05f0cd 100644 --- a/drivers/char/ip2/i2hw.h +++ b/drivers/char/ip2/i2hw.h @@ -559,7 +559,7 @@ Loadware may be sent to the board in two ways: 2) It may be hard-coded into your source by including a .h file (typically supplied by Computone), which declares a data array and initializes every - element. This acheives the same result as if an entire loadware file had + element. This achieves the same result as if an entire loadware file had been read into the array. This requires more data space in your program, but access to the file system diff --git a/drivers/char/pty.c b/drivers/char/pty.c index 385c44b3034f..5ee424817263 100644 --- a/drivers/char/pty.c +++ b/drivers/char/pty.c @@ -220,7 +220,7 @@ static void pty_set_termios(struct tty_struct *tty, * @tty: tty being resized * @ws: window size being set. * - * Update the termios variables and send the neccessary signals to + * Update the termios variables and send the necessary signals to * peform a terminal resize correctly */ diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c index c6f3b48be9dd..56b11c1c7aeb 100644 --- a/drivers/char/tty_io.c +++ b/drivers/char/tty_io.c @@ -2026,7 +2026,7 @@ static int tiocgwinsz(struct tty_struct *tty, struct winsize __user *arg) * @rows: rows (character) * @cols: cols (character) * - * Update the termios variables and send the neccessary signals to + * Update the termios variables and send the necessary signals to * peform a terminal resize correctly */ diff --git a/drivers/char/vt.c b/drivers/char/vt.c index 94f530a29691..bd1d1164fec5 100644 --- a/drivers/char/vt.c +++ b/drivers/char/vt.c @@ -821,7 +821,7 @@ static inline int resize_screen(struct vc_data *vc, int width, int height, * * Resize a virtual console, clipping according to the actual constraints. * If the caller passes a tty structure then update the termios winsize - * information and perform any neccessary signal handling. + * information and perform any necessary signal handling. * * Caller must hold the console semaphore. Takes the termios mutex and * ctrl_lock of the tty IFF a tty is passed. diff --git a/drivers/dma/coh901318_lli.h b/drivers/dma/coh901318_lli.h index 7bf713b79c6b..7a5c80990e9e 100644 --- a/drivers/dma/coh901318_lli.h +++ b/drivers/dma/coh901318_lli.h @@ -30,7 +30,7 @@ struct device; * @pool: pool handle * @dev: dma device * @lli_nbr: number of lli:s in the pool - * @algin: adress alignemtn of lli:s + * @algin: address alignemtn of lli:s * returns 0 on success otherwise none zero */ int coh901318_pool_create(struct coh901318_pool *pool, diff --git a/drivers/gpu/drm/nouveau/nouveau_bios.c b/drivers/gpu/drm/nouveau/nouveau_bios.c index d7f8d8b4a4b8..52fb371784e1 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bios.c +++ b/drivers/gpu/drm/nouveau/nouveau_bios.c @@ -3544,7 +3544,7 @@ int nouveau_bios_parse_lvds_table(struct drm_device *dev, int pxclk, bool *dl, b * at which modes should be set up in the dual link style. * * Following the header, the BMP (ver 0xa) table has several records, - * indexed by a seperate xlat table, indexed in turn by the fp strap in + * indexed by a separate xlat table, indexed in turn by the fp strap in * EXTDEV_BOOT. Each record had a config byte, followed by 6 script * numbers for use by INIT_SUB which controlled panel init and power, * and finally a dword of ms to sleep between power off and on diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h index 6b9690418bc7..23664058690f 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.h +++ b/drivers/gpu/drm/nouveau/nouveau_drv.h @@ -544,7 +544,7 @@ struct drm_nouveau_private { uint32_t ramro_offset; uint32_t ramro_size; - /* base physical adresses */ + /* base physical addresses */ uint64_t fb_phys; uint64_t fb_available_size; uint64_t fb_mappable_pages; diff --git a/drivers/gpu/drm/via/via_irq.c b/drivers/gpu/drm/via/via_irq.c index 5935b8842e86..34079f251cd4 100644 --- a/drivers/gpu/drm/via/via_irq.c +++ b/drivers/gpu/drm/via/via_irq.c @@ -150,7 +150,7 @@ irqreturn_t via_driver_irq_handler(DRM_IRQ_ARGS) cur_irq++; } - /* Acknowlege interrupts */ + /* Acknowledge interrupts */ VIA_WRITE(VIA_REG_INTERRUPT, status); @@ -165,7 +165,7 @@ static __inline__ void viadrv_acknowledge_irqs(drm_via_private_t * dev_priv) u32 status; if (dev_priv) { - /* Acknowlege interrupts */ + /* Acknowledge interrupts */ status = VIA_READ(VIA_REG_INTERRUPT); VIA_WRITE(VIA_REG_INTERRUPT, status | dev_priv->irq_pending_mask); diff --git a/drivers/i2c/busses/i2c-pxa.c b/drivers/i2c/busses/i2c-pxa.c index 7647a20523a0..90ffbf6f9d4f 100644 --- a/drivers/i2c/busses/i2c-pxa.c +++ b/drivers/i2c/busses/i2c-pxa.c @@ -12,7 +12,7 @@ * * History: * Apr 2002: Initial version [CS] - * Jun 2002: Properly seperated algo/adap [FB] + * Jun 2002: Properly separated algo/adap [FB] * Jan 2003: Fixed several bugs concerning interrupt handling [Kai-Uwe Bloem] * Jan 2003: added limited signal handling [Kai-Uwe Bloem] * Sep 2004: Major rework to ensure efficient bus handling [RMK] diff --git a/drivers/infiniband/hw/ehca/ehca_qes.h b/drivers/infiniband/hw/ehca/ehca_qes.h index 5d28e3e98a20..90c4efa67586 100644 --- a/drivers/infiniband/hw/ehca/ehca_qes.h +++ b/drivers/infiniband/hw/ehca/ehca_qes.h @@ -46,7 +46,7 @@ #include "ehca_tools.h" -/* virtual scatter gather entry to specify remote adresses with length */ +/* virtual scatter gather entry to specify remote addresses with length */ struct ehca_vsgentry { u64 vaddr; u32 lkey; @@ -148,7 +148,7 @@ struct ehca_wqe { u32 immediate_data; union { struct { - u64 remote_virtual_adress; + u64 remote_virtual_address; u32 rkey; u32 reserved; u64 atomic_1st_op_dma_len; diff --git a/drivers/infiniband/hw/ehca/ehca_reqs.c b/drivers/infiniband/hw/ehca/ehca_reqs.c index e3ec7fdd67bd..9a3fbfca9b41 100644 --- a/drivers/infiniband/hw/ehca/ehca_reqs.c +++ b/drivers/infiniband/hw/ehca/ehca_reqs.c @@ -269,7 +269,7 @@ static inline int ehca_write_swqe(struct ehca_qp *qp, /* no break is intentional here */ case IB_QPT_RC: /* TODO: atomic not implemented */ - wqe_p->u.nud.remote_virtual_adress = + wqe_p->u.nud.remote_virtual_address = send_wr->wr.rdma.remote_addr; wqe_p->u.nud.rkey = send_wr->wr.rdma.rkey; diff --git a/drivers/input/misc/yealink.h b/drivers/input/misc/yealink.h index 48af0be9cbdf..1e0f52397010 100644 --- a/drivers/input/misc/yealink.h +++ b/drivers/input/misc/yealink.h @@ -127,7 +127,7 @@ struct yld_ctl_packet { * yld_status struct. */ -/* LCD, each segment must be driven seperately. +/* LCD, each segment must be driven separately. * * Layout: * diff --git a/drivers/isdn/i4l/isdn_common.c b/drivers/isdn/i4l/isdn_common.c index adb1e8c36b46..00c60e2e0ff7 100644 --- a/drivers/isdn/i4l/isdn_common.c +++ b/drivers/isdn/i4l/isdn_common.c @@ -1347,7 +1347,7 @@ isdn_ioctl(struct inode *inode, struct file *file, uint cmd, ulong arg) /* * isdn net devices manage lots of configuration variables as linked lists. * Those lists must only be manipulated from user space. Some of the ioctl's - * service routines access user space and are not atomic. Therefor, ioctl's + * service routines access user space and are not atomic. Therefore, ioctl's * manipulating the lists and ioctl's sleeping while accessing the lists * are serialized by means of a semaphore. */ diff --git a/drivers/media/dvb/dvb-core/dvb_frontend.h b/drivers/media/dvb/dvb-core/dvb_frontend.h index 52e4ce4304ee..80dda308ff74 100644 --- a/drivers/media/dvb/dvb-core/dvb_frontend.h +++ b/drivers/media/dvb/dvb-core/dvb_frontend.h @@ -214,14 +214,14 @@ struct dvb_tuner_ops { int (*get_status)(struct dvb_frontend *fe, u32 *status); int (*get_rf_strength)(struct dvb_frontend *fe, u16 *strength); - /** These are provided seperately from set_params in order to facilitate silicon - * tuners which require sophisticated tuning loops, controlling each parameter seperately. */ + /** These are provided separately from set_params in order to facilitate silicon + * tuners which require sophisticated tuning loops, controlling each parameter separately. */ int (*set_frequency)(struct dvb_frontend *fe, u32 frequency); int (*set_bandwidth)(struct dvb_frontend *fe, u32 bandwidth); /* - * These are provided seperately from set_params in order to facilitate silicon - * tuners which require sophisticated tuning loops, controlling each parameter seperately. + * These are provided separately from set_params in order to facilitate silicon + * tuners which require sophisticated tuning loops, controlling each parameter separately. */ int (*set_state)(struct dvb_frontend *fe, enum tuner_param param, struct tuner_state *state); int (*get_state)(struct dvb_frontend *fe, enum tuner_param param, struct tuner_state *state); diff --git a/drivers/media/video/bt8xx/bttv-cards.c b/drivers/media/video/bt8xx/bttv-cards.c index 12279f6d9bc4..716870ae85d5 100644 --- a/drivers/media/video/bt8xx/bttv-cards.c +++ b/drivers/media/video/bt8xx/bttv-cards.c @@ -4404,7 +4404,7 @@ static void rv605_muxsel(struct bttv *btv, unsigned int input) /* Tibet Systems 'Progress DVR' CS16 muxsel helper [Chris Fanning] * * The CS16 (available on eBay cheap) is a PCI board with four Fusion - * 878A chips, a PCI bridge, an Atmel microcontroller, four sync seperator + * 878A chips, a PCI bridge, an Atmel microcontroller, four sync separator * chips, ten eight input analog multiplexors, a not chip and a few * other components. * @@ -4426,7 +4426,7 @@ static void rv605_muxsel(struct bttv *btv, unsigned int input) * * There is an ATMEL microcontroller with an 8031 core on board. I have not * determined what function (if any) it provides. With the microcontroller - * and sync seperator chips a guess is that it might have to do with video + * and sync separator chips a guess is that it might have to do with video * switching and maybe some digital I/O. */ static void tibetCS16_muxsel(struct bttv *btv, unsigned int input) diff --git a/drivers/media/video/gspca/ov519.c b/drivers/media/video/gspca/ov519.c index b4f965731244..e5e4c4440d39 100644 --- a/drivers/media/video/gspca/ov519.c +++ b/drivers/media/video/gspca/ov519.c @@ -503,7 +503,7 @@ static const struct v4l2_pix_format ovfx2_ov3610_mode[] = { /* * The FX2 chip does not give us a zero length read at end of frame. * It does, however, give a short read at the end of a frame, if - * neccessary, rather than run two frames together. + * necessary, rather than run two frames together. * * By choosing the right bulk transfer size, we are guaranteed to always * get a short read for the last read of each frame. Frame sizes are diff --git a/drivers/media/video/pwc/philips.txt b/drivers/media/video/pwc/philips.txt index f9f3584281d8..d38dd791511e 100644 --- a/drivers/media/video/pwc/philips.txt +++ b/drivers/media/video/pwc/philips.txt @@ -33,7 +33,7 @@ a lot of extra information, a FAQ, and the binary plugin 'PWCX'. This plugin contains decompression routines that allow you to use higher image sizes and framerates; in addition the webcam uses less bandwidth on the USB bus (handy if you want to run more than 1 camera simultaneously). These routines fall -under a NDA, and may therefor not be distributed as source; however, its use +under a NDA, and may therefore not be distributed as source; however, its use is completely optional. You can build this code either into your kernel, or as a module. I recommend diff --git a/drivers/media/video/sn9c102/sn9c102_sensor.h b/drivers/media/video/sn9c102/sn9c102_sensor.h index 4af7382da5c5..494957b10bac 100644 --- a/drivers/media/video/sn9c102/sn9c102_sensor.h +++ b/drivers/media/video/sn9c102/sn9c102_sensor.h @@ -120,7 +120,7 @@ extern int sn9c102_write_regs(struct sn9c102_device*, const u8 valreg[][2], /* Write multiple registers with constant values. For example: sn9c102_write_const_regs(cam, {0x00, 0x14}, {0x60, 0x17}, {0x0f, 0x18}); - Register adresses must be < 256. + Register addresses must be < 256. */ #define sn9c102_write_const_regs(sn9c102_device, data...) \ ({ static const u8 _valreg[][2] = {data}; \ diff --git a/drivers/media/video/tea6420.c b/drivers/media/video/tea6420.c index 0446524d3543..6bf6bc7dbc7f 100644 --- a/drivers/media/video/tea6420.c +++ b/drivers/media/video/tea6420.c @@ -6,7 +6,7 @@ The tea6420 is a bus controlled audio-matrix with 5 stereo inputs, 4 stereo outputs and gain control for each output. - It is cascadable, i.e. it can be found at the adresses 0x98 + It is cascadable, i.e. it can be found at the addresses 0x98 and 0x9a on the i2c-bus. For detailed informations download the specifications directly diff --git a/drivers/mfd/sm501.c b/drivers/mfd/sm501.c index 0cc5eeff5ee8..10491e4e305d 100644 --- a/drivers/mfd/sm501.c +++ b/drivers/mfd/sm501.c @@ -523,7 +523,7 @@ unsigned long sm501_set_clock(struct device *dev, unsigned long clock = readl(sm->regs + SM501_CURRENT_CLOCK); unsigned char reg; unsigned int pll_reg = 0; - unsigned long sm501_freq; /* the actual frequency acheived */ + unsigned long sm501_freq; /* the actual frequency achieved */ struct sm501_clock to; @@ -533,7 +533,7 @@ unsigned long sm501_set_clock(struct device *dev, switch (clksrc) { case SM501_CLOCK_P2XCLK: - /* This clock is divided in half so to achive the + /* This clock is divided in half so to achieve the * requested frequency the value must be multiplied by * 2. This clock also has an additional pre divisor */ @@ -562,7 +562,7 @@ unsigned long sm501_set_clock(struct device *dev, break; case SM501_CLOCK_V2XCLK: - /* This clock is divided in half so to achive the + /* This clock is divided in half so to achieve the * requested frequency the value must be multiplied by 2. */ sm501_freq = (sm501_select_clock(2 * req_freq, &to, 3) / 2); @@ -648,7 +648,7 @@ unsigned long sm501_find_clock(struct device *dev, unsigned long req_freq) { struct sm501_devdata *sm = dev_get_drvdata(dev); - unsigned long sm501_freq; /* the frequency achiveable by the 501 */ + unsigned long sm501_freq; /* the frequency achieveable by the 501 */ struct sm501_clock to; switch (clksrc) { diff --git a/drivers/mmc/host/mxcmmc.c b/drivers/mmc/host/mxcmmc.c index 60a2b69e54f5..16cc91c827c9 100644 --- a/drivers/mmc/host/mxcmmc.c +++ b/drivers/mmc/host/mxcmmc.c @@ -4,7 +4,7 @@ * This is a driver for the SDHC controller found in Freescale MX2/MX3 * SoCs. It is basically the same hardware as found on MX1 (imxmmc.c). * Unlike the hardware found on MX1, this hardware just works and does - * not need all the quirks found in imxmmc.c, hence the seperate driver. + * not need all the quirks found in imxmmc.c, hence the separate driver. * * Copyright (C) 2008 Sascha Hauer, Pengutronix * Copyright (C) 2006 Pavel Pisa, PiKRON diff --git a/drivers/mtd/chips/jedec_probe.c b/drivers/mtd/chips/jedec_probe.c index 1bec5e1ce6ac..8db1148dfa47 100644 --- a/drivers/mtd/chips/jedec_probe.c +++ b/drivers/mtd/chips/jedec_probe.c @@ -226,7 +226,7 @@ struct unlock_addr { * exists, but is for MTD_UADDR_NOT_SUPPORTED - and, therefore, * should not be used. The problem is that structures with * initializers have extra fields initialized to 0. It is _very_ - * desireable to have the unlock address entries for unsupported + * desirable to have the unlock address entries for unsupported * data widths automatically initialized - that means that * MTD_UADDR_NOT_SUPPORTED must be 0 and the first entry here * must go unused. diff --git a/drivers/mtd/nand/bcm_umi_nand.c b/drivers/mtd/nand/bcm_umi_nand.c index 087bcd745bb7..7d1cca7a31a9 100644 --- a/drivers/mtd/nand/bcm_umi_nand.c +++ b/drivers/mtd/nand/bcm_umi_nand.c @@ -381,7 +381,7 @@ static int __devinit bcm_umi_nand_probe(struct platform_device *pdev) if (!r) return -ENXIO; - /* map physical adress */ + /* map physical address */ bcm_umi_io_base = ioremap(r->start, r->end - r->start + 1); if (!bcm_umi_io_base) { @@ -525,7 +525,7 @@ static int bcm_umi_nand_remove(struct platform_device *pdev) /* Release resources, unregister device */ nand_release(board_mtd); - /* unmap physical adress */ + /* unmap physical address */ iounmap(bcm_umi_io_base); /* Free the MTD device structure */ diff --git a/drivers/mtd/nand/mxc_nand.c b/drivers/mtd/nand/mxc_nand.c index 45dec5770da0..b2900d8406d3 100644 --- a/drivers/mtd/nand/mxc_nand.c +++ b/drivers/mtd/nand/mxc_nand.c @@ -507,7 +507,7 @@ static void mxc_do_addr_cycle(struct mtd_info *mtd, int column, int page_addr) * MXC NANDFC can only perform full page+spare or * spare-only read/write. When the upper layers * layers perform a read/write buf operation, - * we will used the saved column adress to index into + * we will used the saved column address to index into * the full page. */ send_addr(host, 0, page_addr == -1); diff --git a/drivers/net/atlx/atl2.h b/drivers/net/atlx/atl2.h index d918bbe621ea..927e4de6474d 100644 --- a/drivers/net/atlx/atl2.h +++ b/drivers/net/atlx/atl2.h @@ -442,7 +442,7 @@ struct atl2_hw { struct atl2_ring_header { /* pointer to the descriptor ring memory */ void *desc; - /* physical adress of the descriptor ring */ + /* physical address of the descriptor ring */ dma_addr_t dma; /* length of descriptor ring in bytes */ unsigned int size; diff --git a/drivers/net/chelsio/sge.c b/drivers/net/chelsio/sge.c index 109d2783e4d8..bef02330464d 100644 --- a/drivers/net/chelsio/sge.c +++ b/drivers/net/chelsio/sge.c @@ -248,7 +248,7 @@ static void restart_sched(unsigned long); * * Interrupts are handled by a single CPU and it is likely that on a MP system * the application is migrated to another CPU. In that scenario, we try to - * seperate the RX(in irq context) and TX state in order to decrease memory + * separate the RX(in irq context) and TX state in order to decrease memory * contention. */ struct sge { diff --git a/drivers/net/e1000e/82571.c b/drivers/net/e1000e/82571.c index 02d67d047d96..dc4eb87309c5 100644 --- a/drivers/net/e1000e/82571.c +++ b/drivers/net/e1000e/82571.c @@ -1363,7 +1363,7 @@ static s32 e1000_setup_fiber_serdes_link_82571(struct e1000_hw *hw) * * 1) down * 2) autoneg_progress - * 3) autoneg_complete (the link sucessfully autonegotiated) + * 3) autoneg_complete (the link successfully autonegotiated) * 4) forced_up (the link has been forced up, it did not autonegotiate) * **/ diff --git a/drivers/net/e1000e/lib.c b/drivers/net/e1000e/lib.c index 2fa9b36a2c5a..3af0b1b82832 100644 --- a/drivers/net/e1000e/lib.c +++ b/drivers/net/e1000e/lib.c @@ -587,7 +587,7 @@ s32 e1000e_check_for_serdes_link(struct e1000_hw *hw) if (!(rxcw & E1000_RXCW_IV)) { mac->serdes_has_link = true; e_dbg("SERDES: Link up - autoneg " - "completed sucessfully.\n"); + "completed successfully.\n"); } else { mac->serdes_has_link = false; e_dbg("SERDES: Link down - invalid" diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c index 997124d2992a..e2ce8f8a21a7 100644 --- a/drivers/net/igb/igb_main.c +++ b/drivers/net/igb/igb_main.c @@ -674,7 +674,7 @@ static void igb_set_interrupt_capability(struct igb_adapter *adapter) /* start with one vector for every rx queue */ numvecs = adapter->num_rx_queues; - /* if tx handler is seperate add 1 for every tx queue */ + /* if tx handler is separate add 1 for every tx queue */ if (!(adapter->flags & IGB_FLAG_QUEUE_PAIRS)) numvecs += adapter->num_tx_queues; diff --git a/drivers/net/irda/sa1100_ir.c b/drivers/net/irda/sa1100_ir.c index c412e8026173..1dcdce0631aa 100644 --- a/drivers/net/irda/sa1100_ir.c +++ b/drivers/net/irda/sa1100_ir.c @@ -331,7 +331,7 @@ static int sa1100_irda_resume(struct platform_device *pdev) * If we missed a speed change, initialise at the new speed * directly. It is debatable whether this is actually * required, but in the interests of continuing from where - * we left off it is desireable. The converse argument is + * we left off it is desirable. The converse argument is * that we should re-negotiate at 9600 baud again. */ if (si->newspeed) { diff --git a/drivers/net/qlge/qlge_ethtool.c b/drivers/net/qlge/qlge_ethtool.c index 058fa0a48c6f..b8d21ab212c6 100644 --- a/drivers/net/qlge/qlge_ethtool.c +++ b/drivers/net/qlge/qlge_ethtool.c @@ -402,7 +402,7 @@ static int ql_set_wol(struct net_device *ndev, struct ethtool_wolinfo *wol) u32 wol = 0; status = ql_mb_wol_mode(qdev, wol); QPRINTK(qdev, DRV, ERR, "WOL %s (wol code 0x%x) on %s\n", - (status == 0) ? "cleared sucessfully" : "clear failed", + (status == 0) ? "cleared successfully" : "clear failed", wol, qdev->ndev->name); } diff --git a/drivers/net/qlge/qlge_main.c b/drivers/net/qlge/qlge_main.c index 894a7c84faef..a35845b48ea4 100644 --- a/drivers/net/qlge/qlge_main.c +++ b/drivers/net/qlge/qlge_main.c @@ -3517,7 +3517,7 @@ int ql_wol(struct ql_adapter *qdev) wol |= MB_WOL_MODE_ON; status = ql_mb_wol_mode(qdev, wol); QPRINTK(qdev, DRV, ERR, "WOL %s (wol code 0x%x) on %s\n", - (status == 0) ? "Sucessfully set" : "Failed", wol, + (status == 0) ? "Successfully set" : "Failed", wol, qdev->ndev->name); } diff --git a/drivers/net/sfc/regs.h b/drivers/net/sfc/regs.h index 89d606fe9248..18a3be428348 100644 --- a/drivers/net/sfc/regs.h +++ b/drivers/net/sfc/regs.h @@ -95,7 +95,7 @@ #define FRF_AA_INT_ACK_KER_FIELD_LBN 0 #define FRF_AA_INT_ACK_KER_FIELD_WIDTH 32 -/* INT_ISR0_REG: Function 0 Interrupt Acknowlege Status register */ +/* INT_ISR0_REG: Function 0 Interrupt Acknowledge Status register */ #define FR_BZ_INT_ISR0 0x00000090 #define FRF_BZ_INT_ISR_REG_LBN 0 #define FRF_BZ_INT_ISR_REG_WIDTH 64 diff --git a/drivers/net/smsc9420.c b/drivers/net/smsc9420.c index 12f0f5d74e3c..2ae1972bcb46 100644 --- a/drivers/net/smsc9420.c +++ b/drivers/net/smsc9420.c @@ -1348,7 +1348,7 @@ static int smsc9420_open(struct net_device *dev) netif_carrier_off(dev); - /* disable, mask and acknowlege all interrupts */ + /* disable, mask and acknowledge all interrupts */ spin_lock_irqsave(&pd->int_lock, flags); int_cfg = smsc9420_reg_read(pd, INT_CFG) & (~INT_CFG_IRQ_EN_); smsc9420_reg_write(pd, INT_CFG, int_cfg); diff --git a/drivers/net/spider_net.c b/drivers/net/spider_net.c index 218524857bfc..839b1f065d3c 100644 --- a/drivers/net/spider_net.c +++ b/drivers/net/spider_net.c @@ -474,7 +474,7 @@ spider_net_prepare_rx_descr(struct spider_net_card *card, * spider_net_enable_rxchtails - sets RX dmac chain tail addresses * @card: card structure * - * spider_net_enable_rxchtails sets the RX DMAC chain tail adresses in the + * spider_net_enable_rxchtails sets the RX DMAC chain tail addresses in the * chip by writing to the appropriate register. DMA is enabled in * spider_net_enable_rxdmac. */ @@ -1820,7 +1820,7 @@ spider_net_enable_card(struct spider_net_card *card) spider_net_write_reg(card, SPIDER_NET_ECMODE, SPIDER_NET_ECMODE_VALUE); - /* set chain tail adress for RX chains and + /* set chain tail address for RX chains and * enable DMA */ spider_net_enable_rxchtails(card); spider_net_enable_rxdmac(card); diff --git a/drivers/net/sungem.c b/drivers/net/sungem.c index b571a1babab9..a88fcb39ba15 100644 --- a/drivers/net/sungem.c +++ b/drivers/net/sungem.c @@ -782,7 +782,7 @@ static int gem_rx(struct gem *gp, int work_to_do) break; /* When writing back RX descriptor, GEM writes status - * then buffer address, possibly in seperate transactions. + * then buffer address, possibly in separate transactions. * If we don't wait for the chip to write both, we could * post a new buffer to this descriptor then have GEM spam * on the buffer address. We sync on the RX completion diff --git a/drivers/net/tehuti.c b/drivers/net/tehuti.c index 80b404f2b938..ed4e9c42935c 100644 --- a/drivers/net/tehuti.c +++ b/drivers/net/tehuti.c @@ -1857,7 +1857,7 @@ static void bdx_tx_push_desc(struct bdx_priv *priv, void *data, int size) * @data - desc's data * @size - desc's size * - * NOTE: this func does check for available space and, if neccessary, waits for + * NOTE: this func does check for available space and, if necessary, waits for * NIC to read existing data before writing new one. */ static void bdx_tx_push_desc_safe(struct bdx_priv *priv, void *data, int size) diff --git a/drivers/net/tokenring/tms380tr.c b/drivers/net/tokenring/tms380tr.c index e3c42f5ac4a9..4e4c402319c9 100644 --- a/drivers/net/tokenring/tms380tr.c +++ b/drivers/net/tokenring/tms380tr.c @@ -693,7 +693,7 @@ static netdev_tx_t tms380tr_hardware_send_packet(struct sk_buff *skb, * NOTE: This function should be used whenever the status of any TPL must be * modified by the driver, because the compiler may otherwise change the * order of instructions such that writing the TPL status may be executed at - * an undesireable time. When this function is used, the status is always + * an undesirable time. When this function is used, the status is always * written when the function is called. */ static void tms380tr_write_tpl_status(TPL *tpl, unsigned int Status) @@ -2266,7 +2266,7 @@ static void tms380tr_rcv_status_irq(struct net_device *dev) * This function should be used whenever the status of any RPL must be * modified by the driver, because the compiler may otherwise change the * order of instructions such that writing the RPL status may be executed - * at an undesireable time. When this function is used, the status is + * at an undesirable time. When this function is used, the status is * always written when the function is called. */ static void tms380tr_write_rpl_status(RPL *rpl, unsigned int Status) diff --git a/drivers/net/tun.c b/drivers/net/tun.c index 2834a01bae24..e572ecc09a44 100644 --- a/drivers/net/tun.c +++ b/drivers/net/tun.c @@ -1365,7 +1365,7 @@ static int tun_chr_close(struct inode *inode, struct file *file) __tun_detach(tun); - /* If desireable, unregister the netdevice. */ + /* If desirable, unregister the netdevice. */ if (!(tun->flags & TUN_PERSIST)) { rtnl_lock(); if (dev->reg_state == NETREG_REGISTERED) diff --git a/drivers/net/ucc_geth.c b/drivers/net/ucc_geth.c index eb8fe7e16c6c..8eec97799e05 100644 --- a/drivers/net/ucc_geth.c +++ b/drivers/net/ucc_geth.c @@ -429,7 +429,7 @@ static void hw_add_addr_in_hash(struct ucc_geth_private *ugeth, ucc_fast_get_qe_cr_subblock(ugeth->ug_info->uf_info.ucc_num); /* Ethernet frames are defined in Little Endian mode, - therefor to insert */ + therefore to insert */ /* the address to the hash (Big Endian mode), we reverse the bytes.*/ set_mac_addr(&p_82xx_addr_filt->taddr.h, p_enet_addr); diff --git a/drivers/net/wimax/i2400m/fw.c b/drivers/net/wimax/i2400m/fw.c index 64cdfeb299ca..6c459f5cb5df 100644 --- a/drivers/net/wimax/i2400m/fw.c +++ b/drivers/net/wimax/i2400m/fw.c @@ -612,7 +612,7 @@ ssize_t i2400m_bm_cmd(struct i2400m *i2400m, goto error_wait_for_ack; } rx_bytes = result; - /* verify the ack and read more if neccessary [result is the + /* verify the ack and read more if necessary [result is the * final amount of bytes we get in the ack] */ result = __i2400m_bm_ack_verify(i2400m, opcode, ack, ack_size, flags); if (result < 0) diff --git a/drivers/net/wimax/i2400m/i2400m.h b/drivers/net/wimax/i2400m/i2400m.h index 04df9bbe340f..820b128705ec 100644 --- a/drivers/net/wimax/i2400m/i2400m.h +++ b/drivers/net/wimax/i2400m/i2400m.h @@ -627,7 +627,7 @@ enum i2400m_bm_cmd_flags { * @I2400M_BRI_NO_REBOOT: Do not reboot the device and proceed * directly to wait for a reboot barker from the device. * @I2400M_BRI_MAC_REINIT: We need to reinitialize the boot - * rom after reading the MAC adress. This is quite a dirty hack, + * rom after reading the MAC address. This is quite a dirty hack, * if you ask me -- the device requires the bootrom to be * intialized after reading the MAC address. */ diff --git a/drivers/net/wimax/i2400m/sdio.c b/drivers/net/wimax/i2400m/sdio.c index 76a50ac02ebb..14f876b1358b 100644 --- a/drivers/net/wimax/i2400m/sdio.c +++ b/drivers/net/wimax/i2400m/sdio.c @@ -304,7 +304,7 @@ error_kzalloc: * * The device will be fully reset internally, but won't be * disconnected from the bus (so no reenumeration will - * happen). Firmware upload will be neccessary. + * happen). Firmware upload will be necessary. * * The device will send a reboot barker that will trigger the driver * to reinitialize the state via __i2400m_dev_reset_handle. @@ -314,7 +314,7 @@ error_kzalloc: * * The device will be fully reset internally, disconnected from the * bus an a reenumeration will happen. Firmware upload will be - * neccessary. Thus, we don't do any locking or struct + * necessary. Thus, we don't do any locking or struct * reinitialization, as we are going to be fully disconnected and * reenumerated. * diff --git a/drivers/net/wimax/i2400m/usb.c b/drivers/net/wimax/i2400m/usb.c index 98f4f8c5fb68..99f04c475898 100644 --- a/drivers/net/wimax/i2400m/usb.c +++ b/drivers/net/wimax/i2400m/usb.c @@ -246,7 +246,7 @@ error_kzalloc: * * The device will be fully reset internally, but won't be * disconnected from the USB bus (so no reenumeration will - * happen). Firmware upload will be neccessary. + * happen). Firmware upload will be necessary. * * The device will send a reboot barker in the notification endpoint * that will trigger the driver to reinitialize the state @@ -257,7 +257,7 @@ error_kzalloc: * * The device will be fully reset internally, disconnected from the * USB bus an a reenumeration will happen. Firmware upload will be - * neccessary. Thus, we don't do any locking or struct + * necessary. Thus, we don't do any locking or struct * reinitialization, as we are going to be fully disconnected and * reenumerated. * diff --git a/drivers/net/wireless/ath/ar9170/main.c b/drivers/net/wireless/ath/ar9170/main.c index f9d6db8d013e..46a1e19c6787 100644 --- a/drivers/net/wireless/ath/ar9170/main.c +++ b/drivers/net/wireless/ath/ar9170/main.c @@ -2535,7 +2535,7 @@ void *ar9170_alloc(size_t priv_size) /* * this buffer is used for rx stream reconstruction. * Under heavy load this device (or the transport layer?) - * tends to split the streams into seperate rx descriptors. + * tends to split the streams into separate rx descriptors. */ skb = __dev_alloc_skb(AR9170_MAX_RX_BUFFER_SIZE, GFP_KERNEL); diff --git a/drivers/net/wireless/iwmc3200wifi/lmac.h b/drivers/net/wireless/iwmc3200wifi/lmac.h index a3a79b5e2898..a855a99e49b8 100644 --- a/drivers/net/wireless/iwmc3200wifi/lmac.h +++ b/drivers/net/wireless/iwmc3200wifi/lmac.h @@ -262,7 +262,7 @@ struct iwm_ct_kill_cfg_cmd { /* Power Management */ #define POWER_TABLE_CMD 0x77 -#define SAVE_RESTORE_ADRESS_CMD 0x78 +#define SAVE_RESTORE_ADDRESS_CMD 0x78 #define REPLY_WATERMARK_CMD 0x79 #define PM_DEBUG_STATISTIC_NOTIFIC 0x7B #define PD_FLUSH_N_NOTIFICATION 0x7C diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c index 83f2592c59de..486c93559c29 100644 --- a/drivers/net/wireless/rt2x00/rt2500usb.c +++ b/drivers/net/wireless/rt2x00/rt2500usb.c @@ -368,7 +368,7 @@ static int rt2500usb_config_key(struct rt2x00_dev *rt2x00dev, /* * The encryption key doesn't fit within the CSR cache, - * this means we should allocate it seperately and use + * this means we should allocate it separately and use * rt2x00usb_vendor_request() to send the key to the hardware. */ reg = KEY_ENTRY(key->hw_key_idx); @@ -382,7 +382,7 @@ static int rt2500usb_config_key(struct rt2x00_dev *rt2x00dev, /* * The driver does not support the IV/EIV generation * in hardware. However it demands the data to be provided - * both seperately as well as inside the frame. + * both separately as well as inside the frame. * We already provided the CONFIG_CRYPTO_COPY_IV to rt2x00lib * to ensure rt2x00lib will not strip the data from the * frame after the copy, now we must tell mac80211 diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c index ab95346cf6a3..2e5c8a13758b 100644 --- a/drivers/net/wireless/rt2x00/rt2800usb.c +++ b/drivers/net/wireless/rt2x00/rt2800usb.c @@ -100,7 +100,7 @@ static int rt2800usb_check_firmware(struct rt2x00_dev *rt2x00dev, * There are 2 variations of the rt2870 firmware. * a) size: 4kb * b) size: 8kb - * Note that (b) contains 2 seperate firmware blobs of 4k + * Note that (b) contains 2 separate firmware blobs of 4k * within the file. The first blob is the same firmware as (a), * but the second blob is for the additional chipsets. */ @@ -118,7 +118,7 @@ static int rt2800usb_check_firmware(struct rt2x00_dev *rt2x00dev, /* * 8kb firmware files must be checked as if it were - * 2 seperate firmware files. + * 2 separate firmware files. */ while (offset < len) { if (!rt2800usb_check_crc(data + offset, 4096)) diff --git a/drivers/net/wireless/rt2x00/rt2x00debug.c b/drivers/net/wireless/rt2x00/rt2x00debug.c index 7d323a763b54..afee806affc2 100644 --- a/drivers/net/wireless/rt2x00/rt2x00debug.c +++ b/drivers/net/wireless/rt2x00/rt2x00debug.c @@ -109,7 +109,7 @@ struct rt2x00debug_intf { /* * HW crypto statistics. - * All statistics are stored seperately per cipher type. + * All statistics are stored separately per cipher type. */ struct rt2x00debug_crypto crypto_stats[CIPHER_MAX]; diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c index 265e66dba552..5e1d5167fff4 100644 --- a/drivers/net/wireless/rt2x00/rt2x00dev.c +++ b/drivers/net/wireless/rt2x00/rt2x00dev.c @@ -397,7 +397,7 @@ void rt2x00lib_rxdone(struct rt2x00_dev *rt2x00dev, /* * Hardware might have stripped the IV/EIV/ICV data, * in that case it is possible that the data was - * provided seperately (through hardware descriptor) + * provided separately (through hardware descriptor) * in which case we should reinsert the data into the frame. */ if ((rxdesc.dev_flags & RXDONE_CRYPTO_IV) && diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.c b/drivers/net/wireless/rt2x00/rt2x00queue.c index 9915a09141ef..38ffca9b0fe7 100644 --- a/drivers/net/wireless/rt2x00/rt2x00queue.c +++ b/drivers/net/wireless/rt2x00/rt2x00queue.c @@ -502,7 +502,7 @@ int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb, /* * When hardware encryption is supported, and this frame * is to be encrypted, we should strip the IV/EIV data from - * the frame so we can provide it to the driver seperately. + * the frame so we can provide it to the driver separately. */ if (test_bit(ENTRY_TXD_ENCRYPT, &txdesc.flags) && !test_bit(ENTRY_TXD_ENCRYPT_IV, &txdesc.flags)) { diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c index 0ca589306d71..99459db61efd 100644 --- a/drivers/net/wireless/rt2x00/rt61pci.c +++ b/drivers/net/wireless/rt2x00/rt61pci.c @@ -476,7 +476,7 @@ static int rt61pci_config_pairwise_key(struct rt2x00_dev *rt2x00dev, * The driver does not support the IV/EIV generation * in hardware. However it doesn't support the IV/EIV * inside the ieee80211 frame either, but requires it - * to be provided seperately for the descriptor. + * to be provided separately for the descriptor. * rt2x00lib will cut the IV/EIV data out of all frames * given to us by mac80211, but we must tell mac80211 * to generate the IV/EIV data. diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c index ced3b6ab5e16..527368a45fd5 100644 --- a/drivers/net/wireless/rt2x00/rt73usb.c +++ b/drivers/net/wireless/rt2x00/rt73usb.c @@ -339,7 +339,7 @@ static int rt73usb_config_shared_key(struct rt2x00_dev *rt2x00dev, * The driver does not support the IV/EIV generation * in hardware. However it doesn't support the IV/EIV * inside the ieee80211 frame either, but requires it - * to be provided seperately for the descriptor. + * to be provided separately for the descriptor. * rt2x00lib will cut the IV/EIV data out of all frames * given to us by mac80211, but we must tell mac80211 * to generate the IV/EIV data. @@ -439,7 +439,7 @@ static int rt73usb_config_pairwise_key(struct rt2x00_dev *rt2x00dev, * The driver does not support the IV/EIV generation * in hardware. However it doesn't support the IV/EIV * inside the ieee80211 frame either, but requires it - * to be provided seperately for the descriptor. + * to be provided separately for the descriptor. * rt2x00lib will cut the IV/EIV data out of all frames * given to us by mac80211, but we must tell mac80211 * to generate the IV/EIV data. @@ -1665,7 +1665,7 @@ static void rt73usb_fill_rxdone(struct queue_entry *entry, /* * Hardware has stripped IV/EIV data from 802.11 frame during - * decryption. It has provided the data seperately but rt2x00lib + * decryption. It has provided the data separately but rt2x00lib * should decide if it should be reinserted. */ rxdesc->flags |= RX_FLAG_IV_STRIPPED; diff --git a/drivers/s390/char/raw3270.c b/drivers/s390/char/raw3270.c index 62ddf5202b79..2a4c566456e7 100644 --- a/drivers/s390/char/raw3270.c +++ b/drivers/s390/char/raw3270.c @@ -373,7 +373,7 @@ raw3270_irq (struct ccw_device *cdev, unsigned long intparm, struct irb *irb) rq->rc = ccw_device_start(rp->cdev, &rq->ccw, (unsigned long) rq, 0, 0); if (rq->rc == 0) - return; /* Sucessfully restarted. */ + return; /* Successfully restarted. */ break; case RAW3270_IO_STOP: if (!rq) diff --git a/drivers/s390/char/sclp.c b/drivers/s390/char/sclp.c index ec88c59842e3..f6d72e1f2a38 100644 --- a/drivers/s390/char/sclp.c +++ b/drivers/s390/char/sclp.c @@ -196,7 +196,7 @@ __sclp_start_request(struct sclp_req *req) req->start_count++; if (rc == 0) { - /* Sucessfully started request */ + /* Successfully started request */ req->status = SCLP_REQ_RUNNING; sclp_running_state = sclp_running_state_running; __sclp_set_request_timer(SCLP_RETRY_INTERVAL * HZ, diff --git a/drivers/scsi/a100u2w.c b/drivers/scsi/a100u2w.c index 208d6df9ed59..ff5716d5f044 100644 --- a/drivers/scsi/a100u2w.c +++ b/drivers/scsi/a100u2w.c @@ -492,7 +492,7 @@ static void init_alloc_map(struct orc_host * host) * init_orchid - initialise the host adapter * @host:host adapter to initialise * - * Initialise the controller and if neccessary load the firmware. + * Initialise the controller and if necessary load the firmware. * * Returns -1 if the initialisation fails. */ diff --git a/drivers/scsi/initio.c b/drivers/scsi/initio.c index 89a59484be02..a7714160fbc3 100644 --- a/drivers/scsi/initio.c +++ b/drivers/scsi/initio.c @@ -531,7 +531,7 @@ static void initio_read_eeprom(unsigned long base) * initio_stop_bm - stop bus master * @host: InitIO we are stopping * - * Stop any pending DMA operation, aborting the DMA if neccessary + * Stop any pending DMA operation, aborting the DMA if necessary */ static void initio_stop_bm(struct initio_host * host) diff --git a/drivers/scsi/libfc/fc_fcp.c b/drivers/scsi/libfc/fc_fcp.c index 96ee599d9a05..96446a85e008 100644 --- a/drivers/scsi/libfc/fc_fcp.c +++ b/drivers/scsi/libfc/fc_fcp.c @@ -48,7 +48,7 @@ struct kmem_cache *scsi_pkt_cachep; #define FC_SRB_CMD_SENT (1 << 0) /* cmd has been sent */ #define FC_SRB_RCV_STATUS (1 << 1) /* response has arrived */ #define FC_SRB_ABORT_PENDING (1 << 2) /* cmd abort sent to device */ -#define FC_SRB_ABORTED (1 << 3) /* abort acknowleged */ +#define FC_SRB_ABORTED (1 << 3) /* abort acknowledged */ #define FC_SRB_DISCONTIG (1 << 4) /* non-sequential data recvd */ #define FC_SRB_COMPL (1 << 5) /* fc_io_compl has been run */ #define FC_SRB_FCP_PROCESSING_TMO (1 << 6) /* timer function processing */ diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c index 2cc39684ce97..c898f47f30ba 100644 --- a/drivers/scsi/lpfc/lpfc_els.c +++ b/drivers/scsi/lpfc/lpfc_els.c @@ -969,7 +969,7 @@ lpfc_issue_els_flogi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, * function returns, it does not guarantee all the IOCBs are actually aborted. * * Return code - * 0 - Sucessfully issued abort iocb on all outstanding flogis (Always 0) + * 0 - Successfully issued abort iocb on all outstanding flogis (Always 0) **/ int lpfc_els_abort_flogi(struct lpfc_hba *phba) @@ -3117,7 +3117,7 @@ lpfc_cmpl_els_rsp(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, if (ndlp && NLP_CHK_NODE_ACT(ndlp) && (*((uint32_t *) (pcmd)) == ELS_CMD_LS_RJT)) { /* A LS_RJT associated with Default RPI cleanup has its own - * seperate code path. + * separate code path. */ if (!(ndlp->nlp_flag & NLP_RM_DFLT_RPI)) ls_rjt = 1; diff --git a/drivers/scsi/pcmcia/nsp_cs.h b/drivers/scsi/pcmcia/nsp_cs.h index 7db28cd49446..8c61a4fe1db9 100644 --- a/drivers/scsi/pcmcia/nsp_cs.h +++ b/drivers/scsi/pcmcia/nsp_cs.h @@ -187,7 +187,7 @@ #define S_IO BIT(1) /* Input/Output line from SCSI bus */ #define S_CD BIT(2) /* Command/Data line from SCSI bus */ #define S_BUSY BIT(3) /* Busy line from SCSI bus */ -#define S_ACK BIT(4) /* Acknowlege line from SCSI bus */ +#define S_ACK BIT(4) /* Acknowledge line from SCSI bus */ #define S_REQUEST BIT(5) /* Request line from SCSI bus */ #define S_SELECT BIT(6) /* */ #define S_ATN BIT(7) /* */ diff --git a/drivers/scsi/pm8001/pm8001_hwi.c b/drivers/scsi/pm8001/pm8001_hwi.c index 9b44c6f1b10e..7985ae45d688 100644 --- a/drivers/scsi/pm8001/pm8001_hwi.c +++ b/drivers/scsi/pm8001/pm8001_hwi.c @@ -2924,7 +2924,7 @@ hw_event_sas_phy_up(struct pm8001_hba_info *pm8001_ha, void *piomb) break; default: PM8001_MSG_DBG(pm8001_ha, - pm8001_printk("unkown device type(%x)\n", deviceType)); + pm8001_printk("unknown device type(%x)\n", deviceType)); break; } phy->phy_type |= PORT_TYPE_SAS; diff --git a/drivers/scsi/pm8001/pm8001_sas.c b/drivers/scsi/pm8001/pm8001_sas.c index 7f9c83a76390..3b2c98fba834 100644 --- a/drivers/scsi/pm8001/pm8001_sas.c +++ b/drivers/scsi/pm8001/pm8001_sas.c @@ -600,7 +600,7 @@ static void pm8001_free_dev(struct pm8001_device *pm8001_dev) * by the command "OPC_INB_REG_DEV", after that the HBA will assign a * device ID(according to device's sas address) and returned it to LLDD. From * now on, we communicate with HBA FW with the device ID which HBA assigned - * rather than sas address. it is the neccessary step for our HBA but it is + * rather than sas address. it is the necessary step for our HBA but it is * the optional for other HBA driver. */ static int pm8001_dev_found_notify(struct domain_device *dev) diff --git a/drivers/scsi/pmcraid.h b/drivers/scsi/pmcraid.h index 92f89d50850c..b8ad07c3449e 100644 --- a/drivers/scsi/pmcraid.h +++ b/drivers/scsi/pmcraid.h @@ -938,7 +938,7 @@ static struct pmcraid_ioasc_error pmcraid_ioasc_error_table[] = { /* * pmcraid_ioctl_header - definition of header structure that preceeds all the - * buffers given as ioctl arguements. + * buffers given as ioctl arguments. * * .signature : always ASCII string, "PMCRAID" * .reserved : not used diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index 255da53e5a01..5d94772d449d 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c @@ -2105,7 +2105,7 @@ static int sd_revalidate_disk(struct gendisk *disk) * which is followed by sdaaa. * * This is basically 26 base counting with one extra 'nil' entry - * at the beggining from the second digit on and can be + * at the beginning from the second digit on and can be * determined using similar method as 26 base conversion with the * index shifted -1 after each digit is computed. * diff --git a/drivers/spi/spi_s3c24xx.c b/drivers/spi/spi_s3c24xx.c index c010733877ae..1fabede9e061 100644 --- a/drivers/spi/spi_s3c24xx.c +++ b/drivers/spi/spi_s3c24xx.c @@ -275,7 +275,7 @@ static inline u32 ack_bit(unsigned int irq) * Claim the FIQ handler (only one can be active at any one time) and * then setup the correct transfer code for this transfer. * - * This call updates all the necessary state information if sucessful, + * This call updates all the necessary state information if successful, * so the caller does not need to do anything more than start the transfer * as normal, since the IRQ will have been re-routed to the FIQ handler. */ diff --git a/drivers/usb/musb/musb_regs.h b/drivers/usb/musb/musb_regs.h index 473a94ef905f..7c14d5c5a8ac 100644 --- a/drivers/usb/musb/musb_regs.h +++ b/drivers/usb/musb/musb_regs.h @@ -436,7 +436,7 @@ static inline void musb_write_txhubport(void __iomem *mbase, u8 epnum, #define MUSB_FLAT_OFFSET(_epnum, _offset) \ (USB_OFFSET(USB_EP_NI0_TXMAXP) + (0x40 * (_epnum)) + (_offset)) -/* Not implemented - HW has seperate Tx/Rx FIFO */ +/* Not implemented - HW has separate Tx/Rx FIFO */ #define MUSB_TXCSR_MODE 0x0000 static inline void musb_write_txfifosz(void __iomem *mbase, u8 c_size) diff --git a/drivers/usb/serial/cypress_m8.c b/drivers/usb/serial/cypress_m8.c index a591ebec0f89..52a81a312b86 100644 --- a/drivers/usb/serial/cypress_m8.c +++ b/drivers/usb/serial/cypress_m8.c @@ -154,7 +154,7 @@ struct cypress_private { int isthrottled; /* if throttled, discard reads */ wait_queue_head_t delta_msr_wait; /* used for TIOCMIWAIT */ char prev_status, diff_status; /* used for TIOCMIWAIT */ - /* we pass a pointer to this as the arguement sent to + /* we pass a pointer to this as the argument sent to cypress_set_termios old_termios */ struct ktermios tmp_termios; /* stores the old termios settings */ }; diff --git a/drivers/video/omap/lcdc.c b/drivers/video/omap/lcdc.c index a33483910dc8..9557f963662e 100644 --- a/drivers/video/omap/lcdc.c +++ b/drivers/video/omap/lcdc.c @@ -389,7 +389,7 @@ static int omap_lcdc_enable_plane(int plane, int enable) /* * Configure the LCD DMA for a palette load operation and do the palette * downloading synchronously. We don't use the frame+palette load mode of - * the controller, since the palette can always be downloaded seperately. + * the controller, since the palette can always be downloaded separately. */ static void load_palette(void) { diff --git a/drivers/video/s1d13xxxfb.c b/drivers/video/s1d13xxxfb.c index 0deb0a8867b7..7b63429f1a7c 100644 --- a/drivers/video/s1d13xxxfb.c +++ b/drivers/video/s1d13xxxfb.c @@ -517,12 +517,12 @@ s1d13xxxfb_bitblt_copyarea(struct fb_info *info, const struct fb_copyarea *area) src = (sy * stride) + (bpp * sx); } - /* set source adress */ + /* set source address */ s1d13xxxfb_writereg(info->par, S1DREG_BBLT_SRC_START0, (src & 0xff)); s1d13xxxfb_writereg(info->par, S1DREG_BBLT_SRC_START1, (src >> 8) & 0x00ff); s1d13xxxfb_writereg(info->par, S1DREG_BBLT_SRC_START2, (src >> 16) & 0x00ff); - /* set destination adress */ + /* set destination address */ s1d13xxxfb_writereg(info->par, S1DREG_BBLT_DST_START0, (dst & 0xff)); s1d13xxxfb_writereg(info->par, S1DREG_BBLT_DST_START1, (dst >> 8) & 0x00ff); s1d13xxxfb_writereg(info->par, S1DREG_BBLT_DST_START2, (dst >> 16) & 0x00ff); diff --git a/drivers/video/sm501fb.c b/drivers/video/sm501fb.c index 35370d0ecf03..b7dc1800efa9 100644 --- a/drivers/video/sm501fb.c +++ b/drivers/video/sm501fb.c @@ -411,7 +411,7 @@ static int sm501fb_set_par_common(struct fb_info *info, struct sm501fb_par *par = info->par; struct sm501fb_info *fbi = par->info; unsigned long pixclock; /* pixelclock in Hz */ - unsigned long sm501pixclock; /* pixelclock the 501 can achive in Hz */ + unsigned long sm501pixclock; /* pixelclock the 501 can achieve in Hz */ unsigned int mem_type; unsigned int clock_type; unsigned int head_addr; diff --git a/fs/affs/bitmap.c b/fs/affs/bitmap.c index dc5ef14bdc1c..8306d53307ed 100644 --- a/fs/affs/bitmap.c +++ b/fs/affs/bitmap.c @@ -128,7 +128,7 @@ err_range: /* * Allocate a block in the given allocation zone. * Since we have to byte-swap the bitmap on little-endian - * machines, this is rather expensive. Therefor we will + * machines, this is rather expensive. Therefore we will * preallocate up to 16 blocks from the same word, if * possible. We are not doing preallocations in the * header zone, though. diff --git a/fs/binfmt_elf_fdpic.c b/fs/binfmt_elf_fdpic.c index 18d77297ccc8..364fcfc0c5df 100644 --- a/fs/binfmt_elf_fdpic.c +++ b/fs/binfmt_elf_fdpic.c @@ -1393,7 +1393,7 @@ static inline void fill_note(struct memelfnote *note, const char *name, int type /* * fill up all the fields in prstatus from the given task struct, except - * registers which need to be filled up seperately. + * registers which need to be filled up separately. */ static void fill_prstatus(struct elf_prstatus *prstatus, struct task_struct *p, long signr) diff --git a/fs/cifs/cifs_dfs_ref.c b/fs/cifs/cifs_dfs_ref.c index b44ce0a0711c..b1d61d0bdfc7 100644 --- a/fs/cifs/cifs_dfs_ref.c +++ b/fs/cifs/cifs_dfs_ref.c @@ -54,7 +54,7 @@ void cifs_dfs_release_automount_timer(void) * Extracts sharename form full UNC. * i.e. strips from UNC trailing path that is not part of share * name and fixup missing '\' in the begining of DFS node refferal - * if neccessary. + * if necessary. * Returns pointer to share name on success or ERR_PTR on error. * Caller is responsible for freeing returned string. */ diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c index 941441d3e386..0e22440d2f0f 100644 --- a/fs/cifs/cifssmb.c +++ b/fs/cifs/cifssmb.c @@ -3886,7 +3886,7 @@ parse_DFS_referrals(TRANSACTION2_GET_DFS_REFER_RSP *pSMBr, goto parse_DFS_referrals_exit; } - /* collect neccessary data from referrals */ + /* collect necessary data from referrals */ for (i = 0; i < *num_of_nodes; i++) { char *temp; int max_len; diff --git a/fs/ext4/move_extent.c b/fs/ext4/move_extent.c index 82c415be87a4..12a9ec73a888 100644 --- a/fs/ext4/move_extent.c +++ b/fs/ext4/move_extent.c @@ -928,7 +928,7 @@ out2: } /** - * mext_check_argumants - Check whether move extent can be done + * mext_check_arguments - Check whether move extent can be done * * @orig_inode: original inode * @donor_inode: donor inode diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c index 1a822ce2b24b..ec14d19ce501 100644 --- a/fs/fuse/inode.c +++ b/fs/fuse/inode.c @@ -850,7 +850,7 @@ static void fuse_send_init(struct fuse_conn *fc, struct fuse_req *req) req->in.args[0].size = sizeof(*arg); req->in.args[0].value = arg; req->out.numargs = 1; - /* Variable length arguement used for backward compatibility + /* Variable length argument used for backward compatibility with interface version < 7.5. Rest of init_out is zeroed by do_get_request(), so a short reply is not a problem */ req->out.argvar = 1; diff --git a/fs/gfs2/ops_fstype.c b/fs/gfs2/ops_fstype.c index edfee24f3636..0556f7fededd 100644 --- a/fs/gfs2/ops_fstype.c +++ b/fs/gfs2/ops_fstype.c @@ -992,7 +992,7 @@ static const struct lm_lockops nolock_ops = { /** * gfs2_lm_mount - mount a locking protocol * @sdp: the filesystem - * @args: mount arguements + * @args: mount arguments * @silent: if 1, don't complain if the FS isn't a GFS2 fs * * Returns: errno diff --git a/fs/jbd/transaction.c b/fs/jbd/transaction.c index 006f9ad838a2..57ae203c8abf 100644 --- a/fs/jbd/transaction.c +++ b/fs/jbd/transaction.c @@ -1398,7 +1398,7 @@ int journal_stop(handle_t *handle) * the case where our storage is so fast that it is more optimal to go * ahead and force a flush and wait for the transaction to be committed * than it is to wait for an arbitrary amount of time for new writers to - * join the transaction. We acheive this by measuring how long it takes + * join the transaction. We achieve this by measuring how long it takes * to commit a transaction, and compare it with how long this * transaction has been running, and if run time < commit time then we * sleep for the delta and commit. This greatly helps super fast disks diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c index a8587e90fd5a..143d43a93b72 100644 --- a/fs/nfsd/nfs4xdr.c +++ b/fs/nfsd/nfs4xdr.c @@ -1528,7 +1528,7 @@ static void write_cinfo(__be32 **p, struct nfsd4_change_info *c) } } while (0); /* Encode as an array of strings the string given with components - * seperated @sep. + * separated @sep. */ static __be32 nfsd4_encode_components(char sep, char *components, __be32 **pp, int *buflen) diff --git a/fs/ocfs2/dlmglue.c b/fs/ocfs2/dlmglue.c index c5e4a49e3a12..ccb9c44f478d 100644 --- a/fs/ocfs2/dlmglue.c +++ b/fs/ocfs2/dlmglue.c @@ -1757,7 +1757,7 @@ out: * ocfs2_file_lock() and ocfs2_file_unlock() map to a single pair of * flock() calls. The locking approach this requires is sufficiently * different from all other cluster lock types that we implement a - * seperate path to the "low-level" dlm calls. In particular: + * separate path to the "low-level" dlm calls. In particular: * * - No optimization of lock levels is done - we take at exactly * what's been requested. diff --git a/fs/ocfs2/extent_map.c b/fs/ocfs2/extent_map.c index d35a27f4523e..83e9b1249aed 100644 --- a/fs/ocfs2/extent_map.c +++ b/fs/ocfs2/extent_map.c @@ -453,7 +453,7 @@ static int ocfs2_get_clusters_nocache(struct inode *inode, if (i == -1) { /* * Holes can be larger than the maximum size of an - * extent, so we return their lengths in a seperate + * extent, so we return their lengths in a separate * field. */ if (hole_len) { diff --git a/fs/reiserfs/bitmap.c b/fs/reiserfs/bitmap.c index 65c872761177..ecc04b5ede57 100644 --- a/fs/reiserfs/bitmap.c +++ b/fs/reiserfs/bitmap.c @@ -169,7 +169,7 @@ static int scan_bitmap_block(struct reiserfs_transaction_handle *th, return 0; // No free blocks in this bitmap } - /* search for a first zero bit -- beggining of a window */ + /* search for a first zero bit -- beginning of a window */ *beg = reiserfs_find_next_zero_le_bit ((unsigned long *)(bh->b_data), boundary, *beg); diff --git a/include/linux/hil.h b/include/linux/hil.h index 13352d7d0caf..523785a9de70 100644 --- a/include/linux/hil.h +++ b/include/linux/hil.h @@ -168,14 +168,14 @@ enum hil_command { HIL_CMD_PR6 = 0x45, /* Prompt6 */ HIL_CMD_PR7 = 0x46, /* Prompt7 */ HIL_CMD_PRM = 0x47, /* Prompt (General Purpose) */ - HIL_CMD_AK1 = 0x48, /* Acknowlege1 */ - HIL_CMD_AK2 = 0x49, /* Acknowlege2 */ - HIL_CMD_AK3 = 0x4a, /* Acknowlege3 */ - HIL_CMD_AK4 = 0x4b, /* Acknowlege4 */ - HIL_CMD_AK5 = 0x4c, /* Acknowlege5 */ - HIL_CMD_AK6 = 0x4d, /* Acknowlege6 */ - HIL_CMD_AK7 = 0x4e, /* Acknowlege7 */ - HIL_CMD_ACK = 0x4f, /* Acknowlege (General Purpose) */ + HIL_CMD_AK1 = 0x48, /* Acknowledge1 */ + HIL_CMD_AK2 = 0x49, /* Acknowledge2 */ + HIL_CMD_AK3 = 0x4a, /* Acknowledge3 */ + HIL_CMD_AK4 = 0x4b, /* Acknowledge4 */ + HIL_CMD_AK5 = 0x4c, /* Acknowledge5 */ + HIL_CMD_AK6 = 0x4d, /* Acknowledge6 */ + HIL_CMD_AK7 = 0x4e, /* Acknowledge7 */ + HIL_CMD_ACK = 0x4f, /* Acknowledge (General Purpose) */ /* 0x50 to 0x78 reserved for future use */ /* 0x80 to 0xEF device-specific commands */ diff --git a/include/linux/lru_cache.h b/include/linux/lru_cache.h index 3a2b2d9b0472..de48d167568b 100644 --- a/include/linux/lru_cache.h +++ b/include/linux/lru_cache.h @@ -64,7 +64,7 @@ For crash recovery after replication node failure, usually the condition is softened to regions that _may_ have been target of in-flight WRITE IO, e.g. by only lazily clearing the on-disk write-intent bitmap, trading frequency of meta data transactions against amount of - (possibly unneccessary) resync traffic. + (possibly unnecessary) resync traffic. If we set a hard limit on the area that may be "hot" at any given time, we limit the amount of resync traffic needed for crash recovery. diff --git a/include/linux/sched.h b/include/linux/sched.h index abdfacc58653..a70957b138ed 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -1533,7 +1533,7 @@ struct task_struct { struct list_head *scm_work_list; #ifdef CONFIG_FUNCTION_GRAPH_TRACER - /* Index of current stored adress in ret_stack */ + /* Index of current stored address in ret_stack */ int curr_ret_stack; /* Stack of return addresses for return function tracing */ struct ftrace_ret_stack *ret_stack; diff --git a/include/media/davinci/vpfe_capture.h b/include/media/davinci/vpfe_capture.h index d863e5e8426d..4314a5f6a087 100644 --- a/include/media/davinci/vpfe_capture.h +++ b/include/media/davinci/vpfe_capture.h @@ -165,7 +165,7 @@ struct vpfe_device { u8 started; /* * offset where second field starts from the starting of the - * buffer for field seperated YCbCr formats + * buffer for field separated YCbCr formats */ u32 field_off; }; diff --git a/net/ipv4/tcp_timer.c b/net/ipv4/tcp_timer.c index 8816a20c2597..aff48d657181 100644 --- a/net/ipv4/tcp_timer.c +++ b/net/ipv4/tcp_timer.c @@ -133,7 +133,7 @@ static void tcp_mtu_probing(struct inet_connection_sock *icsk, struct sock *sk) } /* This function calculates a "timeout" which is equivalent to the timeout of a - * TCP connection after "boundary" unsucessful, exponentially backed-off + * TCP connection after "boundary" unsuccessful, exponentially backed-off * retransmissions with an initial RTO of TCP_RTO_MIN. */ static bool retransmits_timed_out(struct sock *sk, diff --git a/net/mac80211/mesh_plink.c b/net/mac80211/mesh_plink.c index 0f7c6e6a4248..54e4c8bb23e7 100644 --- a/net/mac80211/mesh_plink.c +++ b/net/mac80211/mesh_plink.c @@ -743,7 +743,7 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m break; default: /* should not get here, PLINK_BLOCKED is dealt with at the - * beggining of the function + * beginning of the function */ spin_unlock_bh(&sta->lock); break; diff --git a/net/netfilter/nf_conntrack_sip.c b/net/netfilter/nf_conntrack_sip.c index 023966b569bf..fbe94adee7ac 100644 --- a/net/netfilter/nf_conntrack_sip.c +++ b/net/netfilter/nf_conntrack_sip.c @@ -276,7 +276,7 @@ EXPORT_SYMBOL_GPL(ct_sip_parse_request); * tabs, spaces and continuation lines, which are treated as a single whitespace * character. * - * Some headers may appear multiple times. A comma seperated list of values is + * Some headers may appear multiple times. A comma separated list of values is * equivalent to multiple headers. */ static const struct sip_header ct_sip_hdrs[] = { @@ -412,7 +412,7 @@ int ct_sip_get_header(const struct nf_conn *ct, const char *dptr, } EXPORT_SYMBOL_GPL(ct_sip_get_header); -/* Get next header field in a list of comma seperated values */ +/* Get next header field in a list of comma separated values */ static int ct_sip_next_header(const struct nf_conn *ct, const char *dptr, unsigned int dataoff, unsigned int datalen, enum sip_header_types type, diff --git a/net/netfilter/xt_hashlimit.c b/net/netfilter/xt_hashlimit.c index dd16e404424f..cbaac92dad59 100644 --- a/net/netfilter/xt_hashlimit.c +++ b/net/netfilter/xt_hashlimit.c @@ -1,6 +1,6 @@ /* * xt_hashlimit - Netfilter module to limit the number of packets per time - * seperately for each hashbucket (sourceip/sourceport/dstip/dstport) + * separately for each hashbucket (sourceip/sourceport/dstip/dstport) * * (C) 2003-2004 by Harald Welte * Copyright © CC Computer Consultants GmbH, 2007 - 2008 diff --git a/net/sctp/sm_sideeffect.c b/net/sctp/sm_sideeffect.c index 4e4ca65cd320..500886bda9b4 100644 --- a/net/sctp/sm_sideeffect.c +++ b/net/sctp/sm_sideeffect.c @@ -475,7 +475,7 @@ static void sctp_do_8_2_transport_strike(struct sctp_association *asoc, * used to provide an upper bound to this doubling operation. * * Special Case: the first HB doesn't trigger exponential backoff. - * The first unacknowleged HB triggers it. We do this with a flag + * The first unacknowledged HB triggers it. We do this with a flag * that indicates that we have an outstanding HB. */ if (!is_hb || transport->hb_sent) { diff --git a/scripts/gfp-translate b/scripts/gfp-translate index 073cb6d152a0..d81b968d864e 100644 --- a/scripts/gfp-translate +++ b/scripts/gfp-translate @@ -19,7 +19,7 @@ usage() { exit 0 } -# Parse command-line arguements +# Parse command-line arguments while [ $# -gt 0 ]; do case $1 in --source) diff --git a/sound/pci/rme9652/hdspm.c b/sound/pci/rme9652/hdspm.c index a1b10d1a384d..db0ed1cbd982 100644 --- a/sound/pci/rme9652/hdspm.c +++ b/sound/pci/rme9652/hdspm.c @@ -2479,7 +2479,7 @@ static int snd_hdspm_put_qs_wire(struct snd_kcontrol *kcontrol, on MADICARD - playback mixer matrix: [channelout+64] [output] [value] - input(thru) mixer matrix: [channelin] [output] [value] - (better do 2 kontrols for seperation ?) + (better do 2 kontrols for separation ?) */ #define HDSPM_MIXER(xname, xindex) \ diff --git a/sound/soc/codecs/wm8990.c b/sound/soc/codecs/wm8990.c index 341481e0e830..427614a2762b 100644 --- a/sound/soc/codecs/wm8990.c +++ b/sound/soc/codecs/wm8990.c @@ -990,7 +990,7 @@ static int wm8990_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id, reg = snd_soc_read(codec, WM8990_CLOCKING_2); snd_soc_write(codec, WM8990_CLOCKING_2, reg | WM8990_SYSCLK_SRC); - /* set up N , fractional mode and pre-divisor if neccessary */ + /* set up N , fractional mode and pre-divisor if necessary */ snd_soc_write(codec, WM8990_PLL1, pll_div.n | WM8990_SDM | (pll_div.div2?WM8990_PRESCALE:0)); snd_soc_write(codec, WM8990_PLL2, (u8)(pll_div.k>>8)); diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c index e8daf5ca6fd2..44408c2621cf 100644 --- a/tools/perf/util/hist.c +++ b/tools/perf/util/hist.c @@ -321,7 +321,7 @@ static size_t __callchain__fprintf_graph(FILE *fp, struct callchain_node *self, new_depth_mask &= ~(1 << (depth - 1)); /* - * But we keep the older depth mask for the line seperator + * But we keep the older depth mask for the line separator * to keep the level link until we reach the last child */ ret += ipchain__fprintf_graph_line(fp, depth, depth_mask, -- cgit v1.2.3 From 74e7e725e4766a2045708d274d4d07cd4fae8adc Mon Sep 17 00:00:00 2001 From: Eric Miao Date: Sun, 7 Feb 2010 23:10:05 -0800 Subject: Input: mark {corgi,spitz,tosa}kbd drivers deprecated Provided that now keyboards on these devices are fully supported by generic GPIO based matrix keypad driver, mark these hardcoded and difficult to maintain drivers as deprecated. Signed-off-by: Eric Miao Acked-by: Pavel Machek Signed-off-by: Dmitry Torokhov --- Documentation/feature-removal-schedule.txt | 11 +++++++++++ drivers/input/keyboard/Kconfig | 18 ++++++++++++------ 2 files changed, 23 insertions(+), 6 deletions(-) (limited to 'drivers/input') diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt index 0a46833c1b76..f8dc4d92e114 100644 --- a/Documentation/feature-removal-schedule.txt +++ b/Documentation/feature-removal-schedule.txt @@ -542,3 +542,14 @@ Why: Duplicate functionality with the gspca_zc3xx driver, zc0301 only sensors) wich are also supported by the gspca_zc3xx driver (which supports 53 USB-ID's in total) Who: Hans de Goede + +---------------------------- + +What: corgikbd, spitzkbd, tosakbd driver +When: 2.6.35 +Files: drivers/input/keyboard/{corgi,spitz,tosa}kbd.c +Why: We now have a generic GPIO based matrix keyboard driver that + are fully capable of handling all the keys on these devices. + The original drivers manipulate the GPIO registers directly + and so are difficult to maintain. +Who: Eric Miao diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig index 616a3916d187..1ad9435d30aa 100644 --- a/drivers/input/keyboard/Kconfig +++ b/drivers/input/keyboard/Kconfig @@ -144,13 +144,15 @@ config KEYBOARD_BFIN module will be called bf54x-keys. config KEYBOARD_CORGI - tristate "Corgi keyboard" + tristate "Corgi keyboard (deprecated)" depends on PXA_SHARPSL - default y help Say Y here to enable the keyboard on the Sharp Zaurus SL-C7xx series of PDAs. + This driver is now deprecated, use generic GPIO based matrix + keyboard driver instead. + To compile this driver as a module, choose M here: the module will be called corgikbd. @@ -338,13 +340,15 @@ config KEYBOARD_PXA930_ROTARY module will be called pxa930_rotary. config KEYBOARD_SPITZ - tristate "Spitz keyboard" + tristate "Spitz keyboard (deprecated)" depends on PXA_SHARPSL - default y help Say Y here to enable the keyboard on the Sharp Zaurus SL-C1000, SL-C3000 and Sl-C3100 series of PDAs. + This driver is now deprecated, use generic GPIO based matrix + keyboard driver instead. + To compile this driver as a module, choose M here: the module will be called spitzkbd. @@ -411,12 +415,14 @@ config KEYBOARD_TWL4030 module will be called twl4030_keypad. config KEYBOARD_TOSA - tristate "Tosa keyboard" + tristate "Tosa keyboard (deprecated)" depends on MACH_TOSA - default y help Say Y here to enable the keyboard on the Sharp Zaurus SL-6000x (Tosa) + This driver is now deprecated, use generic GPIO based matrix + keyboard driver instead. + To compile this driver as a module, choose M here: the module will be called tosakbd. -- cgit v1.2.3 From b63de38591605916fff5d483e0bedc65dfe3d395 Mon Sep 17 00:00:00 2001 From: Eric Miao Date: Sun, 7 Feb 2010 23:10:05 -0800 Subject: Input: schedule corgi_ssp and corgi_ts to be removed Signed-off-by: Eric Miao Acked-by: Richard Purdie Acked-by: Pavel Machek Signed-off-by: Dmitry Torokhov --- Documentation/feature-removal-schedule.txt | 12 ++++++++++++ drivers/input/touchscreen/Kconfig | 1 - 2 files changed, 12 insertions(+), 1 deletion(-) (limited to 'drivers/input') diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt index f8dc4d92e114..54d2d7795544 100644 --- a/Documentation/feature-removal-schedule.txt +++ b/Documentation/feature-removal-schedule.txt @@ -553,3 +553,15 @@ Why: We now have a generic GPIO based matrix keyboard driver that The original drivers manipulate the GPIO registers directly and so are difficult to maintain. Who: Eric Miao + +---------------------------- + +What: corgi_ssp and corgi_ts driver +When: 2.6.35 +Files: arch/arm/mach-pxa/corgi_ssp.c, drivers/input/touchscreen/corgi_ts.c +Why: The corgi touchscreen is now deprecated in favour of the generic + ads7846.c driver. The noise reduction technique used in corgi_ts.c, + that's to wait till vsync before ADC sampling, is also integrated into + ads7846 driver now. Provided that the original driver is not generic + and is difficult to maintain, it will be removed later. +Who: Eric Miao diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig index a1e2d845f680..6457e060ae49 100644 --- a/drivers/input/touchscreen/Kconfig +++ b/drivers/input/touchscreen/Kconfig @@ -90,7 +90,6 @@ config TOUCHSCREEN_CORGI tristate "SharpSL (Corgi and Spitz series) touchscreen driver (DEPRECATED)" depends on PXA_SHARPSL select CORGI_SSP_DEPRECATED - default y help Say Y here to enable the driver for the touchscreen on the Sharp SL-C7xx and SL-Cxx00 series of PDAs. -- cgit v1.2.3 From 2b14a808fbbb042d0de323260d939bdf95e9efdf Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Wed, 10 Feb 2010 22:13:21 -0800 Subject: Input: sh_keysc - factor out hw access functions Update the sh_keysc driver to factor out the register access functions sh_keysc_read(), sh_keysc_write() together with sh_keysc_level_mode(). This makes the code a bit easier to follow. Signed-off-by: Magnus Damm Signed-off-by: Dmitry Torokhov --- drivers/input/keyboard/sh_keysc.c | 69 ++++++++++++++++++++++++--------------- 1 file changed, 43 insertions(+), 26 deletions(-) (limited to 'drivers/input') diff --git a/drivers/input/keyboard/sh_keysc.c b/drivers/input/keyboard/sh_keysc.c index efcc3a3b9b53..6218b2f02495 100644 --- a/drivers/input/keyboard/sh_keysc.c +++ b/drivers/input/keyboard/sh_keysc.c @@ -22,14 +22,6 @@ #include #include -#define KYCR1_OFFS 0x00 -#define KYCR2_OFFS 0x04 -#define KYINDR_OFFS 0x08 -#define KYOUTDR_OFFS 0x0c - -#define KYCR2_IRQ_LEVEL 0x10 -#define KYCR2_IRQ_DISABLED 0x00 - static const struct { unsigned char kymd, keyout, keyin; } sh_keysc_mode[] = { @@ -48,6 +40,37 @@ struct sh_keysc_priv { struct sh_keysc_info pdata; }; +#define KYCR1 0 +#define KYCR2 1 +#define KYINDR 2 +#define KYOUTDR 3 + +#define KYCR2_IRQ_LEVEL 0x10 +#define KYCR2_IRQ_DISABLED 0x00 + +static unsigned long sh_keysc_read(struct sh_keysc_priv *p, int reg_nr) +{ + return ioread16(p->iomem_base + (reg_nr << 2)); +} + +static void sh_keysc_write(struct sh_keysc_priv *p, int reg_nr, + unsigned long value) +{ + iowrite16(value, p->iomem_base + (reg_nr << 2)); +} + +static void sh_keysc_level_mode(struct sh_keysc_priv *p, + unsigned long keys_set) +{ + struct sh_keysc_info *pdata = &p->pdata; + + sh_keysc_write(p, KYOUTDR, 0); + sh_keysc_write(p, KYCR2, KYCR2_IRQ_LEVEL | (keys_set << 8)); + + if (pdata->kycr2_delay) + udelay(pdata->kycr2_delay); +} + static irqreturn_t sh_keysc_isr(int irq, void *dev_id) { struct platform_device *pdev = dev_id; @@ -66,24 +89,19 @@ static irqreturn_t sh_keysc_isr(int irq, void *dev_id) keys = 0; keyin_set = 0; - iowrite16(KYCR2_IRQ_DISABLED, priv->iomem_base + KYCR2_OFFS); + sh_keysc_write(priv, KYCR2, KYCR2_IRQ_DISABLED); for (i = 0; i < sh_keysc_mode[pdata->mode].keyout; i++) { - iowrite16(0xfff ^ (3 << (i * 2)), - priv->iomem_base + KYOUTDR_OFFS); + sh_keysc_write(priv, KYOUTDR, 0xfff ^ (3 << (i * 2))); udelay(pdata->delay); - tmp = ioread16(priv->iomem_base + KYINDR_OFFS); + tmp = sh_keysc_read(priv, KYINDR); + keys |= tmp << (sh_keysc_mode[pdata->mode].keyin * i); tmp ^= (1 << sh_keysc_mode[pdata->mode].keyin) - 1; keyin_set |= tmp; } - iowrite16(0, priv->iomem_base + KYOUTDR_OFFS); - iowrite16(KYCR2_IRQ_LEVEL | (keyin_set << 8), - priv->iomem_base + KYCR2_OFFS); - - if (pdata->kycr2_delay) - udelay(pdata->kycr2_delay); + sh_keysc_level_mode(priv, keyin_set); keys ^= ~0; keys &= (1 << (sh_keysc_mode[pdata->mode].keyin * @@ -93,7 +111,7 @@ static irqreturn_t sh_keysc_isr(int irq, void *dev_id) dev_dbg(&pdev->dev, "keys 0x%08lx\n", keys); - } while (ioread16(priv->iomem_base + KYCR2_OFFS) & 0x01); + } while (sh_keysc_read(priv, KYCR2) & 0x01); dev_dbg(&pdev->dev, "last_keys 0x%08lx keys0 0x%08lx keys1 0x%08lx\n", priv->last_keys, keys0, keys1); @@ -220,10 +238,9 @@ static int __devinit sh_keysc_probe(struct platform_device *pdev) clk_enable(priv->clk); - iowrite16((sh_keysc_mode[pdata->mode].kymd << 8) | - pdata->scan_timing, priv->iomem_base + KYCR1_OFFS); - iowrite16(0, priv->iomem_base + KYOUTDR_OFFS); - iowrite16(KYCR2_IRQ_LEVEL, priv->iomem_base + KYCR2_OFFS); + sh_keysc_write(priv, KYCR1, (sh_keysc_mode[pdata->mode].kymd << 8) | + pdata->scan_timing); + sh_keysc_level_mode(priv, 0); device_init_wakeup(&pdev->dev, 1); @@ -248,7 +265,7 @@ static int __devexit sh_keysc_remove(struct platform_device *pdev) { struct sh_keysc_priv *priv = platform_get_drvdata(pdev); - iowrite16(KYCR2_IRQ_DISABLED, priv->iomem_base + KYCR2_OFFS); + sh_keysc_write(priv, KYCR2, KYCR2_IRQ_DISABLED); input_unregister_device(priv->input); free_irq(platform_get_irq(pdev, 0), pdev); @@ -270,7 +287,7 @@ static int sh_keysc_suspend(struct device *dev) int irq = platform_get_irq(pdev, 0); unsigned short value; - value = ioread16(priv->iomem_base + KYCR1_OFFS); + value = sh_keysc_read(priv, KYCR1); if (device_may_wakeup(dev)) { value |= 0x80; @@ -279,7 +296,7 @@ static int sh_keysc_suspend(struct device *dev) value &= ~0x80; } - iowrite16(value, priv->iomem_base + KYCR1_OFFS); + sh_keysc_write(priv, KYCR1, value); return 0; } -- cgit v1.2.3 From 324e5ade1569111a40c349726d8a2694b28d7943 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Wed, 10 Feb 2010 22:13:21 -0800 Subject: Input: sh_keysc - switch to using bitmaps Use bitmaps instead of using 32-bit integers to keep track of the key states. With this change in place the driver supports key pads with more than 32 keys. Signed-off-by: Magnus Damm Signed-off-by: Dmitry Torokhov --- drivers/input/keyboard/sh_keysc.c | 69 +++++++++++++++++++++++++-------------- 1 file changed, 44 insertions(+), 25 deletions(-) (limited to 'drivers/input') diff --git a/drivers/input/keyboard/sh_keysc.c b/drivers/input/keyboard/sh_keysc.c index 6218b2f02495..c2fc97732f0c 100644 --- a/drivers/input/keyboard/sh_keysc.c +++ b/drivers/input/keyboard/sh_keysc.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include @@ -35,7 +36,7 @@ static const struct { struct sh_keysc_priv { void __iomem *iomem_base; struct clk *clk; - unsigned long last_keys; + DECLARE_BITMAP(last_keys, SH_KEYSC_MAXKEYS); struct input_dev *input; struct sh_keysc_info pdata; }; @@ -71,69 +72,87 @@ static void sh_keysc_level_mode(struct sh_keysc_priv *p, udelay(pdata->kycr2_delay); } +static void sh_keysc_map_dbg(struct device *dev, unsigned long *map, + const char *str) +{ + int k; + + for (k = 0; k < BITS_TO_LONGS(SH_KEYSC_MAXKEYS); k++) + dev_dbg(dev, "%s[%d] 0x%lx\n", str, k, map[k]); +} + static irqreturn_t sh_keysc_isr(int irq, void *dev_id) { struct platform_device *pdev = dev_id; struct sh_keysc_priv *priv = platform_get_drvdata(pdev); struct sh_keysc_info *pdata = &priv->pdata; - unsigned long keys, keys1, keys0, mask; + int keyout_nr = sh_keysc_mode[pdata->mode].keyout; + int keyin_nr = sh_keysc_mode[pdata->mode].keyin; + DECLARE_BITMAP(keys, SH_KEYSC_MAXKEYS); + DECLARE_BITMAP(keys0, SH_KEYSC_MAXKEYS); + DECLARE_BITMAP(keys1, SH_KEYSC_MAXKEYS); unsigned char keyin_set, tmp; - int i, k; + int i, k, n; dev_dbg(&pdev->dev, "isr!\n"); - keys1 = ~0; - keys0 = 0; + bitmap_fill(keys1, SH_KEYSC_MAXKEYS); + bitmap_zero(keys0, SH_KEYSC_MAXKEYS); do { - keys = 0; + bitmap_zero(keys, SH_KEYSC_MAXKEYS); keyin_set = 0; sh_keysc_write(priv, KYCR2, KYCR2_IRQ_DISABLED); - for (i = 0; i < sh_keysc_mode[pdata->mode].keyout; i++) { + for (i = 0; i < keyout_nr; i++) { + n = keyin_nr * i; + + /* drive one KEYOUT pin low, read KEYIN pins */ sh_keysc_write(priv, KYOUTDR, 0xfff ^ (3 << (i * 2))); udelay(pdata->delay); tmp = sh_keysc_read(priv, KYINDR); - keys |= tmp << (sh_keysc_mode[pdata->mode].keyin * i); - tmp ^= (1 << sh_keysc_mode[pdata->mode].keyin) - 1; - keyin_set |= tmp; + /* set bit if key press has been detected */ + for (k = 0; k < keyin_nr; k++) { + if (tmp & (1 << k)) + __set_bit(n + k, keys); + } + + /* keep track of which KEYIN bits that have been set */ + keyin_set |= tmp ^ ((1 << keyin_nr) - 1); } sh_keysc_level_mode(priv, keyin_set); - keys ^= ~0; - keys &= (1 << (sh_keysc_mode[pdata->mode].keyin * - sh_keysc_mode[pdata->mode].keyout)) - 1; - keys1 &= keys; - keys0 |= keys; + bitmap_complement(keys, keys, SH_KEYSC_MAXKEYS); + bitmap_and(keys1, keys1, keys, SH_KEYSC_MAXKEYS); + bitmap_or(keys0, keys0, keys, SH_KEYSC_MAXKEYS); - dev_dbg(&pdev->dev, "keys 0x%08lx\n", keys); + sh_keysc_map_dbg(&pdev->dev, keys, "keys"); } while (sh_keysc_read(priv, KYCR2) & 0x01); - dev_dbg(&pdev->dev, "last_keys 0x%08lx keys0 0x%08lx keys1 0x%08lx\n", - priv->last_keys, keys0, keys1); + sh_keysc_map_dbg(&pdev->dev, priv->last_keys, "last_keys"); + sh_keysc_map_dbg(&pdev->dev, keys0, "keys0"); + sh_keysc_map_dbg(&pdev->dev, keys1, "keys1"); for (i = 0; i < SH_KEYSC_MAXKEYS; i++) { k = pdata->keycodes[i]; if (!k) continue; - mask = 1 << i; - - if (!((priv->last_keys ^ keys0) & mask)) + if (test_bit(i, keys0) == test_bit(i, priv->last_keys)) continue; - if ((keys1 | keys0) & mask) { + if (test_bit(i, keys1) || test_bit(i, keys0)) { input_event(priv->input, EV_KEY, k, 1); - priv->last_keys |= mask; + __set_bit(i, priv->last_keys); } - if (!(keys1 & mask)) { + if (!test_bit(i, keys1)) { input_event(priv->input, EV_KEY, k, 0); - priv->last_keys &= ~mask; + __clear_bit(i, priv->last_keys); } } -- cgit v1.2.3 From 8f8be2439cd368cc6ba94888919ee90b5a26f0cb Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Wed, 10 Feb 2010 23:03:22 -0800 Subject: Input: sh_keysc - update the driver with mode 6 Add mode 6 support to the sh_keysc driver. Also update the KYOUTDR mask value to include all 16 register bits. Signed-off-by: Magnus Damm Signed-off-by: Dmitry Torokhov --- drivers/input/keyboard/sh_keysc.c | 3 ++- include/linux/input/sh_keysc.h | 6 +++--- 2 files changed, 5 insertions(+), 4 deletions(-) (limited to 'drivers/input') diff --git a/drivers/input/keyboard/sh_keysc.c b/drivers/input/keyboard/sh_keysc.c index c2fc97732f0c..854e2035cd6e 100644 --- a/drivers/input/keyboard/sh_keysc.c +++ b/drivers/input/keyboard/sh_keysc.c @@ -31,6 +31,7 @@ static const struct { [SH_KEYSC_MODE_3] = { 2, 4, 7 }, [SH_KEYSC_MODE_4] = { 3, 6, 6 }, [SH_KEYSC_MODE_5] = { 4, 6, 7 }, + [SH_KEYSC_MODE_6] = { 5, 7, 7 }, }; struct sh_keysc_priv { @@ -109,7 +110,7 @@ static irqreturn_t sh_keysc_isr(int irq, void *dev_id) n = keyin_nr * i; /* drive one KEYOUT pin low, read KEYIN pins */ - sh_keysc_write(priv, KYOUTDR, 0xfff ^ (3 << (i * 2))); + sh_keysc_write(priv, KYOUTDR, 0xffff ^ (3 << (i * 2))); udelay(pdata->delay); tmp = sh_keysc_read(priv, KYINDR); diff --git a/include/linux/input/sh_keysc.h b/include/linux/input/sh_keysc.h index 2aff38bcf2ba..649dc7f12925 100644 --- a/include/linux/input/sh_keysc.h +++ b/include/linux/input/sh_keysc.h @@ -1,15 +1,15 @@ #ifndef __SH_KEYSC_H__ #define __SH_KEYSC_H__ -#define SH_KEYSC_MAXKEYS 42 +#define SH_KEYSC_MAXKEYS 49 struct sh_keysc_info { enum { SH_KEYSC_MODE_1, SH_KEYSC_MODE_2, SH_KEYSC_MODE_3, - SH_KEYSC_MODE_4, SH_KEYSC_MODE_5 } mode; + SH_KEYSC_MODE_4, SH_KEYSC_MODE_5, SH_KEYSC_MODE_6 } mode; int scan_timing; /* 0 -> 7, see KYCR1, SCN[2:0] */ int delay; int kycr2_delay; - int keycodes[SH_KEYSC_MAXKEYS]; + int keycodes[SH_KEYSC_MAXKEYS]; /* KEYIN * KEYOUT */ }; #endif /* __SH_KEYSC_H__ */ -- cgit v1.2.3 From 5deeac99fe1146532eb7c64f9adb17d17628d751 Mon Sep 17 00:00:00 2001 From: Andrew Clayton Date: Wed, 10 Feb 2010 23:18:05 -0800 Subject: Input: rotary-encoder - set gpio direction for each requested gpio Even with the correct pin mux settings, you still need to explicitly set the gpio direction. Call gpio_direction_input() after each requested gpio. Signed-off-by: Andrew Clayton Signed-off-by: Mark Somerville Tested-by: H Hartley Sweeten Acked-by: Daniel Mack Signed-off-by: Dmitry Torokhov --- drivers/input/misc/rotary_encoder.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'drivers/input') diff --git a/drivers/input/misc/rotary_encoder.c b/drivers/input/misc/rotary_encoder.c index 3b9f588fc747..4ae07935985e 100644 --- a/drivers/input/misc/rotary_encoder.c +++ b/drivers/input/misc/rotary_encoder.c @@ -152,6 +152,13 @@ static int __devinit rotary_encoder_probe(struct platform_device *pdev) goto exit_unregister_input; } + err = gpio_direction_input(pdata->gpio_a); + if (err) { + dev_err(&pdev->dev, "unable to set GPIO %d for input\n", + pdata->gpio_a); + goto exit_unregister_input; + } + err = gpio_request(pdata->gpio_b, DRV_NAME); if (err) { dev_err(&pdev->dev, "unable to request GPIO %d\n", @@ -159,6 +166,13 @@ static int __devinit rotary_encoder_probe(struct platform_device *pdev) goto exit_free_gpio_a; } + err = gpio_direction_input(pdata->gpio_b); + if (err) { + dev_err(&pdev->dev, "unable to set GPIO %d for input\n", + pdata->gpio_b); + goto exit_free_gpio_a; + } + /* request the IRQs */ err = request_irq(encoder->irq_a, &rotary_encoder_irq, IORESOURCE_IRQ_HIGHEDGE | IORESOURCE_IRQ_LOWEDGE, -- cgit v1.2.3 From b036f6fb3aa23a52d90da5fc57e0803f08292e82 Mon Sep 17 00:00:00 2001 From: Bastian Blank Date: Wed, 10 Feb 2010 23:06:23 -0800 Subject: Input: wacom - get features from driver info Get the features information from the driver info of the usb device id structure provided by the caller. The device ids and feature structs are strong coupled using indices. Signed-off-by: Bastian Blank Tested-by: Jason Childs Acked-by: Ping Cheng Signed-off-by: Dmitry Torokhov --- drivers/input/tablet/wacom.h | 5 +- drivers/input/tablet/wacom_sys.c | 10 +- drivers/input/tablet/wacom_wac.c | 342 ++++++++++++++++++++++----------------- 3 files changed, 205 insertions(+), 152 deletions(-) (limited to 'drivers/input') diff --git a/drivers/input/tablet/wacom.h b/drivers/input/tablet/wacom.h index 16310f368dab..8fef1b689c69 100644 --- a/drivers/input/tablet/wacom.h +++ b/drivers/input/tablet/wacom.h @@ -85,6 +85,7 @@ #include #include #include +#include #include #include #include @@ -120,6 +121,8 @@ struct wacom_combo { struct urb *urb; }; +extern const struct usb_device_id wacom_ids[]; + extern int wacom_wac_irq(struct wacom_wac * wacom_wac, void * wcombo); extern void wacom_report_abs(void *wcombo, unsigned int abs_type, int abs_data); extern void wacom_report_rel(void *wcombo, unsigned int rel_type, int rel_data); @@ -142,7 +145,5 @@ extern void input_dev_mo(struct input_dev *input_dev, struct wacom_wac *wacom_wa extern void input_dev_bee(struct input_dev *input_dev, struct wacom_wac *wacom_wac); extern __u16 wacom_le16_to_cpu(unsigned char *data); extern __u16 wacom_be16_to_cpu(unsigned char *data); -extern struct wacom_features *get_wacom_feature(const struct usb_device_id *id); -extern const struct usb_device_id *get_device_table(void); #endif diff --git a/drivers/input/tablet/wacom_sys.c b/drivers/input/tablet/wacom_sys.c index 072f33b3b2b0..be4b76f264a7 100644 --- a/drivers/input/tablet/wacom_sys.c +++ b/drivers/input/tablet/wacom_sys.c @@ -530,10 +530,13 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i struct usb_endpoint_descriptor *endpoint; struct wacom *wacom; struct wacom_wac *wacom_wac; - struct wacom_features *features; + struct wacom_features *features = (void *)id->driver_info; struct input_dev *input_dev; int error = -ENOMEM; + if (!features) + return -EINVAL; + wacom = kzalloc(sizeof(struct wacom), GFP_KERNEL); wacom_wac = kzalloc(sizeof(struct wacom_wac), GFP_KERNEL); input_dev = input_allocate_device(); @@ -555,7 +558,7 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i usb_make_path(dev, wacom->phys, sizeof(wacom->phys)); strlcat(wacom->phys, "/input0", sizeof(wacom->phys)); - wacom_wac->features = features = get_wacom_feature(id); + wacom_wac->features = features; BUG_ON(features->pktlen > WACOM_PKGLEN_MAX); input_dev->name = wacom_wac->features->name; @@ -663,6 +666,7 @@ static int wacom_reset_resume(struct usb_interface *intf) static struct usb_driver wacom_driver = { .name = "wacom", + .id_table = wacom_ids, .probe = wacom_probe, .disconnect = wacom_disconnect, .suspend = wacom_suspend, @@ -674,7 +678,7 @@ static struct usb_driver wacom_driver = { static int __init wacom_init(void) { int result; - wacom_driver.id_table = get_device_table(); + result = usb_register(&wacom_driver); if (result == 0) printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":" diff --git a/drivers/input/tablet/wacom_wac.c b/drivers/input/tablet/wacom_wac.c index 1056f149fe31..56aaf0164a56 100644 --- a/drivers/input/tablet/wacom_wac.c +++ b/drivers/input/tablet/wacom_wac.c @@ -903,153 +903,201 @@ void wacom_init_input_dev(struct input_dev *input_dev, struct wacom_wac *wacom_w return; } -static struct wacom_features wacom_features[] = { - { "Wacom Penpartner", WACOM_PKGLEN_PENPRTN, 5040, 3780, 255, 0, PENPARTNER }, - { "Wacom Graphire", WACOM_PKGLEN_GRAPHIRE, 10206, 7422, 511, 63, GRAPHIRE }, - { "Wacom Graphire2 4x5", WACOM_PKGLEN_GRAPHIRE, 10206, 7422, 511, 63, GRAPHIRE }, - { "Wacom Graphire2 5x7", WACOM_PKGLEN_GRAPHIRE, 13918, 10206, 511, 63, GRAPHIRE }, - { "Wacom Graphire3", WACOM_PKGLEN_GRAPHIRE, 10208, 7424, 511, 63, GRAPHIRE }, - { "Wacom Graphire3 6x8", WACOM_PKGLEN_GRAPHIRE, 16704, 12064, 511, 63, GRAPHIRE }, - { "Wacom Graphire4 4x5", WACOM_PKGLEN_GRAPHIRE, 10208, 7424, 511, 63, WACOM_G4 }, - { "Wacom Graphire4 6x8", WACOM_PKGLEN_GRAPHIRE, 16704, 12064, 511, 63, WACOM_G4 }, - { "Wacom BambooFun 4x5", WACOM_PKGLEN_BBFUN, 14760, 9225, 511, 63, WACOM_MO }, - { "Wacom BambooFun 6x8", WACOM_PKGLEN_BBFUN, 21648, 13530, 511, 63, WACOM_MO }, - { "Wacom Bamboo1 Medium", WACOM_PKGLEN_GRAPHIRE, 16704, 12064, 511, 63, GRAPHIRE }, - { "Wacom Volito", WACOM_PKGLEN_GRAPHIRE, 5104, 3712, 511, 63, GRAPHIRE }, - { "Wacom PenStation2", WACOM_PKGLEN_GRAPHIRE, 3250, 2320, 255, 63, GRAPHIRE }, - { "Wacom Volito2 4x5", WACOM_PKGLEN_GRAPHIRE, 5104, 3712, 511, 63, GRAPHIRE }, - { "Wacom Volito2 2x3", WACOM_PKGLEN_GRAPHIRE, 3248, 2320, 511, 63, GRAPHIRE }, - { "Wacom PenPartner2", WACOM_PKGLEN_GRAPHIRE, 3250, 2320, 511, 63, GRAPHIRE }, - { "Wacom Bamboo", WACOM_PKGLEN_BBFUN, 14760, 9225, 511, 63, WACOM_MO }, - { "Wacom Bamboo1", WACOM_PKGLEN_GRAPHIRE, 5104, 3712, 511, 63, GRAPHIRE }, - { "Wacom Intuos 4x5", WACOM_PKGLEN_INTUOS, 12700, 10600, 1023, 31, INTUOS }, - { "Wacom Intuos 6x8", WACOM_PKGLEN_INTUOS, 20320, 16240, 1023, 31, INTUOS }, - { "Wacom Intuos 9x12", WACOM_PKGLEN_INTUOS, 30480, 24060, 1023, 31, INTUOS }, - { "Wacom Intuos 12x12", WACOM_PKGLEN_INTUOS, 30480, 31680, 1023, 31, INTUOS }, - { "Wacom Intuos 12x18", WACOM_PKGLEN_INTUOS, 45720, 31680, 1023, 31, INTUOS }, - { "Wacom PL400", WACOM_PKGLEN_GRAPHIRE, 5408, 4056, 255, 0, PL }, - { "Wacom PL500", WACOM_PKGLEN_GRAPHIRE, 6144, 4608, 255, 0, PL }, - { "Wacom PL600", WACOM_PKGLEN_GRAPHIRE, 6126, 4604, 255, 0, PL }, - { "Wacom PL600SX", WACOM_PKGLEN_GRAPHIRE, 6260, 5016, 255, 0, PL }, - { "Wacom PL550", WACOM_PKGLEN_GRAPHIRE, 6144, 4608, 511, 0, PL }, - { "Wacom PL800", WACOM_PKGLEN_GRAPHIRE, 7220, 5780, 511, 0, PL }, - { "Wacom PL700", WACOM_PKGLEN_GRAPHIRE, 6758, 5406, 511, 0, PL }, - { "Wacom PL510", WACOM_PKGLEN_GRAPHIRE, 6282, 4762, 511, 0, PL }, - { "Wacom DTU710", WACOM_PKGLEN_GRAPHIRE, 34080, 27660, 511, 0, PL }, - { "Wacom DTF521", WACOM_PKGLEN_GRAPHIRE, 6282, 4762, 511, 0, PL }, - { "Wacom DTF720", WACOM_PKGLEN_GRAPHIRE, 6858, 5506, 511, 0, PL }, - { "Wacom DTF720a", WACOM_PKGLEN_GRAPHIRE, 6858, 5506, 511, 0, PL }, - { "Wacom Cintiq Partner", WACOM_PKGLEN_GRAPHIRE, 20480, 15360, 511, 0, PTU }, - { "Wacom Intuos2 4x5", WACOM_PKGLEN_INTUOS, 12700, 10600, 1023, 31, INTUOS }, - { "Wacom Intuos2 6x8", WACOM_PKGLEN_INTUOS, 20320, 16240, 1023, 31, INTUOS }, - { "Wacom Intuos2 9x12", WACOM_PKGLEN_INTUOS, 30480, 24060, 1023, 31, INTUOS }, - { "Wacom Intuos2 12x12", WACOM_PKGLEN_INTUOS, 30480, 31680, 1023, 31, INTUOS }, - { "Wacom Intuos2 12x18", WACOM_PKGLEN_INTUOS, 45720, 31680, 1023, 31, INTUOS }, - { "Wacom Intuos3 4x5", WACOM_PKGLEN_INTUOS, 25400, 20320, 1023, 63, INTUOS3S }, - { "Wacom Intuos3 6x8", WACOM_PKGLEN_INTUOS, 40640, 30480, 1023, 63, INTUOS3 }, - { "Wacom Intuos3 9x12", WACOM_PKGLEN_INTUOS, 60960, 45720, 1023, 63, INTUOS3 }, - { "Wacom Intuos3 12x12", WACOM_PKGLEN_INTUOS, 60960, 60960, 1023, 63, INTUOS3L }, - { "Wacom Intuos3 12x19", WACOM_PKGLEN_INTUOS, 97536, 60960, 1023, 63, INTUOS3L }, - { "Wacom Intuos3 6x11", WACOM_PKGLEN_INTUOS, 54204, 31750, 1023, 63, INTUOS3 }, - { "Wacom Intuos3 4x6", WACOM_PKGLEN_INTUOS, 31496, 19685, 1023, 63, INTUOS3S }, - { "Wacom Intuos4 4x6", WACOM_PKGLEN_INTUOS, 31496, 19685, 2047, 63, INTUOS4S }, - { "Wacom Intuos4 6x9", WACOM_PKGLEN_INTUOS, 44704, 27940, 2047, 63, INTUOS4 }, - { "Wacom Intuos4 8x13", WACOM_PKGLEN_INTUOS, 65024, 40640, 2047, 63, INTUOS4L }, - { "Wacom Intuos4 12x19", WACOM_PKGLEN_INTUOS, 97536, 60960, 2047, 63, INTUOS4L }, - { "Wacom Cintiq 21UX", WACOM_PKGLEN_INTUOS, 87200, 65600, 1023, 63, CINTIQ }, - { "Wacom Cintiq 20WSX", WACOM_PKGLEN_INTUOS, 86680, 54180, 1023, 63, WACOM_BEE }, - { "Wacom Cintiq 12WX", WACOM_PKGLEN_INTUOS, 53020, 33440, 1023, 63, WACOM_BEE }, - { "Wacom DTU1931", WACOM_PKGLEN_GRAPHIRE, 37832, 30305, 511, 0, PL }, - { "Wacom ISDv4 90", WACOM_PKGLEN_GRAPHIRE, 26202, 16325, 255, 0, TABLETPC }, - { "Wacom ISDv4 93", WACOM_PKGLEN_GRAPHIRE, 26202, 16325, 255, 0, TABLETPC }, - { "Wacom ISDv4 9A", WACOM_PKGLEN_GRAPHIRE, 26202, 16325, 255, 0, TABLETPC }, - { "Wacom ISDv4 9F", WACOM_PKGLEN_PENABLED, 26202, 16325, 255, 0, TABLETPC }, - { "Wacom ISDv4 E2", WACOM_PKGLEN_TPC2FG, 26202, 16325, 255, 0, TABLETPC2FG }, - { "Wacom ISDv4 E3", WACOM_PKGLEN_TPC2FG, 26202, 16325, 255, 0, TABLETPC2FG }, - { "Wacom Intuos2 6x8", WACOM_PKGLEN_INTUOS, 20320, 16240, 1023, 31, INTUOS }, +static struct wacom_features wacom_features_0x00 = + { "Wacom Penpartner", WACOM_PKGLEN_PENPRTN, 5040, 3780, 255, 0, PENPARTNER }; +static struct wacom_features wacom_features_0x10 = + { "Wacom Graphire", WACOM_PKGLEN_GRAPHIRE, 10206, 7422, 511, 63, GRAPHIRE }; +static struct wacom_features wacom_features_0x11 = + { "Wacom Graphire2 4x5", WACOM_PKGLEN_GRAPHIRE, 10206, 7422, 511, 63, GRAPHIRE }; +static struct wacom_features wacom_features_0x12 = + { "Wacom Graphire2 5x7", WACOM_PKGLEN_GRAPHIRE, 13918, 10206, 511, 63, GRAPHIRE }; +static struct wacom_features wacom_features_0x13 = + { "Wacom Graphire3", WACOM_PKGLEN_GRAPHIRE, 10208, 7424, 511, 63, GRAPHIRE }; +static struct wacom_features wacom_features_0x14 = + { "Wacom Graphire3 6x8", WACOM_PKGLEN_GRAPHIRE, 16704, 12064, 511, 63, GRAPHIRE }; +static struct wacom_features wacom_features_0x15 = + { "Wacom Graphire4 4x5", WACOM_PKGLEN_GRAPHIRE, 10208, 7424, 511, 63, WACOM_G4 }; +static struct wacom_features wacom_features_0x16 = + { "Wacom Graphire4 6x8", WACOM_PKGLEN_GRAPHIRE, 16704, 12064, 511, 63, WACOM_G4 }; +static struct wacom_features wacom_features_0x17 = + { "Wacom BambooFun 4x5", WACOM_PKGLEN_BBFUN, 14760, 9225, 511, 63, WACOM_MO }; +static struct wacom_features wacom_features_0x18 = + { "Wacom BambooFun 6x8", WACOM_PKGLEN_BBFUN, 21648, 13530, 511, 63, WACOM_MO }; +static struct wacom_features wacom_features_0x19 = + { "Wacom Bamboo1 Medium", WACOM_PKGLEN_GRAPHIRE, 16704, 12064, 511, 63, GRAPHIRE }; +static struct wacom_features wacom_features_0x60 = + { "Wacom Volito", WACOM_PKGLEN_GRAPHIRE, 5104, 3712, 511, 63, GRAPHIRE }; +static struct wacom_features wacom_features_0x61 = + { "Wacom PenStation2", WACOM_PKGLEN_GRAPHIRE, 3250, 2320, 255, 63, GRAPHIRE }; +static struct wacom_features wacom_features_0x62 = + { "Wacom Volito2 4x5", WACOM_PKGLEN_GRAPHIRE, 5104, 3712, 511, 63, GRAPHIRE }; +static struct wacom_features wacom_features_0x63 = + { "Wacom Volito2 2x3", WACOM_PKGLEN_GRAPHIRE, 3248, 2320, 511, 63, GRAPHIRE }; +static struct wacom_features wacom_features_0x64 = + { "Wacom PenPartner2", WACOM_PKGLEN_GRAPHIRE, 3250, 2320, 511, 63, GRAPHIRE }; +static struct wacom_features wacom_features_0x65 = + { "Wacom Bamboo", WACOM_PKGLEN_BBFUN, 14760, 9225, 511, 63, WACOM_MO }; +static struct wacom_features wacom_features_0x69 = + { "Wacom Bamboo1", WACOM_PKGLEN_GRAPHIRE, 5104, 3712, 511, 63, GRAPHIRE }; +static struct wacom_features wacom_features_0x20 = + { "Wacom Intuos 4x5", WACOM_PKGLEN_INTUOS, 12700, 10600, 1023, 31, INTUOS }; +static struct wacom_features wacom_features_0x21 = + { "Wacom Intuos 6x8", WACOM_PKGLEN_INTUOS, 20320, 16240, 1023, 31, INTUOS }; +static struct wacom_features wacom_features_0x22 = + { "Wacom Intuos 9x12", WACOM_PKGLEN_INTUOS, 30480, 24060, 1023, 31, INTUOS }; +static struct wacom_features wacom_features_0x23 = + { "Wacom Intuos 12x12", WACOM_PKGLEN_INTUOS, 30480, 31680, 1023, 31, INTUOS }; +static struct wacom_features wacom_features_0x24 = + { "Wacom Intuos 12x18", WACOM_PKGLEN_INTUOS, 45720, 31680, 1023, 31, INTUOS }; +static struct wacom_features wacom_features_0x30 = + { "Wacom PL400", WACOM_PKGLEN_GRAPHIRE, 5408, 4056, 255, 0, PL }; +static struct wacom_features wacom_features_0x31 = + { "Wacom PL500", WACOM_PKGLEN_GRAPHIRE, 6144, 4608, 255, 0, PL }; +static struct wacom_features wacom_features_0x32 = + { "Wacom PL600", WACOM_PKGLEN_GRAPHIRE, 6126, 4604, 255, 0, PL }; +static struct wacom_features wacom_features_0x33 = + { "Wacom PL600SX", WACOM_PKGLEN_GRAPHIRE, 6260, 5016, 255, 0, PL }; +static struct wacom_features wacom_features_0x34 = + { "Wacom PL550", WACOM_PKGLEN_GRAPHIRE, 6144, 4608, 511, 0, PL }; +static struct wacom_features wacom_features_0x35 = + { "Wacom PL800", WACOM_PKGLEN_GRAPHIRE, 7220, 5780, 511, 0, PL }; +static struct wacom_features wacom_features_0x37 = + { "Wacom PL700", WACOM_PKGLEN_GRAPHIRE, 6758, 5406, 511, 0, PL }; +static struct wacom_features wacom_features_0x38 = + { "Wacom PL510", WACOM_PKGLEN_GRAPHIRE, 6282, 4762, 511, 0, PL }; +static struct wacom_features wacom_features_0x39 = + { "Wacom DTU710", WACOM_PKGLEN_GRAPHIRE, 34080, 27660, 511, 0, PL }; +static struct wacom_features wacom_features_0xC4 = + { "Wacom DTF521", WACOM_PKGLEN_GRAPHIRE, 6282, 4762, 511, 0, PL }; +static struct wacom_features wacom_features_0xC0 = + { "Wacom DTF720", WACOM_PKGLEN_GRAPHIRE, 6858, 5506, 511, 0, PL }; +static struct wacom_features wacom_features_0xC2 = + { "Wacom DTF720a", WACOM_PKGLEN_GRAPHIRE, 6858, 5506, 511, 0, PL }; +static struct wacom_features wacom_features_0x03 = + { "Wacom Cintiq Partner", WACOM_PKGLEN_GRAPHIRE, 20480, 15360, 511, 0, PTU }; +static struct wacom_features wacom_features_0x41 = + { "Wacom Intuos2 4x5", WACOM_PKGLEN_INTUOS, 12700, 10600, 1023, 31, INTUOS }; +static struct wacom_features wacom_features_0x42 = + { "Wacom Intuos2 6x8", WACOM_PKGLEN_INTUOS, 20320, 16240, 1023, 31, INTUOS }; +static struct wacom_features wacom_features_0x43 = + { "Wacom Intuos2 9x12", WACOM_PKGLEN_INTUOS, 30480, 24060, 1023, 31, INTUOS }; +static struct wacom_features wacom_features_0x44 = + { "Wacom Intuos2 12x12", WACOM_PKGLEN_INTUOS, 30480, 31680, 1023, 31, INTUOS }; +static struct wacom_features wacom_features_0x45 = + { "Wacom Intuos2 12x18", WACOM_PKGLEN_INTUOS, 45720, 31680, 1023, 31, INTUOS }; +static struct wacom_features wacom_features_0xB0 = + { "Wacom Intuos3 4x5", WACOM_PKGLEN_INTUOS, 25400, 20320, 1023, 63, INTUOS3S }; +static struct wacom_features wacom_features_0xB1 = + { "Wacom Intuos3 6x8", WACOM_PKGLEN_INTUOS, 40640, 30480, 1023, 63, INTUOS3 }; +static struct wacom_features wacom_features_0xB2 = + { "Wacom Intuos3 9x12", WACOM_PKGLEN_INTUOS, 60960, 45720, 1023, 63, INTUOS3 }; +static struct wacom_features wacom_features_0xB3 = + { "Wacom Intuos3 12x12", WACOM_PKGLEN_INTUOS, 60960, 60960, 1023, 63, INTUOS3L }; +static struct wacom_features wacom_features_0xB4 = + { "Wacom Intuos3 12x19", WACOM_PKGLEN_INTUOS, 97536, 60960, 1023, 63, INTUOS3L }; +static struct wacom_features wacom_features_0xB5 = + { "Wacom Intuos3 6x11", WACOM_PKGLEN_INTUOS, 54204, 31750, 1023, 63, INTUOS3 }; +static struct wacom_features wacom_features_0xB7 = + { "Wacom Intuos3 4x6", WACOM_PKGLEN_INTUOS, 31496, 19685, 1023, 63, INTUOS3S }; +static struct wacom_features wacom_features_0xB8 = + { "Wacom Intuos4 4x6", WACOM_PKGLEN_INTUOS, 31496, 19685, 2047, 63, INTUOS4S }; +static struct wacom_features wacom_features_0xB9 = + { "Wacom Intuos4 6x9", WACOM_PKGLEN_INTUOS, 44704, 27940, 2047, 63, INTUOS4 }; +static struct wacom_features wacom_features_0xBA = + { "Wacom Intuos4 8x13", WACOM_PKGLEN_INTUOS, 65024, 40640, 2047, 63, INTUOS4L }; +static struct wacom_features wacom_features_0xBB = + { "Wacom Intuos4 12x19", WACOM_PKGLEN_INTUOS, 97536, 60960, 2047, 63, INTUOS4L }; +static struct wacom_features wacom_features_0x3F = + { "Wacom Cintiq 21UX", WACOM_PKGLEN_INTUOS, 87200, 65600, 1023, 63, CINTIQ }; +static struct wacom_features wacom_features_0xC5 = + { "Wacom Cintiq 20WSX", WACOM_PKGLEN_INTUOS, 86680, 54180, 1023, 63, WACOM_BEE }; +static struct wacom_features wacom_features_0xC6 = + { "Wacom Cintiq 12WX", WACOM_PKGLEN_INTUOS, 53020, 33440, 1023, 63, WACOM_BEE }; +static struct wacom_features wacom_features_0xC7 = + { "Wacom DTU1931", WACOM_PKGLEN_GRAPHIRE, 37832, 30305, 511, 0, PL }; +static struct wacom_features wacom_features_0x90 = + { "Wacom ISDv4 90", WACOM_PKGLEN_GRAPHIRE, 26202, 16325, 255, 0, TABLETPC }; +static struct wacom_features wacom_features_0x93 = + { "Wacom ISDv4 93", WACOM_PKGLEN_GRAPHIRE, 26202, 16325, 255, 0, TABLETPC }; +static struct wacom_features wacom_features_0x9A = + { "Wacom ISDv4 9A", WACOM_PKGLEN_GRAPHIRE, 26202, 16325, 255, 0, TABLETPC }; +static struct wacom_features wacom_features_0x9F = + { "Wacom ISDv4 9F", WACOM_PKGLEN_PENABLED, 26202, 16325, 255, 0, TABLETPC }; +static struct wacom_features wacom_features_0xE2 = + { "Wacom ISDv4 E2", WACOM_PKGLEN_TPC2FG, 26202, 16325, 255, 0, TABLETPC2FG }; +static struct wacom_features wacom_features_0xE3 = + { "Wacom ISDv4 E3", WACOM_PKGLEN_TPC2FG, 26202, 16325, 255, 0, TABLETPC2FG }; +static struct wacom_features wacom_features_0x47 = + { "Wacom Intuos2 6x8", WACOM_PKGLEN_INTUOS, 20320, 16240, 1023, 31, INTUOS }; + +#define USB_DEVICE_WACOM(prod) \ + USB_DEVICE(USB_VENDOR_ID_WACOM, prod), \ + .driver_info = (kernel_ulong_t)&wacom_features_##prod + +const struct usb_device_id wacom_ids[] = { + { USB_DEVICE_WACOM(0x00) }, + { USB_DEVICE_WACOM(0x10) }, + { USB_DEVICE_WACOM(0x11) }, + { USB_DEVICE_WACOM(0x12) }, + { USB_DEVICE_WACOM(0x13) }, + { USB_DEVICE_WACOM(0x14) }, + { USB_DEVICE_WACOM(0x15) }, + { USB_DEVICE_WACOM(0x16) }, + { USB_DEVICE_WACOM(0x17) }, + { USB_DEVICE_WACOM(0x18) }, + { USB_DEVICE_WACOM(0x19) }, + { USB_DEVICE_WACOM(0x60) }, + { USB_DEVICE_WACOM(0x61) }, + { USB_DEVICE_WACOM(0x62) }, + { USB_DEVICE_WACOM(0x63) }, + { USB_DEVICE_WACOM(0x64) }, + { USB_DEVICE_WACOM(0x65) }, + { USB_DEVICE_WACOM(0x69) }, + { USB_DEVICE_WACOM(0x20) }, + { USB_DEVICE_WACOM(0x21) }, + { USB_DEVICE_WACOM(0x22) }, + { USB_DEVICE_WACOM(0x23) }, + { USB_DEVICE_WACOM(0x24) }, + { USB_DEVICE_WACOM(0x30) }, + { USB_DEVICE_WACOM(0x31) }, + { USB_DEVICE_WACOM(0x32) }, + { USB_DEVICE_WACOM(0x33) }, + { USB_DEVICE_WACOM(0x34) }, + { USB_DEVICE_WACOM(0x35) }, + { USB_DEVICE_WACOM(0x37) }, + { USB_DEVICE_WACOM(0x38) }, + { USB_DEVICE_WACOM(0x39) }, + { USB_DEVICE_WACOM(0xC4) }, + { USB_DEVICE_WACOM(0xC0) }, + { USB_DEVICE_WACOM(0xC2) }, + { USB_DEVICE_WACOM(0x03) }, + { USB_DEVICE_WACOM(0x41) }, + { USB_DEVICE_WACOM(0x42) }, + { USB_DEVICE_WACOM(0x43) }, + { USB_DEVICE_WACOM(0x44) }, + { USB_DEVICE_WACOM(0x45) }, + { USB_DEVICE_WACOM(0xB0) }, + { USB_DEVICE_WACOM(0xB1) }, + { USB_DEVICE_WACOM(0xB2) }, + { USB_DEVICE_WACOM(0xB3) }, + { USB_DEVICE_WACOM(0xB4) }, + { USB_DEVICE_WACOM(0xB5) }, + { USB_DEVICE_WACOM(0xB7) }, + { USB_DEVICE_WACOM(0xB8) }, + { USB_DEVICE_WACOM(0xB9) }, + { USB_DEVICE_WACOM(0xBA) }, + { USB_DEVICE_WACOM(0xBB) }, + { USB_DEVICE_WACOM(0x3F) }, + { USB_DEVICE_WACOM(0xC5) }, + { USB_DEVICE_WACOM(0xC6) }, + { USB_DEVICE_WACOM(0xC7) }, + { USB_DEVICE_WACOM(0x90) }, + { USB_DEVICE_WACOM(0x93) }, + { USB_DEVICE_WACOM(0x9A) }, + { USB_DEVICE_WACOM(0x9F) }, + { USB_DEVICE_WACOM(0xE2) }, + { USB_DEVICE_WACOM(0xE3) }, + { USB_DEVICE_WACOM(0x47) }, { } }; - -static struct usb_device_id wacom_ids[] = { - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x00) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x10) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x11) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x12) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x13) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x14) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x15) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x16) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x17) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x18) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x19) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x60) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x61) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x62) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x63) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x64) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x65) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x69) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x20) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x21) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x22) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x23) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x24) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x30) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x31) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x32) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x33) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x34) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x35) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x37) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x38) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x39) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xC4) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xC0) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xC2) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x03) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x41) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x42) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x43) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x44) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x45) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xB0) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xB1) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xB2) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xB3) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xB4) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xB5) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xB7) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xB8) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xB9) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xBA) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xBB) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x3F) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xC5) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xC6) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xC7) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x90) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x93) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x9A) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x9F) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xE2) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xE3) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x47) }, - { } -}; - -const struct usb_device_id *get_device_table(void) -{ - const struct usb_device_id *id_table = wacom_ids; - - return id_table; -} - -struct wacom_features * get_wacom_feature(const struct usb_device_id *id) -{ - int index = id - wacom_ids; - struct wacom_features *wf = &wacom_features[index]; - - return wf; -} - MODULE_DEVICE_TABLE(usb, wacom_ids); -- cgit v1.2.3 From 4e45ad5e89128939c671e927f030cb3909fe1d69 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Tue, 16 Feb 2010 21:50:58 -0800 Subject: Input: sh_keysc - enable building on SH-Mobile ARM Update the Kconfig entry for the sh_keysc driver to enable build on SH-Mobile ARM platforms. Signed-off-by: Magnus Damm Signed-off-by: Dmitry Torokhov --- drivers/input/keyboard/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/input') diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig index 1ad9435d30aa..64c102355f53 100644 --- a/drivers/input/keyboard/Kconfig +++ b/drivers/input/keyboard/Kconfig @@ -376,7 +376,7 @@ config KEYBOARD_SUNKBD config KEYBOARD_SH_KEYSC tristate "SuperH KEYSC keypad support" - depends on SUPERH + depends on SUPERH || ARCH_SHMOBILE help Say Y here if you want to use a keypad attached to the KEYSC block on SuperH processors such as sh7722 and sh7343. -- cgit v1.2.3 From e33da8a5486aaadf5161118869e6cfb3d119beea Mon Sep 17 00:00:00 2001 From: Jason Childs Date: Wed, 17 Feb 2010 22:38:31 -0800 Subject: Input: wacom - use per-device instance of wacom_features Since we mangle data in wacom_features when dealing with certain devices let's use a private (per-device) instance of wacom_features in wacom_wac. This way same product ID can support more than one type of device, such as pen and touch, and not interfere with each other. Signed-off-by: Jason Childs Signed-off-by: Ping Cheng Signed-off-by: Dmitry Torokhov --- drivers/input/tablet/wacom_sys.c | 58 ++++++++++++++++++++++------------- drivers/input/tablet/wacom_wac.c | 66 ++++++++++++++++++++++------------------ drivers/input/tablet/wacom_wac.h | 10 +++--- 3 files changed, 78 insertions(+), 56 deletions(-) (limited to 'drivers/input') diff --git a/drivers/input/tablet/wacom_sys.c b/drivers/input/tablet/wacom_sys.c index be4b76f264a7..f22b88d03c6c 100644 --- a/drivers/input/tablet/wacom_sys.c +++ b/drivers/input/tablet/wacom_sys.c @@ -211,7 +211,8 @@ void input_dev_g(struct input_dev *input_dev, struct wacom_wac *wacom_wac) input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOOL_RUBBER) | BIT_MASK(BTN_TOOL_PEN) | BIT_MASK(BTN_STYLUS) | BIT_MASK(BTN_TOOL_MOUSE) | BIT_MASK(BTN_STYLUS2); - input_set_abs_params(input_dev, ABS_DISTANCE, 0, wacom_wac->features->distance_max, 0, 0); + input_set_abs_params(input_dev, ABS_DISTANCE, + 0, wacom_wac->features.distance_max, 0, 0); } void input_dev_i3s(struct input_dev *input_dev, struct wacom_wac *wacom_wac) @@ -261,7 +262,8 @@ void input_dev_i(struct input_dev *input_dev, struct wacom_wac *wacom_wac) BIT_MASK(BTN_TOOL_MOUSE) | BIT_MASK(BTN_TOOL_BRUSH) | BIT_MASK(BTN_TOOL_PENCIL) | BIT_MASK(BTN_TOOL_AIRBRUSH) | BIT_MASK(BTN_TOOL_LENS) | BIT_MASK(BTN_STYLUS2); - input_set_abs_params(input_dev, ABS_DISTANCE, 0, wacom_wac->features->distance_max, 0, 0); + input_set_abs_params(input_dev, ABS_DISTANCE, + 0, wacom_wac->features.distance_max, 0, 0); input_set_abs_params(input_dev, ABS_WHEEL, 0, 1023, 0, 0); input_set_abs_params(input_dev, ABS_TILT_X, 0, 127, 0, 0); input_set_abs_params(input_dev, ABS_TILT_Y, 0, 127, 0, 0); @@ -282,17 +284,19 @@ void input_dev_pt(struct input_dev *input_dev, struct wacom_wac *wacom_wac) void input_dev_tpc(struct input_dev *input_dev, struct wacom_wac *wacom_wac) { - if (wacom_wac->features->device_type == BTN_TOOL_DOUBLETAP || - wacom_wac->features->device_type == BTN_TOOL_TRIPLETAP) { - input_set_abs_params(input_dev, ABS_RX, 0, wacom_wac->features->x_phy, 0, 0); - input_set_abs_params(input_dev, ABS_RY, 0, wacom_wac->features->y_phy, 0, 0); - input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOOL_DOUBLETAP); + struct wacom_features *features = &wacom_wac->features; + + if (features->device_type == BTN_TOOL_DOUBLETAP || + features->device_type == BTN_TOOL_TRIPLETAP) { + input_set_abs_params(input_dev, ABS_RX, 0, features->x_phy, 0, 0); + input_set_abs_params(input_dev, ABS_RY, 0, features->y_phy, 0, 0); + __set_bit(BTN_TOOL_DOUBLETAP, input_dev->keybit); } } void input_dev_tpc2fg(struct input_dev *input_dev, struct wacom_wac *wacom_wac) { - if (wacom_wac->features->device_type == BTN_TOOL_TRIPLETAP) { + if (wacom_wac->features.device_type == BTN_TOOL_TRIPLETAP) { input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOOL_TRIPLETAP); input_dev->evbit[0] |= BIT_MASK(EV_MSC); input_dev->mscbit[0] |= BIT_MASK(MSC_SERIAL); @@ -530,26 +534,40 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i struct usb_endpoint_descriptor *endpoint; struct wacom *wacom; struct wacom_wac *wacom_wac; - struct wacom_features *features = (void *)id->driver_info; + struct wacom_features *features; struct input_dev *input_dev; - int error = -ENOMEM; + int error; - if (!features) + if (!id->driver_info) return -EINVAL; wacom = kzalloc(sizeof(struct wacom), GFP_KERNEL); wacom_wac = kzalloc(sizeof(struct wacom_wac), GFP_KERNEL); input_dev = input_allocate_device(); - if (!wacom || !input_dev || !wacom_wac) + if (!wacom || !input_dev || !wacom_wac) { + error = -ENOMEM; + goto fail1; + } + + wacom_wac->features = *((struct wacom_features *)id->driver_info); + features = &wacom_wac->features; + if (features->pktlen > WACOM_PKGLEN_MAX) { + error = -EINVAL; goto fail1; + } - wacom_wac->data = usb_buffer_alloc(dev, WACOM_PKGLEN_MAX, GFP_KERNEL, &wacom->data_dma); - if (!wacom_wac->data) + wacom_wac->data = usb_buffer_alloc(dev, WACOM_PKGLEN_MAX, + GFP_KERNEL, &wacom->data_dma); + if (!wacom_wac->data) { + error = -ENOMEM; goto fail1; + } wacom->irq = usb_alloc_urb(0, GFP_KERNEL); - if (!wacom->irq) + if (!wacom->irq) { + error = -ENOMEM; goto fail2; + } wacom->usbdev = dev; wacom->dev = input_dev; @@ -558,11 +576,6 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i usb_make_path(dev, wacom->phys, sizeof(wacom->phys)); strlcat(wacom->phys, "/input0", sizeof(wacom->phys)); - wacom_wac->features = features; - BUG_ON(features->pktlen > WACOM_PKGLEN_MAX); - - input_dev->name = wacom_wac->features->name; - wacom->wacom_wac = wacom_wac; usb_to_input_id(dev, &input_dev->id); input_dev->dev.parent = &intf->dev; @@ -579,6 +592,9 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i if (error) goto fail2; + input_dev->name = features->name; + wacom->wacom_wac = wacom_wac; + input_dev->evbit[0] |= BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOUCH); @@ -643,7 +659,7 @@ static int wacom_suspend(struct usb_interface *intf, pm_message_t message) static int wacom_resume(struct usb_interface *intf) { struct wacom *wacom = usb_get_intfdata(intf); - struct wacom_features *features = wacom->wacom_wac->features; + struct wacom_features *features = &wacom->wacom_wac->features; int rv; mutex_lock(&wacom->lock); diff --git a/drivers/input/tablet/wacom_wac.c b/drivers/input/tablet/wacom_wac.c index 56aaf0164a56..e4a1a7dcd9a4 100644 --- a/drivers/input/tablet/wacom_wac.c +++ b/drivers/input/tablet/wacom_wac.c @@ -55,6 +55,7 @@ static int wacom_penpartner_irq(struct wacom_wac *wacom, void *wcombo) static int wacom_pl_irq(struct wacom_wac *wacom, void *wcombo) { + struct wacom_features *features = &wacom->features; unsigned char *data = wacom->data; int prox, pressure; @@ -68,9 +69,9 @@ static int wacom_pl_irq(struct wacom_wac *wacom, void *wcombo) if (prox) { wacom->id[0] = ERASER_DEVICE_ID; pressure = (signed char)((data[7] << 1) | ((data[4] >> 2) & 1)); - if (wacom->features->pressure_max > 255) + if (features->pressure_max > 255) pressure = (pressure << 1) | ((data[4] >> 6) & 1); - pressure += (wacom->features->pressure_max + 1) / 2; + pressure += (features->pressure_max + 1) / 2; /* * if going from out of proximity into proximity select between the eraser @@ -152,6 +153,7 @@ static int wacom_ptu_irq(struct wacom_wac *wacom, void *wcombo) static int wacom_graphire_irq(struct wacom_wac *wacom, void *wcombo) { + struct wacom_features *features = &wacom->features; unsigned char *data = wacom->data; int x, y, rw; static int penData = 0; @@ -179,8 +181,7 @@ static int wacom_graphire_irq(struct wacom_wac *wacom, void *wcombo) case 2: /* Mouse with wheel */ wacom_report_key(wcombo, BTN_MIDDLE, data[1] & 0x04); - if (wacom->features->type == WACOM_G4 || - wacom->features->type == WACOM_MO) { + if (features->type == WACOM_G4 || features->type == WACOM_MO) { rw = data[7] & 0x04 ? (data[7] & 0x03)-4 : (data[7] & 0x03); wacom_report_rel(wcombo, REL_WHEEL, -rw); } else @@ -192,8 +193,7 @@ static int wacom_graphire_irq(struct wacom_wac *wacom, void *wcombo) wacom->id[0] = CURSOR_DEVICE_ID; wacom_report_key(wcombo, BTN_LEFT, data[1] & 0x01); wacom_report_key(wcombo, BTN_RIGHT, data[1] & 0x02); - if (wacom->features->type == WACOM_G4 || - wacom->features->type == WACOM_MO) + if (features->type == WACOM_G4 || features->type == WACOM_MO) wacom_report_abs(wcombo, ABS_DISTANCE, data[6] & 0x3f); else wacom_report_abs(wcombo, ABS_DISTANCE, data[7] & 0x3f); @@ -230,7 +230,7 @@ static int wacom_graphire_irq(struct wacom_wac *wacom, void *wcombo) } /* send pad data */ - switch (wacom->features->type) { + switch (features->type) { case WACOM_G4: if (data[7] & 0xf8) { if (penData) { @@ -300,11 +300,12 @@ static int wacom_graphire_irq(struct wacom_wac *wacom, void *wcombo) static int wacom_intuos_inout(struct wacom_wac *wacom, void *wcombo) { + struct wacom_features *features = &wacom->features; unsigned char *data = wacom->data; int idx = 0; /* tool number */ - if (wacom->features->type == INTUOS) + if (features->type == INTUOS) idx = data[1] & 0x01; /* Enter report */ @@ -402,7 +403,7 @@ static int wacom_intuos_inout(struct wacom_wac *wacom, void *wcombo) wacom_report_key(wcombo, BTN_STYLUS2, 0); wacom_report_key(wcombo, BTN_TOUCH, 0); wacom_report_abs(wcombo, ABS_WHEEL, 0); - if (wacom->features->type >= INTUOS3S) + if (features->type >= INTUOS3S) wacom_report_abs(wcombo, ABS_Z, 0); } wacom_report_key(wcombo, wacom->tool[idx], 0); @@ -416,13 +417,14 @@ static int wacom_intuos_inout(struct wacom_wac *wacom, void *wcombo) static void wacom_intuos_general(struct wacom_wac *wacom, void *wcombo) { + struct wacom_features *features = &wacom->features; unsigned char *data = wacom->data; unsigned int t; /* general pen packet */ if ((data[1] & 0xb8) == 0xa0) { t = (data[6] << 2) | ((data[7] >> 6) & 3); - if (wacom->features->type >= INTUOS4S && wacom->features->type <= INTUOS4L) + if (features->type >= INTUOS4S && features->type <= INTUOS4L) t = (t << 1) | (data[1] & 1); wacom_report_abs(wcombo, ABS_PRESSURE, t); wacom_report_abs(wcombo, ABS_TILT_X, @@ -446,6 +448,7 @@ static void wacom_intuos_general(struct wacom_wac *wacom, void *wcombo) static int wacom_intuos_irq(struct wacom_wac *wacom, void *wcombo) { + struct wacom_features *features = &wacom->features; unsigned char *data = wacom->data; unsigned int t; int idx = 0, result; @@ -457,7 +460,7 @@ static int wacom_intuos_irq(struct wacom_wac *wacom, void *wcombo) } /* tool number */ - if (wacom->features->type == INTUOS) + if (features->type == INTUOS) idx = data[1] & 0x01; /* pad packets. Works as a second tool and is always in prox */ @@ -466,7 +469,7 @@ static int wacom_intuos_irq(struct wacom_wac *wacom, void *wcombo) if (wacom->tool[1] != BTN_TOOL_FINGER) wacom->tool[1] = BTN_TOOL_FINGER; - if (wacom->features->type >= INTUOS4S && wacom->features->type <= INTUOS4L) { + if (features->type >= INTUOS4S && features->type <= INTUOS4L) { wacom_report_key(wcombo, BTN_0, (data[2] & 0x01)); wacom_report_key(wcombo, BTN_1, (data[3] & 0x01)); wacom_report_key(wcombo, BTN_2, (data[3] & 0x02)); @@ -480,7 +483,7 @@ static int wacom_intuos_irq(struct wacom_wac *wacom, void *wcombo) /* Out of proximity, clear wheel value. */ wacom_report_abs(wcombo, ABS_WHEEL, 0); } - if (wacom->features->type != INTUOS4S) { + if (features->type != INTUOS4S) { wacom_report_key(wcombo, BTN_7, (data[3] & 0x40)); wacom_report_key(wcombo, BTN_8, (data[3] & 0x80)); } @@ -528,18 +531,20 @@ static int wacom_intuos_irq(struct wacom_wac *wacom, void *wcombo) return 0; /* Only large Intuos support Lense Cursor */ - if ((wacom->tool[idx] == BTN_TOOL_LENS) - && ((wacom->features->type == INTUOS3) - || (wacom->features->type == INTUOS3S) - || (wacom->features->type == INTUOS4) - || (wacom->features->type == INTUOS4S))) + if (wacom->tool[idx] == BTN_TOOL_LENS && + (features->type == INTUOS3 || + features->type == INTUOS3S || + features->type == INTUOS4 || + features->type == INTUOS4S)) { + return 0; + } /* Cintiq doesn't send data when RDY bit isn't set */ - if ((wacom->features->type == CINTIQ) && !(data[1] & 0x40)) + if (features->type == CINTIQ && !(data[1] & 0x40)) return 0; - if (wacom->features->type >= INTUOS3S) { + if (features->type >= INTUOS3S) { wacom_report_abs(wcombo, ABS_X, (data[2] << 9) | (data[3] << 1) | ((data[9] >> 1) & 1)); wacom_report_abs(wcombo, ABS_Y, (data[4] << 9) | (data[5] << 1) | (data[9] & 1)); wacom_report_abs(wcombo, ABS_DISTANCE, ((data[9] >> 2) & 0x3f)); @@ -557,7 +562,7 @@ static int wacom_intuos_irq(struct wacom_wac *wacom, void *wcombo) if (data[1] & 0x02) { /* Rotation packet */ - if (wacom->features->type >= INTUOS3S) { + if (features->type >= INTUOS3S) { /* I3 marker pen rotation */ t = (data[6] << 3) | ((data[7] >> 5) & 7); t = (data[7] & 0x20) ? ((t > 900) ? ((t-1) / 2 - 1350) : @@ -570,7 +575,7 @@ static int wacom_intuos_irq(struct wacom_wac *wacom, void *wcombo) ((t - 1) / 2) : -t / 2); } - } else if (!(data[1] & 0x10) && wacom->features->type < INTUOS3S) { + } else if (!(data[1] & 0x10) && features->type < INTUOS3S) { /* 4D mouse packet */ wacom_report_key(wcombo, BTN_LEFT, data[8] & 0x01); wacom_report_key(wcombo, BTN_MIDDLE, data[8] & 0x02); @@ -583,7 +588,7 @@ static int wacom_intuos_irq(struct wacom_wac *wacom, void *wcombo) } else if (wacom->tool[idx] == BTN_TOOL_MOUSE) { /* I4 mouse */ - if (wacom->features->type >= INTUOS4S && wacom->features->type <= INTUOS4L) { + if (features->type >= INTUOS4S && features->type <= INTUOS4L) { wacom_report_key(wcombo, BTN_LEFT, data[6] & 0x01); wacom_report_key(wcombo, BTN_MIDDLE, data[6] & 0x02); wacom_report_key(wcombo, BTN_RIGHT, data[6] & 0x04); @@ -604,13 +609,13 @@ static int wacom_intuos_irq(struct wacom_wac *wacom, void *wcombo) - ((data[8] & 0x02) >> 1)); /* I3 2D mouse side buttons */ - if (wacom->features->type >= INTUOS3S && wacom->features->type <= INTUOS3L) { + if (features->type >= INTUOS3S && features->type <= INTUOS3L) { wacom_report_key(wcombo, BTN_SIDE, data[8] & 0x40); wacom_report_key(wcombo, BTN_EXTRA, data[8] & 0x20); } } - } else if ((wacom->features->type < INTUOS3S || wacom->features->type == INTUOS3L || - wacom->features->type == INTUOS4L) && + } else if ((features->type < INTUOS3S || features->type == INTUOS3L || + features->type == INTUOS4L) && wacom->tool[idx] == BTN_TOOL_LENS) { /* Lens cursor packets */ wacom_report_key(wcombo, BTN_LEFT, data[8] & 0x01); @@ -718,6 +723,7 @@ static void wacom_tpc_touch_in(struct wacom_wac *wacom, void *wcombo) static int wacom_tpc_irq(struct wacom_wac *wacom, void *wcombo) { + struct wacom_features *features = &wacom->features; char *data = wacom->data; int prox = 0, pressure, idx = -1; static int stylusInProx, touchInProx = 1, touchOut; @@ -791,7 +797,7 @@ static int wacom_tpc_irq(struct wacom_wac *wacom, void *wcombo) wacom_report_abs(wcombo, ABS_Y, wacom_le16_to_cpu(&data[4])); pressure = ((data[7] & 0x01) << 8) | data[6]; if (pressure < 0) - pressure = wacom->features->pressure_max + pressure + 1; + pressure = features->pressure_max + pressure + 1; wacom_report_abs(wcombo, ABS_PRESSURE, pressure); wacom_report_key(wcombo, BTN_TOUCH, data[1] & 0x05); } else { @@ -815,7 +821,7 @@ static int wacom_tpc_irq(struct wacom_wac *wacom, void *wcombo) int wacom_wac_irq(struct wacom_wac *wacom_wac, void *wcombo) { - switch (wacom_wac->features->type) { + switch (wacom_wac->features.type) { case PENPARTNER: return wacom_penpartner_irq(wacom_wac, wcombo); @@ -853,7 +859,7 @@ int wacom_wac_irq(struct wacom_wac *wacom_wac, void *wcombo) void wacom_init_input_dev(struct input_dev *input_dev, struct wacom_wac *wacom_wac) { - switch (wacom_wac->features->type) { + switch (wacom_wac->features.type) { case WACOM_MO: input_dev_mo(input_dev, wacom_wac); case WACOM_G4: @@ -888,7 +894,7 @@ void wacom_init_input_dev(struct input_dev *input_dev, struct wacom_wac *wacom_w /* fall through */ case TABLETPC: input_dev_tpc(input_dev, wacom_wac); - if (wacom_wac->features->device_type != BTN_TOOL_PEN) + if (wacom_wac->features.device_type != BTN_TOOL_PEN) break; /* no need to process stylus stuff */ /* fall through */ diff --git a/drivers/input/tablet/wacom_wac.h b/drivers/input/tablet/wacom_wac.h index ee01e1902785..3f4b89d51fe2 100644 --- a/drivers/input/tablet/wacom_wac.h +++ b/drivers/input/tablet/wacom_wac.h @@ -15,11 +15,11 @@ /* packet length for individual models */ #define WACOM_PKGLEN_PENPRTN 7 #define WACOM_PKGLEN_GRAPHIRE 8 -#define WACOM_PKGLEN_BBFUN 9 -#define WACOM_PKGLEN_INTUOS 10 +#define WACOM_PKGLEN_BBFUN 9 +#define WACOM_PKGLEN_INTUOS 10 #define WACOM_PKGLEN_PENABLED 8 #define WACOM_PKGLEN_TPC1FG 5 -#define WACOM_PKGLEN_TPC2FG 14 +#define WACOM_PKGLEN_TPC2FG 14 /* device IDs */ #define STYLUS_DEVICE_ID 0x02 @@ -58,7 +58,7 @@ enum { }; struct wacom_features { - char *name; + const char *name; int pktlen; int x_max; int y_max; @@ -77,7 +77,7 @@ struct wacom_wac { int tool[2]; int id[2]; __u32 serial[2]; - struct wacom_features *features; + struct wacom_features features; }; #endif -- cgit v1.2.3 From e87a344d0eef52cadcd5e1ef33a8771afc879896 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Thu, 18 Feb 2010 01:51:47 -0800 Subject: Input: wacom - constify product features data Features are not supposed to be modified; devices use their own private copies, so let's mark them const. Signed-off-by: Dmitry Torokhov --- drivers/input/tablet/wacom_wac.c | 126 +++++++++++++++++++-------------------- 1 file changed, 63 insertions(+), 63 deletions(-) (limited to 'drivers/input') diff --git a/drivers/input/tablet/wacom_wac.c b/drivers/input/tablet/wacom_wac.c index e4a1a7dcd9a4..3d81443e683a 100644 --- a/drivers/input/tablet/wacom_wac.c +++ b/drivers/input/tablet/wacom_wac.c @@ -909,131 +909,131 @@ void wacom_init_input_dev(struct input_dev *input_dev, struct wacom_wac *wacom_w return; } -static struct wacom_features wacom_features_0x00 = +static const struct wacom_features wacom_features_0x00 = { "Wacom Penpartner", WACOM_PKGLEN_PENPRTN, 5040, 3780, 255, 0, PENPARTNER }; -static struct wacom_features wacom_features_0x10 = +static const struct wacom_features wacom_features_0x10 = { "Wacom Graphire", WACOM_PKGLEN_GRAPHIRE, 10206, 7422, 511, 63, GRAPHIRE }; -static struct wacom_features wacom_features_0x11 = +static const struct wacom_features wacom_features_0x11 = { "Wacom Graphire2 4x5", WACOM_PKGLEN_GRAPHIRE, 10206, 7422, 511, 63, GRAPHIRE }; -static struct wacom_features wacom_features_0x12 = +static const struct wacom_features wacom_features_0x12 = { "Wacom Graphire2 5x7", WACOM_PKGLEN_GRAPHIRE, 13918, 10206, 511, 63, GRAPHIRE }; -static struct wacom_features wacom_features_0x13 = +static const struct wacom_features wacom_features_0x13 = { "Wacom Graphire3", WACOM_PKGLEN_GRAPHIRE, 10208, 7424, 511, 63, GRAPHIRE }; -static struct wacom_features wacom_features_0x14 = +static const struct wacom_features wacom_features_0x14 = { "Wacom Graphire3 6x8", WACOM_PKGLEN_GRAPHIRE, 16704, 12064, 511, 63, GRAPHIRE }; -static struct wacom_features wacom_features_0x15 = +static const struct wacom_features wacom_features_0x15 = { "Wacom Graphire4 4x5", WACOM_PKGLEN_GRAPHIRE, 10208, 7424, 511, 63, WACOM_G4 }; -static struct wacom_features wacom_features_0x16 = +static const struct wacom_features wacom_features_0x16 = { "Wacom Graphire4 6x8", WACOM_PKGLEN_GRAPHIRE, 16704, 12064, 511, 63, WACOM_G4 }; -static struct wacom_features wacom_features_0x17 = +static const struct wacom_features wacom_features_0x17 = { "Wacom BambooFun 4x5", WACOM_PKGLEN_BBFUN, 14760, 9225, 511, 63, WACOM_MO }; -static struct wacom_features wacom_features_0x18 = +static const struct wacom_features wacom_features_0x18 = { "Wacom BambooFun 6x8", WACOM_PKGLEN_BBFUN, 21648, 13530, 511, 63, WACOM_MO }; -static struct wacom_features wacom_features_0x19 = +static const struct wacom_features wacom_features_0x19 = { "Wacom Bamboo1 Medium", WACOM_PKGLEN_GRAPHIRE, 16704, 12064, 511, 63, GRAPHIRE }; -static struct wacom_features wacom_features_0x60 = +static const struct wacom_features wacom_features_0x60 = { "Wacom Volito", WACOM_PKGLEN_GRAPHIRE, 5104, 3712, 511, 63, GRAPHIRE }; -static struct wacom_features wacom_features_0x61 = +static const struct wacom_features wacom_features_0x61 = { "Wacom PenStation2", WACOM_PKGLEN_GRAPHIRE, 3250, 2320, 255, 63, GRAPHIRE }; -static struct wacom_features wacom_features_0x62 = +static const struct wacom_features wacom_features_0x62 = { "Wacom Volito2 4x5", WACOM_PKGLEN_GRAPHIRE, 5104, 3712, 511, 63, GRAPHIRE }; -static struct wacom_features wacom_features_0x63 = +static const struct wacom_features wacom_features_0x63 = { "Wacom Volito2 2x3", WACOM_PKGLEN_GRAPHIRE, 3248, 2320, 511, 63, GRAPHIRE }; -static struct wacom_features wacom_features_0x64 = +static const struct wacom_features wacom_features_0x64 = { "Wacom PenPartner2", WACOM_PKGLEN_GRAPHIRE, 3250, 2320, 511, 63, GRAPHIRE }; -static struct wacom_features wacom_features_0x65 = +static const struct wacom_features wacom_features_0x65 = { "Wacom Bamboo", WACOM_PKGLEN_BBFUN, 14760, 9225, 511, 63, WACOM_MO }; -static struct wacom_features wacom_features_0x69 = +static const struct wacom_features wacom_features_0x69 = { "Wacom Bamboo1", WACOM_PKGLEN_GRAPHIRE, 5104, 3712, 511, 63, GRAPHIRE }; -static struct wacom_features wacom_features_0x20 = +static const struct wacom_features wacom_features_0x20 = { "Wacom Intuos 4x5", WACOM_PKGLEN_INTUOS, 12700, 10600, 1023, 31, INTUOS }; -static struct wacom_features wacom_features_0x21 = +static const struct wacom_features wacom_features_0x21 = { "Wacom Intuos 6x8", WACOM_PKGLEN_INTUOS, 20320, 16240, 1023, 31, INTUOS }; -static struct wacom_features wacom_features_0x22 = +static const struct wacom_features wacom_features_0x22 = { "Wacom Intuos 9x12", WACOM_PKGLEN_INTUOS, 30480, 24060, 1023, 31, INTUOS }; -static struct wacom_features wacom_features_0x23 = +static const struct wacom_features wacom_features_0x23 = { "Wacom Intuos 12x12", WACOM_PKGLEN_INTUOS, 30480, 31680, 1023, 31, INTUOS }; -static struct wacom_features wacom_features_0x24 = +static const struct wacom_features wacom_features_0x24 = { "Wacom Intuos 12x18", WACOM_PKGLEN_INTUOS, 45720, 31680, 1023, 31, INTUOS }; -static struct wacom_features wacom_features_0x30 = +static const struct wacom_features wacom_features_0x30 = { "Wacom PL400", WACOM_PKGLEN_GRAPHIRE, 5408, 4056, 255, 0, PL }; -static struct wacom_features wacom_features_0x31 = +static const struct wacom_features wacom_features_0x31 = { "Wacom PL500", WACOM_PKGLEN_GRAPHIRE, 6144, 4608, 255, 0, PL }; -static struct wacom_features wacom_features_0x32 = +static const struct wacom_features wacom_features_0x32 = { "Wacom PL600", WACOM_PKGLEN_GRAPHIRE, 6126, 4604, 255, 0, PL }; -static struct wacom_features wacom_features_0x33 = +static const struct wacom_features wacom_features_0x33 = { "Wacom PL600SX", WACOM_PKGLEN_GRAPHIRE, 6260, 5016, 255, 0, PL }; -static struct wacom_features wacom_features_0x34 = +static const struct wacom_features wacom_features_0x34 = { "Wacom PL550", WACOM_PKGLEN_GRAPHIRE, 6144, 4608, 511, 0, PL }; -static struct wacom_features wacom_features_0x35 = +static const struct wacom_features wacom_features_0x35 = { "Wacom PL800", WACOM_PKGLEN_GRAPHIRE, 7220, 5780, 511, 0, PL }; -static struct wacom_features wacom_features_0x37 = +static const struct wacom_features wacom_features_0x37 = { "Wacom PL700", WACOM_PKGLEN_GRAPHIRE, 6758, 5406, 511, 0, PL }; -static struct wacom_features wacom_features_0x38 = +static const struct wacom_features wacom_features_0x38 = { "Wacom PL510", WACOM_PKGLEN_GRAPHIRE, 6282, 4762, 511, 0, PL }; -static struct wacom_features wacom_features_0x39 = +static const struct wacom_features wacom_features_0x39 = { "Wacom DTU710", WACOM_PKGLEN_GRAPHIRE, 34080, 27660, 511, 0, PL }; -static struct wacom_features wacom_features_0xC4 = +static const struct wacom_features wacom_features_0xC4 = { "Wacom DTF521", WACOM_PKGLEN_GRAPHIRE, 6282, 4762, 511, 0, PL }; -static struct wacom_features wacom_features_0xC0 = +static const struct wacom_features wacom_features_0xC0 = { "Wacom DTF720", WACOM_PKGLEN_GRAPHIRE, 6858, 5506, 511, 0, PL }; -static struct wacom_features wacom_features_0xC2 = +static const struct wacom_features wacom_features_0xC2 = { "Wacom DTF720a", WACOM_PKGLEN_GRAPHIRE, 6858, 5506, 511, 0, PL }; -static struct wacom_features wacom_features_0x03 = +static const struct wacom_features wacom_features_0x03 = { "Wacom Cintiq Partner", WACOM_PKGLEN_GRAPHIRE, 20480, 15360, 511, 0, PTU }; -static struct wacom_features wacom_features_0x41 = +static const struct wacom_features wacom_features_0x41 = { "Wacom Intuos2 4x5", WACOM_PKGLEN_INTUOS, 12700, 10600, 1023, 31, INTUOS }; -static struct wacom_features wacom_features_0x42 = +static const struct wacom_features wacom_features_0x42 = { "Wacom Intuos2 6x8", WACOM_PKGLEN_INTUOS, 20320, 16240, 1023, 31, INTUOS }; -static struct wacom_features wacom_features_0x43 = +static const struct wacom_features wacom_features_0x43 = { "Wacom Intuos2 9x12", WACOM_PKGLEN_INTUOS, 30480, 24060, 1023, 31, INTUOS }; -static struct wacom_features wacom_features_0x44 = +static const struct wacom_features wacom_features_0x44 = { "Wacom Intuos2 12x12", WACOM_PKGLEN_INTUOS, 30480, 31680, 1023, 31, INTUOS }; -static struct wacom_features wacom_features_0x45 = +static const struct wacom_features wacom_features_0x45 = { "Wacom Intuos2 12x18", WACOM_PKGLEN_INTUOS, 45720, 31680, 1023, 31, INTUOS }; -static struct wacom_features wacom_features_0xB0 = +static const struct wacom_features wacom_features_0xB0 = { "Wacom Intuos3 4x5", WACOM_PKGLEN_INTUOS, 25400, 20320, 1023, 63, INTUOS3S }; -static struct wacom_features wacom_features_0xB1 = +static const struct wacom_features wacom_features_0xB1 = { "Wacom Intuos3 6x8", WACOM_PKGLEN_INTUOS, 40640, 30480, 1023, 63, INTUOS3 }; -static struct wacom_features wacom_features_0xB2 = +static const struct wacom_features wacom_features_0xB2 = { "Wacom Intuos3 9x12", WACOM_PKGLEN_INTUOS, 60960, 45720, 1023, 63, INTUOS3 }; -static struct wacom_features wacom_features_0xB3 = +static const struct wacom_features wacom_features_0xB3 = { "Wacom Intuos3 12x12", WACOM_PKGLEN_INTUOS, 60960, 60960, 1023, 63, INTUOS3L }; -static struct wacom_features wacom_features_0xB4 = +static const struct wacom_features wacom_features_0xB4 = { "Wacom Intuos3 12x19", WACOM_PKGLEN_INTUOS, 97536, 60960, 1023, 63, INTUOS3L }; -static struct wacom_features wacom_features_0xB5 = +static const struct wacom_features wacom_features_0xB5 = { "Wacom Intuos3 6x11", WACOM_PKGLEN_INTUOS, 54204, 31750, 1023, 63, INTUOS3 }; -static struct wacom_features wacom_features_0xB7 = +static const struct wacom_features wacom_features_0xB7 = { "Wacom Intuos3 4x6", WACOM_PKGLEN_INTUOS, 31496, 19685, 1023, 63, INTUOS3S }; -static struct wacom_features wacom_features_0xB8 = +static const struct wacom_features wacom_features_0xB8 = { "Wacom Intuos4 4x6", WACOM_PKGLEN_INTUOS, 31496, 19685, 2047, 63, INTUOS4S }; -static struct wacom_features wacom_features_0xB9 = +static const struct wacom_features wacom_features_0xB9 = { "Wacom Intuos4 6x9", WACOM_PKGLEN_INTUOS, 44704, 27940, 2047, 63, INTUOS4 }; -static struct wacom_features wacom_features_0xBA = +static const struct wacom_features wacom_features_0xBA = { "Wacom Intuos4 8x13", WACOM_PKGLEN_INTUOS, 65024, 40640, 2047, 63, INTUOS4L }; -static struct wacom_features wacom_features_0xBB = +static const struct wacom_features wacom_features_0xBB = { "Wacom Intuos4 12x19", WACOM_PKGLEN_INTUOS, 97536, 60960, 2047, 63, INTUOS4L }; -static struct wacom_features wacom_features_0x3F = +static const struct wacom_features wacom_features_0x3F = { "Wacom Cintiq 21UX", WACOM_PKGLEN_INTUOS, 87200, 65600, 1023, 63, CINTIQ }; -static struct wacom_features wacom_features_0xC5 = +static const struct wacom_features wacom_features_0xC5 = { "Wacom Cintiq 20WSX", WACOM_PKGLEN_INTUOS, 86680, 54180, 1023, 63, WACOM_BEE }; -static struct wacom_features wacom_features_0xC6 = +static const struct wacom_features wacom_features_0xC6 = { "Wacom Cintiq 12WX", WACOM_PKGLEN_INTUOS, 53020, 33440, 1023, 63, WACOM_BEE }; -static struct wacom_features wacom_features_0xC7 = +static const struct wacom_features wacom_features_0xC7 = { "Wacom DTU1931", WACOM_PKGLEN_GRAPHIRE, 37832, 30305, 511, 0, PL }; -static struct wacom_features wacom_features_0x90 = +static const struct wacom_features wacom_features_0x90 = { "Wacom ISDv4 90", WACOM_PKGLEN_GRAPHIRE, 26202, 16325, 255, 0, TABLETPC }; -static struct wacom_features wacom_features_0x93 = +static const struct wacom_features wacom_features_0x93 = { "Wacom ISDv4 93", WACOM_PKGLEN_GRAPHIRE, 26202, 16325, 255, 0, TABLETPC }; -static struct wacom_features wacom_features_0x9A = +static const struct wacom_features wacom_features_0x9A = { "Wacom ISDv4 9A", WACOM_PKGLEN_GRAPHIRE, 26202, 16325, 255, 0, TABLETPC }; -static struct wacom_features wacom_features_0x9F = +static const struct wacom_features wacom_features_0x9F = { "Wacom ISDv4 9F", WACOM_PKGLEN_PENABLED, 26202, 16325, 255, 0, TABLETPC }; -static struct wacom_features wacom_features_0xE2 = +static const struct wacom_features wacom_features_0xE2 = { "Wacom ISDv4 E2", WACOM_PKGLEN_TPC2FG, 26202, 16325, 255, 0, TABLETPC2FG }; -static struct wacom_features wacom_features_0xE3 = +static const struct wacom_features wacom_features_0xE3 = { "Wacom ISDv4 E3", WACOM_PKGLEN_TPC2FG, 26202, 16325, 255, 0, TABLETPC2FG }; -static struct wacom_features wacom_features_0x47 = +static const struct wacom_features wacom_features_0x47 = { "Wacom Intuos2 6x8", WACOM_PKGLEN_INTUOS, 20320, 16240, 1023, 31, INTUOS }; #define USB_DEVICE_WACOM(prod) \ -- cgit v1.2.3 From 2f09586557ed9b6d50bc8bb5104e70006513bdc2 Mon Sep 17 00:00:00 2001 From: Vasily Khoruzhick Date: Fri, 19 Feb 2010 01:18:11 -0800 Subject: Input: s3c24xx_ts - re-enable IRQ on resume IRQ should be re-enabled on resume, otherwise driver stops reporting events. Signed-off-by: Vasily Khoruzhick Signed-off-by: Dmitry Torokhov --- drivers/input/touchscreen/s3c2410_ts.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/input') diff --git a/drivers/input/touchscreen/s3c2410_ts.c b/drivers/input/touchscreen/s3c2410_ts.c index 6386b441ef85..ffc355e696dc 100644 --- a/drivers/input/touchscreen/s3c2410_ts.c +++ b/drivers/input/touchscreen/s3c2410_ts.c @@ -401,6 +401,7 @@ static int s3c2410ts_resume(struct device *dev) struct s3c2410_ts_mach_info *info = pdev->dev.platform_data; clk_enable(ts.clock); + enable_irq(ts.irq_tc); /* Initialise registers */ if ((info->delay & 0xffff) > 0) -- cgit v1.2.3 From 23c239be223d7427da51656d6f196bde965d9796 Mon Sep 17 00:00:00 2001 From: Vasily Khoruzhick Date: Sat, 20 Feb 2010 01:06:20 -0800 Subject: Input: s3c24xx_ts - report touch only when stylus is down Currently driver reports touches when it gets (1 << ts.shift) samples, even if stylus is up, which is incorrect. We should only report coordinates and touch condition when stylus is down. Signed-off-by: Vasily Khoruzhick Signed-off-by: Dmitry Torokhov --- drivers/input/touchscreen/s3c2410_ts.c | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-) (limited to 'drivers/input') diff --git a/drivers/input/touchscreen/s3c2410_ts.c b/drivers/input/touchscreen/s3c2410_ts.c index ffc355e696dc..3755a47d053c 100644 --- a/drivers/input/touchscreen/s3c2410_ts.c +++ b/drivers/input/touchscreen/s3c2410_ts.c @@ -128,27 +128,29 @@ static void touch_timer_fire(unsigned long data) down = get_down(data0, data1); - if (ts.count == (1 << ts.shift)) { - ts.xp >>= ts.shift; - ts.yp >>= ts.shift; + if (down) { + if (ts.count == (1 << ts.shift)) { + ts.xp >>= ts.shift; + ts.yp >>= ts.shift; - dev_dbg(ts.dev, "%s: X=%lu, Y=%lu, count=%d\n", - __func__, ts.xp, ts.yp, ts.count); + dev_dbg(ts.dev, "%s: X=%lu, Y=%lu, count=%d\n", + __func__, ts.xp, ts.yp, ts.count); - input_report_abs(ts.input, ABS_X, ts.xp); - input_report_abs(ts.input, ABS_Y, ts.yp); + input_report_abs(ts.input, ABS_X, ts.xp); + input_report_abs(ts.input, ABS_Y, ts.yp); - input_report_key(ts.input, BTN_TOUCH, 1); - input_sync(ts.input); + input_report_key(ts.input, BTN_TOUCH, 1); + input_sync(ts.input); - ts.xp = 0; - ts.yp = 0; - ts.count = 0; - } + ts.xp = 0; + ts.yp = 0; + ts.count = 0; + } - if (down) { s3c_adc_start(ts.client, 0, 1 << ts.shift); } else { + ts.xp = 0; + ts.yp = 0; ts.count = 0; input_report_key(ts.input, BTN_TOUCH, 0); -- cgit v1.2.3 From 49b764aebde6ceea393f56cd3449bfa5720f8383 Mon Sep 17 00:00:00 2001 From: Ping Cheng Date: Sat, 20 Feb 2010 00:53:49 -0800 Subject: Input: wacom - add device type to device name string Devices supporting both pen and touch features share the same product ID, but presented as 2 separate input devices. By adding device type to device name string we can help userspace applications and users differentiate between them. 'Finger' is used for the touch since touch has been used as a suffix by userland hotplugging services. Signed-off-by: Jason Childs Signed-off-by: Ping Cheng Signed-off-by: Dmitry Torokhov --- drivers/input/tablet/wacom_sys.c | 12 +++++++++++- drivers/input/tablet/wacom_wac.h | 7 ++++--- 2 files changed, 15 insertions(+), 4 deletions(-) (limited to 'drivers/input') diff --git a/drivers/input/tablet/wacom_sys.c b/drivers/input/tablet/wacom_sys.c index f22b88d03c6c..a1770e6feeec 100644 --- a/drivers/input/tablet/wacom_sys.c +++ b/drivers/input/tablet/wacom_sys.c @@ -592,7 +592,17 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i if (error) goto fail2; - input_dev->name = features->name; + strlcpy(wacom_wac->name, features->name, sizeof(wacom_wac->name)); + + if (features->type == TABLETPC || features->type == TABLETPC2FG) { + /* Append the device type to the name */ + strlcat(wacom_wac->name, + features->device_type == BTN_TOOL_PEN ? + " Pen" : " Finger", + sizeof(wacom_wac->name)); + } + + input_dev->name = wacom_wac->name; wacom->wacom_wac = wacom_wac; input_dev->evbit[0] |= BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); diff --git a/drivers/input/tablet/wacom_wac.h b/drivers/input/tablet/wacom_wac.h index 3f4b89d51fe2..8590b1e8ec37 100644 --- a/drivers/input/tablet/wacom_wac.h +++ b/drivers/input/tablet/wacom_wac.h @@ -73,10 +73,11 @@ struct wacom_features { }; struct wacom_wac { + char name[64]; unsigned char *data; - int tool[2]; - int id[2]; - __u32 serial[2]; + int tool[2]; + int id[2]; + __u32 serial[2]; struct wacom_features features; }; -- cgit v1.2.3 From 7aa9e0e8263259f4517ba1788f4fbaa88e878400 Mon Sep 17 00:00:00 2001 From: Scott Moreau Date: Sun, 21 Feb 2010 20:53:55 -0800 Subject: Input: gamecon - add rumble support for N64 pads Add force-feedback support for N64 pads with rumble pak accessory installed. Actually we do not check for the presence of rumble pad but simply assume it is installed and expect the device to ignore FF commands if rumble pak is missing. Signed-off-by: Scott Moreau Signed-off-by: Dmitry Torokhov --- drivers/input/joystick/Kconfig | 1 + drivers/input/joystick/gamecon.c | 125 +++++++++++++++++++++++++++++++++++++-- 2 files changed, 120 insertions(+), 6 deletions(-) (limited to 'drivers/input') diff --git a/drivers/input/joystick/Kconfig b/drivers/input/joystick/Kconfig index b11419590cfe..5b596165b571 100644 --- a/drivers/input/joystick/Kconfig +++ b/drivers/input/joystick/Kconfig @@ -221,6 +221,7 @@ config JOYSTICK_DB9 config JOYSTICK_GAMECON tristate "Multisystem, NES, SNES, N64, PSX joysticks and gamepads" depends on PARPORT + select INPUT_FF_MEMLESS ---help--- Say Y here if you have a Nintendo Entertainment System gamepad, Super Nintendo Entertainment System gamepad, Nintendo 64 gamepad, diff --git a/drivers/input/joystick/gamecon.c b/drivers/input/joystick/gamecon.c index 07a32aff5a31..bbde4e524da3 100644 --- a/drivers/input/joystick/gamecon.c +++ b/drivers/input/joystick/gamecon.c @@ -85,6 +85,10 @@ struct gc { char phys[GC_MAX_DEVICES][32]; }; +struct gc_subdev { + unsigned int idx; +}; + static struct gc *gc_base[3]; static int gc_status_bit[] = { 0x40, 0x80, 0x20, 0x10, 0x08 }; @@ -100,9 +104,16 @@ static unsigned char gc_n64_bytes[] = { 0, 1, 13, 15, 14, 12, 10, 11, 2, 3 }; static short gc_n64_btn[] = { BTN_A, BTN_B, BTN_C, BTN_X, BTN_Y, BTN_Z, BTN_TL, BTN_TR, BTN_TRIGGER, BTN_START }; #define GC_N64_LENGTH 32 /* N64 bit length, not including stop bit */ -#define GC_N64_REQUEST_LENGTH 37 /* transmit request sequence is 9 bits long */ +#define GC_N64_STOP_LENGTH 5 /* Length of encoded stop bit */ +#define GC_N64_CMD_00 0x11111111UL +#define GC_N64_CMD_01 0xd1111111UL +#define GC_N64_CMD_03 0xdd111111UL +#define GC_N64_CMD_1b 0xdd1dd111UL +#define GC_N64_CMD_c0 0x111111ddUL +#define GC_N64_CMD_80 0x1111111dUL +#define GC_N64_STOP_BIT 0x1d /* Encoded stop bit */ +#define GC_N64_REQUEST_DATA GC_N64_CMD_01 /* the request data command */ #define GC_N64_DELAY 133 /* delay between transmit request, and response ready (us) */ -#define GC_N64_REQUEST 0x1dd1111111ULL /* the request data command (encoded for 000000011) */ #define GC_N64_DWS 3 /* delay between write segments (required for sound playback because of ISA DMA) */ /* GC_N64_DWS > 24 is known to fail */ #define GC_N64_POWER_W 0xe2 /* power during write (transmit request) */ @@ -113,6 +124,37 @@ static short gc_n64_btn[] = { BTN_A, BTN_B, BTN_C, BTN_X, BTN_Y, BTN_Z, BTN_TL, /* than 123 us */ #define GC_N64_CLOCK 0x02 /* clock bits for read */ +/* + * Used for rumble code. + */ + +/* Send encoded command */ +static void gc_n64_send_command(struct gc *gc, unsigned long cmd, + unsigned char target) +{ + struct parport *port = gc->pd->port; + int i; + + for (i = 0; i < GC_N64_LENGTH; i++) { + unsigned char data = (cmd >> i) & 1 ? target : 0; + parport_write_data(port, GC_N64_POWER_W | data); + udelay(GC_N64_DWS); + } +} + +/* Send stop bit */ +static void gc_n64_send_stop_bit(struct gc *gc, unsigned char target) +{ + struct parport *port = gc->pd->port; + int i; + + for (i = 0; i < GC_N64_STOP_LENGTH; i++) { + unsigned char data = (GC_N64_STOP_BIT >> i) & 1 ? target : 0; + parport_write_data(port, GC_N64_POWER_W | data); + udelay(GC_N64_DWS); + } +} + /* * gc_n64_read_packet() reads an N64 packet. * Each pad uses one bit per byte. So all pads connected to this port are read in parallel. @@ -128,10 +170,8 @@ static void gc_n64_read_packet(struct gc *gc, unsigned char *data) */ local_irq_save(flags); - for (i = 0; i < GC_N64_REQUEST_LENGTH; i++) { - parport_write_data(gc->pd->port, GC_N64_POWER_W | ((GC_N64_REQUEST >> i) & 1 ? GC_N64_OUT : 0)); - udelay(GC_N64_DWS); - } + gc_n64_send_command(gc, GC_N64_REQUEST_DATA, GC_N64_OUT); + gc_n64_send_stop_bit(gc, GC_N64_OUT); local_irq_restore(flags); /* @@ -146,6 +186,7 @@ static void gc_n64_read_packet(struct gc *gc, unsigned char *data) for (i = 0; i < GC_N64_LENGTH; i++) { parport_write_data(gc->pd->port, GC_N64_POWER_R); + udelay(2); data[i] = parport_read_status(gc->pd->port); parport_write_data(gc->pd->port, GC_N64_POWER_R | GC_N64_CLOCK); } @@ -199,6 +240,70 @@ static void gc_n64_process_packet(struct gc *gc) } } +static int gc_n64_play_effect(struct input_dev *dev, void *data, + struct ff_effect *effect) +{ + int i; + unsigned long flags; + struct gc *gc = input_get_drvdata(dev); + struct gc_subdev *sdev = data; + unsigned char target = 1 << sdev->idx; /* select desired pin */ + + if (effect->type == FF_RUMBLE) { + struct ff_rumble_effect *rumble = &effect->u.rumble; + unsigned int cmd = + rumble->strong_magnitude || rumble->weak_magnitude ? + GC_N64_CMD_01 : GC_N64_CMD_00; + + local_irq_save(flags); + + /* Init Rumble - 0x03, 0x80, 0x01, (34)0x80 */ + gc_n64_send_command(gc, GC_N64_CMD_03, target); + gc_n64_send_command(gc, GC_N64_CMD_80, target); + gc_n64_send_command(gc, GC_N64_CMD_01, target); + for (i = 0; i < 32; i++) + gc_n64_send_command(gc, GC_N64_CMD_80, target); + gc_n64_send_stop_bit(gc, target); + + udelay(GC_N64_DELAY); + + /* Now start or stop it - 0x03, 0xc0, 0zx1b, (32)0x01/0x00 */ + gc_n64_send_command(gc, GC_N64_CMD_03, target); + gc_n64_send_command(gc, GC_N64_CMD_c0, target); + gc_n64_send_command(gc, GC_N64_CMD_1b, target); + for (i = 0; i < 32; i++) + gc_n64_send_command(gc, cmd, target); + gc_n64_send_stop_bit(gc, target); + + local_irq_restore(flags); + + } + + return 0; +} + +static int __init gc_n64_init_ff(struct input_dev *dev, int i) +{ + struct gc_subdev *sdev; + int err; + + sdev = kmalloc(sizeof(*sdev), GFP_KERNEL); + if (!sdev) + return -ENOMEM; + + sdev->idx = i; + + input_set_capability(dev, EV_FF, FF_RUMBLE); + + err = input_ff_create_memless(dev, sdev, gc_n64_play_effect); + if (err) { + kfree(sdev); + return err; + } + + return 0; +} + /* * NES/SNES support. */ @@ -624,6 +729,7 @@ static int __init gc_setup_pad(struct gc *gc, int idx, int pad_type) { struct input_dev *input_dev; int i; + int err; if (!pad_type) return 0; @@ -673,6 +779,13 @@ static int __init gc_setup_pad(struct gc *gc, int idx, int pad_type) input_set_abs_params(input_dev, ABS_HAT0X + i, -1, 1, 0, 0); } + err = gc_n64_init_ff(input_dev, idx); + if (err) { + printk(KERN_WARNING "gamecon.c: Failed to initiate rumble for N64 device %d\n", idx); + input_free_device(input_dev); + return err; + } + break; case GC_SNESMOUSE: -- cgit v1.2.3 From d38fcb9690532e6e2e064d711262b14d638113b9 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Sun, 21 Feb 2010 20:54:28 -0800 Subject: Input: gamecon - fix some formatting issues Fix formatting of 'switch' statements and change the code to stay closer to 80 column limit where it does not hurt code readability. Tested-by: Scott Moreau Signed-off-by: Dmitry Torokhov --- drivers/input/joystick/gamecon.c | 347 ++++++++++++++++++++++----------------- 1 file changed, 194 insertions(+), 153 deletions(-) (limited to 'drivers/input') diff --git a/drivers/input/joystick/gamecon.c b/drivers/input/joystick/gamecon.c index bbde4e524da3..ec01bea8dc81 100644 --- a/drivers/input/joystick/gamecon.c +++ b/drivers/input/joystick/gamecon.c @@ -93,15 +93,21 @@ static struct gc *gc_base[3]; static int gc_status_bit[] = { 0x40, 0x80, 0x20, 0x10, 0x08 }; -static char *gc_names[] = { NULL, "SNES pad", "NES pad", "NES FourPort", "Multisystem joystick", - "Multisystem 2-button joystick", "N64 controller", "PSX controller", - "PSX DDR controller", "SNES mouse" }; +static char *gc_names[] = { + NULL, "SNES pad", "NES pad", "NES FourPort", "Multisystem joystick", + "Multisystem 2-button joystick", "N64 controller", "PSX controller", + "PSX DDR controller", "SNES mouse" +}; + /* * N64 support. */ static unsigned char gc_n64_bytes[] = { 0, 1, 13, 15, 14, 12, 10, 11, 2, 3 }; -static short gc_n64_btn[] = { BTN_A, BTN_B, BTN_C, BTN_X, BTN_Y, BTN_Z, BTN_TL, BTN_TR, BTN_TRIGGER, BTN_START }; +static short gc_n64_btn[] = { + BTN_A, BTN_B, BTN_C, BTN_X, BTN_Y, BTN_Z, + BTN_TL, BTN_TR, BTN_TRIGGER, BTN_START +}; #define GC_N64_LENGTH 32 /* N64 bit length, not including stop bit */ #define GC_N64_STOP_LENGTH 5 /* Length of encoded stop bit */ @@ -157,7 +163,8 @@ static void gc_n64_send_stop_bit(struct gc *gc, unsigned char target) /* * gc_n64_read_packet() reads an N64 packet. - * Each pad uses one bit per byte. So all pads connected to this port are read in parallel. + * Each pad uses one bit per byte. So all pads connected to this port + * are read in parallel. */ static void gc_n64_read_packet(struct gc *gc, unsigned char *data) @@ -175,7 +182,8 @@ static void gc_n64_read_packet(struct gc *gc, unsigned char *data) local_irq_restore(flags); /* - * Wait for the pad response to be loaded into the 33-bit register of the adapter + * Wait for the pad response to be loaded into the 33-bit register + * of the adapter. */ udelay(GC_N64_DELAY); @@ -192,8 +200,9 @@ static void gc_n64_read_packet(struct gc *gc, unsigned char *data) } /* - * We must wait 200 ms here for the controller to reinitialize before the next read request. - * No worries as long as gc_read is polled less frequently than this. + * We must wait 200 ms here for the controller to reinitialize before + * the next read request. No worries as long as gc_read is polled less + * frequently than this. */ } @@ -201,9 +210,9 @@ static void gc_n64_read_packet(struct gc *gc, unsigned char *data) static void gc_n64_process_packet(struct gc *gc) { unsigned char data[GC_N64_LENGTH]; - signed char axes[2]; struct input_dev *dev; int i, j, s; + signed char x, y; gc_n64_read_packet(gc, data); @@ -217,23 +226,26 @@ static void gc_n64_process_packet(struct gc *gc) if (s & gc->pads[GC_N64] & ~(data[8] | data[9])) { - axes[0] = axes[1] = 0; + x = y = 0; for (j = 0; j < 8; j++) { if (data[23 - j] & s) - axes[0] |= 1 << j; + x |= 1 << j; if (data[31 - j] & s) - axes[1] |= 1 << j; + y |= 1 << j; } - input_report_abs(dev, ABS_X, axes[0]); - input_report_abs(dev, ABS_Y, -axes[1]); + input_report_abs(dev, ABS_X, x); + input_report_abs(dev, ABS_Y, -y); - input_report_abs(dev, ABS_HAT0X, !(s & data[6]) - !(s & data[7])); - input_report_abs(dev, ABS_HAT0Y, !(s & data[4]) - !(s & data[5])); + input_report_abs(dev, ABS_HAT0X, + !(s & data[6]) - !(s & data[7])); + input_report_abs(dev, ABS_HAT0Y, + !(s & data[4]) - !(s & data[5])); for (j = 0; j < 10; j++) - input_report_key(dev, gc_n64_btn[j], s & data[gc_n64_bytes[j]]); + input_report_key(dev, gc_n64_btn[j], + s & data[gc_n64_bytes[j]]); input_sync(dev); } @@ -321,7 +333,9 @@ static int __init gc_n64_init_ff(struct input_dev *dev, int i) static unsigned char gc_nes_bytes[] = { 0, 1, 2, 3 }; static unsigned char gc_snes_bytes[] = { 8, 0, 2, 3, 9, 1, 10, 11 }; -static short gc_snes_btn[] = { BTN_A, BTN_B, BTN_SELECT, BTN_START, BTN_X, BTN_Y, BTN_TL, BTN_TR }; +static short gc_snes_btn[] = { + BTN_A, BTN_B, BTN_SELECT, BTN_START, BTN_X, BTN_Y, BTN_TL, BTN_TR +}; /* * gc_nes_read_packet() reads a NES/SNES packet. @@ -373,16 +387,19 @@ static void gc_nes_process_packet(struct gc *gc) if (s & gc->pads[GC_NES]) for (j = 0; j < 4; j++) - input_report_key(dev, gc_snes_btn[j], s & data[gc_nes_bytes[j]]); + input_report_key(dev, gc_snes_btn[j], + s & data[gc_nes_bytes[j]]); if (s & gc->pads[GC_SNES]) for (j = 0; j < 8; j++) - input_report_key(dev, gc_snes_btn[j], s & data[gc_snes_bytes[j]]); + input_report_key(dev, gc_snes_btn[j], + s & data[gc_snes_bytes[j]]); if (s & gc->pads[GC_SNESMOUSE]) { /* - * The 4 unused bits from SNES controllers appear to be ID bits - * so use them to make sure iwe are dealing with a mouse. + * The 4 unused bits from SNES controllers appear + * to be ID bits so use them to make sure we are + * dealing with a mouse. * gamepad is connected. This is important since * my SNES gamepad sends 1's for bits 16-31, which * cause the mouse pointer to quickly move to the @@ -445,10 +462,11 @@ static void gc_multi_read_packet(struct gc *gc, int length, unsigned char *data) static void gc_multi_process_packet(struct gc *gc) { unsigned char data[GC_MULTI2_LENGTH]; + int data_len = gc->pads[GC_MULTI2] ? GC_MULTI2_LENGTH : GC_MULTI_LENGTH; struct input_dev *dev; int i, s; - gc_multi_read_packet(gc, gc->pads[GC_MULTI2] ? GC_MULTI2_LENGTH : GC_MULTI_LENGTH, data); + gc_multi_read_packet(gc, data_len, data); for (i = 0; i < GC_MAX_DEVICES; i++) { @@ -459,8 +477,10 @@ static void gc_multi_process_packet(struct gc *gc) s = gc_status_bit[i]; if (s & (gc->pads[GC_MULTI] | gc->pads[GC_MULTI2])) { - input_report_abs(dev, ABS_X, !(s & data[2]) - !(s & data[3])); - input_report_abs(dev, ABS_Y, !(s & data[0]) - !(s & data[1])); + input_report_abs(dev, ABS_X, + !(s & data[2]) - !(s & data[3])); + input_report_abs(dev, ABS_Y, + !(s & data[0]) - !(s & data[1])); input_report_key(dev, BTN_TRIGGER, s & data[4]); } @@ -503,9 +523,13 @@ static int gc_psx_delay = GC_PSX_DELAY; module_param_named(psx_delay, gc_psx_delay, uint, 0); MODULE_PARM_DESC(psx_delay, "Delay when accessing Sony PSX controller (usecs)"); -static short gc_psx_abs[] = { ABS_X, ABS_Y, ABS_RX, ABS_RY, ABS_HAT0X, ABS_HAT0Y }; -static short gc_psx_btn[] = { BTN_TL, BTN_TR, BTN_TL2, BTN_TR2, BTN_A, BTN_B, BTN_X, BTN_Y, - BTN_START, BTN_SELECT, BTN_THUMBL, BTN_THUMBR }; +static short gc_psx_abs[] = { + ABS_X, ABS_Y, ABS_RX, ABS_RY, ABS_HAT0X, ABS_HAT0Y +}; +static short gc_psx_btn[] = { + BTN_TL, BTN_TR, BTN_TL2, BTN_TR2, BTN_A, BTN_B, BTN_X, BTN_Y, + BTN_START, BTN_SELECT, BTN_THUMBL, BTN_THUMBR +}; static short gc_psx_ddr_btn[] = { BTN_0, BTN_1, BTN_2, BTN_3 }; /* @@ -513,18 +537,18 @@ static short gc_psx_ddr_btn[] = { BTN_0, BTN_1, BTN_2, BTN_3 }; * the psx pad. */ -static void gc_psx_command(struct gc *gc, int b, unsigned char data[GC_MAX_DEVICES]) +static void gc_psx_command(struct gc *gc, int b, unsigned char *data) { + struct parport *port = gc->pd->port; int i, j, cmd, read; - for (i = 0; i < GC_MAX_DEVICES; i++) - data[i] = 0; + memset(data, 0, GC_MAX_DEVICES); for (i = 0; i < GC_PSX_LENGTH; i++, b >>= 1) { cmd = (b & 1) ? GC_PSX_COMMAND : 0; - parport_write_data(gc->pd->port, cmd | GC_PSX_POWER); + parport_write_data(port, cmd | GC_PSX_POWER); udelay(gc_psx_delay); - read = parport_read_status(gc->pd->port) ^ 0x80; + read = parport_read_status(port) ^ 0x80; for (j = 0; j < GC_MAX_DEVICES; j++) data[j] |= (read & gc_status_bit[j] & (gc->pads[GC_PSX] | gc->pads[GC_DDR])) ? (1 << i) : 0; parport_write_data(gc->pd->port, cmd | GC_PSX_CLOCK | GC_PSX_POWER); @@ -544,24 +568,29 @@ static void gc_psx_read_packet(struct gc *gc, unsigned char data[GC_MAX_DEVICES] unsigned long flags; unsigned char data2[GC_MAX_DEVICES]; - parport_write_data(gc->pd->port, GC_PSX_CLOCK | GC_PSX_SELECT | GC_PSX_POWER); /* Select pad */ + /* Select pad */ + parport_write_data(gc->pd->port, GC_PSX_CLOCK | GC_PSX_SELECT | GC_PSX_POWER); udelay(gc_psx_delay); - parport_write_data(gc->pd->port, GC_PSX_CLOCK | GC_PSX_POWER); /* Deselect, begin command */ + /* Deselect, begin command */ + parport_write_data(gc->pd->port, GC_PSX_CLOCK | GC_PSX_POWER); udelay(gc_psx_delay); local_irq_save(flags); - gc_psx_command(gc, 0x01, data2); /* Access pad */ - gc_psx_command(gc, 0x42, id); /* Get device ids */ - gc_psx_command(gc, 0, data2); /* Dump status */ + gc_psx_command(gc, 0x01, data2); /* Access pad */ + gc_psx_command(gc, 0x42, id); /* Get device ids */ + gc_psx_command(gc, 0, data2); /* Dump status */ - for (i =0; i < GC_MAX_DEVICES; i++) /* Find the longest pad */ - if((gc_status_bit[i] & (gc->pads[GC_PSX] | gc->pads[GC_DDR])) - && (GC_PSX_LEN(id[i]) > max_len) - && (GC_PSX_LEN(id[i]) <= GC_PSX_BYTES)) + /* Find the longest pad */ + for (i = 0; i < GC_MAX_DEVICES; i++) + if ((gc_status_bit[i] & (gc->pads[GC_PSX] | gc->pads[GC_DDR])) && + GC_PSX_LEN(id[i]) > max_len && + GC_PSX_LEN(id[i]) <= GC_PSX_BYTES) { max_len = GC_PSX_LEN(id[i]); + } - for (i = 0; i < max_len; i++) { /* Read in all the data */ + /* Read in all the data */ + for (i = 0; i < max_len; i++) { gc_psx_command(gc, 0, data2); for (j = 0; j < GC_MAX_DEVICES; j++) data[j][i] = data2[j]; @@ -571,86 +600,99 @@ static void gc_psx_read_packet(struct gc *gc, unsigned char data[GC_MAX_DEVICES] parport_write_data(gc->pd->port, GC_PSX_CLOCK | GC_PSX_SELECT | GC_PSX_POWER); - for(i = 0; i < GC_MAX_DEVICES; i++) /* Set id's to the real value */ + /* Set id's to the real value */ + for (i = 0; i < GC_MAX_DEVICES; i++) id[i] = GC_PSX_ID(id[i]); } -static void gc_psx_process_packet(struct gc *gc) +static void gc_psx_report_one(struct gc *gc, struct input_dev *dev, + unsigned char pad_type, unsigned char status_bit, + unsigned char *data) { - unsigned char data[GC_MAX_DEVICES][GC_PSX_BYTES]; - unsigned char id[GC_MAX_DEVICES]; - struct input_dev *dev; - int i, j; + int i; - gc_psx_read_packet(gc, data, id); + switch (pad_type) { - for (i = 0; i < GC_MAX_DEVICES; i++) { + case GC_PSX_RUMBLE: - dev = gc->dev[i]; - if (!dev) - continue; + input_report_key(dev, BTN_THUMBL, ~data[0] & 0x04); + input_report_key(dev, BTN_THUMBR, ~data[0] & 0x02); - switch (id[i]) { + case GC_PSX_NEGCON: + case GC_PSX_ANALOG: - case GC_PSX_RUMBLE: + if (gc->pads[GC_DDR] & status_bit) { + for (i = 0; i < 4; i++) + input_report_key(dev, gc_psx_ddr_btn[i], + ~data[0] & (0x10 << i)); + } else { + for (i = 0; i < 4; i++) + input_report_abs(dev, gc_psx_abs[i + 2], + data[i + 2]); - input_report_key(dev, BTN_THUMBL, ~data[i][0] & 0x04); - input_report_key(dev, BTN_THUMBR, ~data[i][0] & 0x02); + input_report_abs(dev, ABS_X, 128 + !(data[0] & 0x20) * 127 - !(data[0] & 0x80) * 128); + input_report_abs(dev, ABS_Y, 128 + !(data[0] & 0x40) * 127 - !(data[0] & 0x10) * 128); + } - case GC_PSX_NEGCON: - case GC_PSX_ANALOG: + for (i = 0; i < 8; i++) + input_report_key(dev, gc_psx_btn[i], ~data[1] & (1 << i)); - if (gc->pads[GC_DDR] & gc_status_bit[i]) { - for(j = 0; j < 4; j++) - input_report_key(dev, gc_psx_ddr_btn[j], ~data[i][0] & (0x10 << j)); - } else { - for (j = 0; j < 4; j++) - input_report_abs(dev, gc_psx_abs[j + 2], data[i][j + 2]); + input_report_key(dev, BTN_START, ~data[0] & 0x08); + input_report_key(dev, BTN_SELECT, ~data[0] & 0x01); - input_report_abs(dev, ABS_X, 128 + !(data[i][0] & 0x20) * 127 - !(data[i][0] & 0x80) * 128); - input_report_abs(dev, ABS_Y, 128 + !(data[i][0] & 0x40) * 127 - !(data[i][0] & 0x10) * 128); - } + input_sync(dev); - for (j = 0; j < 8; j++) - input_report_key(dev, gc_psx_btn[j], ~data[i][1] & (1 << j)); + break; - input_report_key(dev, BTN_START, ~data[i][0] & 0x08); - input_report_key(dev, BTN_SELECT, ~data[i][0] & 0x01); + case GC_PSX_NORMAL: + if (gc->pads[GC_DDR] & status_bit) { + for (i = 0; i < 4; i++) + input_report_key(dev, gc_psx_ddr_btn[i], + ~data[0] & (0x10 << i)); + } else { + input_report_abs(dev, ABS_X, 128 + !(data[0] & 0x20) * 127 - !(data[0] & 0x80) * 128); + input_report_abs(dev, ABS_Y, 128 + !(data[0] & 0x40) * 127 - !(data[0] & 0x10) * 128); - input_sync(dev); + /* + * For some reason if the extra axes are left unset + * they drift. + * for (i = 0; i < 4; i++) + input_report_abs(dev, gc_psx_abs[i + 2], 128); + * This needs to be debugged properly, + * maybe fuzz processing needs to be done + * in input_sync() + * --vojtech + */ + } - break; + for (i = 0; i < 8; i++) + input_report_key(dev, gc_psx_btn[i], ~data[1] & (1 << i)); - case GC_PSX_NORMAL: - if (gc->pads[GC_DDR] & gc_status_bit[i]) { - for(j = 0; j < 4; j++) - input_report_key(dev, gc_psx_ddr_btn[j], ~data[i][0] & (0x10 << j)); - } else { - input_report_abs(dev, ABS_X, 128 + !(data[i][0] & 0x20) * 127 - !(data[i][0] & 0x80) * 128); - input_report_abs(dev, ABS_Y, 128 + !(data[i][0] & 0x40) * 127 - !(data[i][0] & 0x10) * 128); + input_report_key(dev, BTN_START, ~data[0] & 0x08); + input_report_key(dev, BTN_SELECT, ~data[0] & 0x01); - /* for some reason if the extra axes are left unset they drift */ - /* for (j = 0; j < 4; j++) - input_report_abs(dev, gc_psx_abs[j + 2], 128); - * This needs to be debugged properly, - * maybe fuzz processing needs to be done in input_sync() - * --vojtech - */ - } + input_sync(dev); + + break; - for (j = 0; j < 8; j++) - input_report_key(dev, gc_psx_btn[j], ~data[i][1] & (1 << j)); + case 0: /* not a pad, ignore */ + break; + } +} - input_report_key(dev, BTN_START, ~data[i][0] & 0x08); - input_report_key(dev, BTN_SELECT, ~data[i][0] & 0x01); +static void gc_psx_process_packet(struct gc *gc) +{ + unsigned char data[GC_MAX_DEVICES][GC_PSX_BYTES]; + unsigned char id[GC_MAX_DEVICES]; + int i; - input_sync(dev); + gc_psx_read_packet(gc, data, id); - break; + for (i = 0; i < GC_MAX_DEVICES; i++) { - case 0: /* not a pad, ignore */ - break; - } + if (gc->dev[i]) + gc_psx_report_one(gc, gc->dev[i], + id[i], gc_status_bit[i], data[i]); } } @@ -770,60 +812,61 @@ static int __init gc_setup_pad(struct gc *gc, int idx, int pad_type) switch (pad_type) { - case GC_N64: - for (i = 0; i < 10; i++) - set_bit(gc_n64_btn[i], input_dev->keybit); - - for (i = 0; i < 2; i++) { - input_set_abs_params(input_dev, ABS_X + i, -127, 126, 0, 2); - input_set_abs_params(input_dev, ABS_HAT0X + i, -1, 1, 0, 0); - } - - err = gc_n64_init_ff(input_dev, idx); - if (err) { - printk(KERN_WARNING "gamecon.c: Failed to initiate rumble for N64 device %d\n", idx); - input_free_device(input_dev); - return err; - } - - break; - - case GC_SNESMOUSE: - set_bit(BTN_LEFT, input_dev->keybit); - set_bit(BTN_RIGHT, input_dev->keybit); - set_bit(REL_X, input_dev->relbit); - set_bit(REL_Y, input_dev->relbit); - break; - - case GC_SNES: - for (i = 4; i < 8; i++) - set_bit(gc_snes_btn[i], input_dev->keybit); - case GC_NES: - for (i = 0; i < 4; i++) - set_bit(gc_snes_btn[i], input_dev->keybit); - break; + case GC_N64: + for (i = 0; i < 10; i++) + __set_bit(gc_n64_btn[i], input_dev->keybit); - case GC_MULTI2: - set_bit(BTN_THUMB, input_dev->keybit); - case GC_MULTI: - set_bit(BTN_TRIGGER, input_dev->keybit); - break; - - case GC_PSX: - for (i = 0; i < 6; i++) - input_set_abs_params(input_dev, gc_psx_abs[i], 4, 252, 0, 2); - for (i = 0; i < 12; i++) - set_bit(gc_psx_btn[i], input_dev->keybit); - - break; + for (i = 0; i < 2; i++) { + input_set_abs_params(input_dev, ABS_X + i, -127, 126, 0, 2); + input_set_abs_params(input_dev, ABS_HAT0X + i, -1, 1, 0, 0); + } - case GC_DDR: - for (i = 0; i < 4; i++) - set_bit(gc_psx_ddr_btn[i], input_dev->keybit); - for (i = 0; i < 12; i++) - set_bit(gc_psx_btn[i], input_dev->keybit); + err = gc_n64_init_ff(input_dev, idx); + if (err) { + printk(KERN_WARNING "gamecon.c: Failed to initiate rumble for N64 device %d\n", idx); + input_free_device(input_dev); + return err; + } - break; + break; + + case GC_SNESMOUSE: + __set_bit(BTN_LEFT, input_dev->keybit); + __set_bit(BTN_RIGHT, input_dev->keybit); + __set_bit(REL_X, input_dev->relbit); + __set_bit(REL_Y, input_dev->relbit); + break; + + case GC_SNES: + for (i = 4; i < 8; i++) + __set_bit(gc_snes_btn[i], input_dev->keybit); + case GC_NES: + for (i = 0; i < 4; i++) + __set_bit(gc_snes_btn[i], input_dev->keybit); + break; + + case GC_MULTI2: + __set_bit(BTN_THUMB, input_dev->keybit); + case GC_MULTI: + __set_bit(BTN_TRIGGER, input_dev->keybit); + break; + + case GC_PSX: + for (i = 0; i < 6; i++) + input_set_abs_params(input_dev, + gc_psx_abs[i], 4, 252, 0, 2); + for (i = 0; i < 12; i++) + __set_bit(gc_psx_btn[i], input_dev->keybit); + + break; + + case GC_DDR: + for (i = 0; i < 4; i++) + __set_bit(gc_psx_ddr_btn[i], input_dev->keybit); + for (i = 0; i < 12; i++) + __set_bit(gc_psx_btn[i], input_dev->keybit); + + break; } return 0; @@ -860,9 +903,7 @@ static struct gc __init *gc_probe(int parport, int *pads, int n_pads) mutex_init(&gc->mutex); gc->pd = pd; - init_timer(&gc->timer); - gc->timer.data = (long) gc; - gc->timer.function = gc_timer; + setup_timer(&gc->timer, gc_timer, (long) gc); for (i = 0; i < n_pads && i < GC_MAX_DEVICES; i++) { if (!pads[i]) -- cgit v1.2.3 From 315543fd112ae3b573bc44e7dbfef99c11714610 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Sun, 21 Feb 2010 20:54:31 -0800 Subject: Input: gamecon - simplify coordinate calculation for PSX Signed-off-by: Dmitry Torokhov --- drivers/input/joystick/gamecon.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'drivers/input') diff --git a/drivers/input/joystick/gamecon.c b/drivers/input/joystick/gamecon.c index ec01bea8dc81..d57edd4a5992 100644 --- a/drivers/input/joystick/gamecon.c +++ b/drivers/input/joystick/gamecon.c @@ -630,8 +630,10 @@ static void gc_psx_report_one(struct gc *gc, struct input_dev *dev, input_report_abs(dev, gc_psx_abs[i + 2], data[i + 2]); - input_report_abs(dev, ABS_X, 128 + !(data[0] & 0x20) * 127 - !(data[0] & 0x80) * 128); - input_report_abs(dev, ABS_Y, 128 + !(data[0] & 0x40) * 127 - !(data[0] & 0x10) * 128); + input_report_abs(dev, ABS_X, + !!(data[0] & 0x80) * 128 + !(data[0] & 0x20) * 127); + input_report_abs(dev, ABS_Y, + !!(data[0] & 0x10) * 128 + !(data[0] & 0x40) * 127); } for (i = 0; i < 8; i++) @@ -650,8 +652,10 @@ static void gc_psx_report_one(struct gc *gc, struct input_dev *dev, input_report_key(dev, gc_psx_ddr_btn[i], ~data[0] & (0x10 << i)); } else { - input_report_abs(dev, ABS_X, 128 + !(data[0] & 0x20) * 127 - !(data[0] & 0x80) * 128); - input_report_abs(dev, ABS_Y, 128 + !(data[0] & 0x40) * 127 - !(data[0] & 0x10) * 128); + input_report_abs(dev, ABS_X, + !!(data[0] & 0x80) * 128 + !(data[0] & 0x20) * 127); + input_report_abs(dev, ABS_Y, + !!(data[0] & 0x10) * 128 + !(data[0] & 0x40) * 127); /* * For some reason if the extra axes are left unset -- cgit v1.2.3 From 0995174dda3e97d70fd9c335c55041b6b5aa11dd Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Sun, 21 Feb 2010 20:54:54 -0800 Subject: Input: gamecon - simplify pad type handling Instead of having array bitmasks by type for all gamepads have explicit type field in every pad structure. Tested-by: Scott Moreau Signed-off-by: Dmitry Torokhov --- drivers/input/joystick/gamecon.c | 202 ++++++++++++++++++++++++--------------- 1 file changed, 123 insertions(+), 79 deletions(-) (limited to 'drivers/input') diff --git a/drivers/input/joystick/gamecon.c b/drivers/input/joystick/gamecon.c index d57edd4a5992..e9c6647e1f74 100644 --- a/drivers/input/joystick/gamecon.c +++ b/drivers/input/joystick/gamecon.c @@ -61,28 +61,36 @@ MODULE_PARM_DESC(map3, "Describes third set of devices"); /* see also gs_psx_delay parameter in PSX support section */ -#define GC_SNES 1 -#define GC_NES 2 -#define GC_NES4 3 -#define GC_MULTI 4 -#define GC_MULTI2 5 -#define GC_N64 6 -#define GC_PSX 7 -#define GC_DDR 8 -#define GC_SNESMOUSE 9 - -#define GC_MAX 9 +enum gc_type { + GC_NONE = 0, + GC_SNES, + GC_NES, + GC_NES4, + GC_MULTI, + GC_MULTI2, + GC_N64, + GC_PSX, + GC_DDR, + GC_SNESMOUSE, + GC_MAX +}; #define GC_REFRESH_TIME HZ/100 +struct gc_pad { + struct input_dev *dev; + enum gc_type type; + char phys[32]; +}; + struct gc { struct pardevice *pd; + struct gc_pad pads[GC_MAX_DEVICES]; struct input_dev *dev[GC_MAX_DEVICES]; struct timer_list timer; - unsigned char pads[GC_MAX + 1]; + int pad_count[GC_MAX]; int used; struct mutex mutex; - char phys[GC_MAX_DEVICES][32]; }; struct gc_subdev { @@ -218,13 +226,13 @@ static void gc_n64_process_packet(struct gc *gc) for (i = 0; i < GC_MAX_DEVICES; i++) { - dev = gc->dev[i]; - if (!dev) + if (gc->pads[i].type != GC_N64) continue; + dev = gc->pads[i].dev; s = gc_status_bit[i]; - if (s & gc->pads[GC_N64] & ~(data[8] | data[9])) { + if (s & ~(data[8] | data[9])) { x = y = 0; @@ -363,39 +371,47 @@ static void gc_nes_read_packet(struct gc *gc, int length, unsigned char *data) static void gc_nes_process_packet(struct gc *gc) { unsigned char data[GC_SNESMOUSE_LENGTH]; + struct gc_pad *pad; struct input_dev *dev; int i, j, s, len; char x_rel, y_rel; - len = gc->pads[GC_SNESMOUSE] ? GC_SNESMOUSE_LENGTH : - (gc->pads[GC_SNES] ? GC_SNES_LENGTH : GC_NES_LENGTH); + len = gc->pad_count[GC_SNESMOUSE] ? GC_SNESMOUSE_LENGTH : + (gc->pad_count[GC_SNES] ? GC_SNES_LENGTH : GC_NES_LENGTH); gc_nes_read_packet(gc, len, data); for (i = 0; i < GC_MAX_DEVICES; i++) { + pad = &gc->pads[i]; dev = gc->dev[i]; - if (!dev) - continue; - s = gc_status_bit[i]; - if (s & (gc->pads[GC_NES] | gc->pads[GC_SNES])) { + switch (pad->type) { + + case GC_NES: + input_report_abs(dev, ABS_X, !(s & data[6]) - !(s & data[7])); input_report_abs(dev, ABS_Y, !(s & data[4]) - !(s & data[5])); - } - if (s & gc->pads[GC_NES]) for (j = 0; j < 4; j++) input_report_key(dev, gc_snes_btn[j], s & data[gc_nes_bytes[j]]); + input_sync(dev); + break; + + case GC_SNES: + + input_report_abs(dev, ABS_X, !(s & data[6]) - !(s & data[7])); + input_report_abs(dev, ABS_Y, !(s & data[4]) - !(s & data[5])); - if (s & gc->pads[GC_SNES]) for (j = 0; j < 8; j++) input_report_key(dev, gc_snes_btn[j], s & data[gc_snes_bytes[j]]); + input_sync(dev); + break; - if (s & gc->pads[GC_SNESMOUSE]) { + case GC_SNESMOUSE: /* * The 4 unused bits from SNES controllers appear * to be ID bits so use them to make sure we are @@ -432,9 +448,14 @@ static void gc_nes_process_packet(struct gc *gc) y_rel = -y_rel; input_report_rel(dev, REL_Y, y_rel); } + + input_sync(dev); } + break; + + default: + break; } - input_sync(dev); } } @@ -462,32 +483,35 @@ static void gc_multi_read_packet(struct gc *gc, int length, unsigned char *data) static void gc_multi_process_packet(struct gc *gc) { unsigned char data[GC_MULTI2_LENGTH]; - int data_len = gc->pads[GC_MULTI2] ? GC_MULTI2_LENGTH : GC_MULTI_LENGTH; + int data_len = gc->pad_count[GC_MULTI2] ? GC_MULTI2_LENGTH : GC_MULTI_LENGTH; + struct gc_pad *pad; struct input_dev *dev; int i, s; gc_multi_read_packet(gc, data_len, data); for (i = 0; i < GC_MAX_DEVICES; i++) { - - dev = gc->dev[i]; - if (!dev) - continue; - + pad = &gc->pads[i]; + dev = pad->dev; s = gc_status_bit[i]; - if (s & (gc->pads[GC_MULTI] | gc->pads[GC_MULTI2])) { + switch (pad->type) { + case GC_MULTI2: + input_report_key(dev, BTN_THUMB, s & data[5]); + /* fall through */ + + case GC_MULTI: input_report_abs(dev, ABS_X, !(s & data[2]) - !(s & data[3])); input_report_abs(dev, ABS_Y, !(s & data[0]) - !(s & data[1])); input_report_key(dev, BTN_TRIGGER, s & data[4]); - } - - if (s & gc->pads[GC_MULTI2]) - input_report_key(dev, BTN_THUMB, s & data[5]); + input_sync(dev); + break; - input_sync(dev); + default: + break; + } } } @@ -548,9 +572,16 @@ static void gc_psx_command(struct gc *gc, int b, unsigned char *data) cmd = (b & 1) ? GC_PSX_COMMAND : 0; parport_write_data(port, cmd | GC_PSX_POWER); udelay(gc_psx_delay); + read = parport_read_status(port) ^ 0x80; - for (j = 0; j < GC_MAX_DEVICES; j++) - data[j] |= (read & gc_status_bit[j] & (gc->pads[GC_PSX] | gc->pads[GC_DDR])) ? (1 << i) : 0; + + for (j = 0; j < GC_MAX_DEVICES; j++) { + struct gc_pad *pad = &gc->pads[i]; + + if (pad->type == GC_PSX || pad->type == GC_DDR) + data[j] |= (read & gc_status_bit[j]) ? (1 << i) : 0; + } + parport_write_data(gc->pd->port, cmd | GC_PSX_CLOCK | GC_PSX_POWER); udelay(gc_psx_delay); } @@ -561,7 +592,8 @@ static void gc_psx_command(struct gc *gc, int b, unsigned char *data) * device identifier code. */ -static void gc_psx_read_packet(struct gc *gc, unsigned char data[GC_MAX_DEVICES][GC_PSX_BYTES], +static void gc_psx_read_packet(struct gc *gc, + unsigned char data[GC_MAX_DEVICES][GC_PSX_BYTES], unsigned char id[GC_MAX_DEVICES]) { int i, j, max_len = 0; @@ -582,12 +614,15 @@ static void gc_psx_read_packet(struct gc *gc, unsigned char data[GC_MAX_DEVICES] gc_psx_command(gc, 0, data2); /* Dump status */ /* Find the longest pad */ - for (i = 0; i < GC_MAX_DEVICES; i++) - if ((gc_status_bit[i] & (gc->pads[GC_PSX] | gc->pads[GC_DDR])) && + for (i = 0; i < GC_MAX_DEVICES; i++) { + struct gc_pad *pad = &gc->pads[i]; + + if ((pad->type == GC_PSX || pad->type == GC_DDR) && GC_PSX_LEN(id[i]) > max_len && GC_PSX_LEN(id[i]) <= GC_PSX_BYTES) { max_len = GC_PSX_LEN(id[i]); } + } /* Read in all the data */ for (i = 0; i < max_len; i++) { @@ -605,13 +640,13 @@ static void gc_psx_read_packet(struct gc *gc, unsigned char data[GC_MAX_DEVICES] id[i] = GC_PSX_ID(id[i]); } -static void gc_psx_report_one(struct gc *gc, struct input_dev *dev, - unsigned char pad_type, unsigned char status_bit, +static void gc_psx_report_one(struct gc_pad *pad, unsigned char psx_type, unsigned char *data) { + struct input_dev *dev = pad->dev; int i; - switch (pad_type) { + switch (psx_type) { case GC_PSX_RUMBLE: @@ -621,7 +656,7 @@ static void gc_psx_report_one(struct gc *gc, struct input_dev *dev, case GC_PSX_NEGCON: case GC_PSX_ANALOG: - if (gc->pads[GC_DDR] & status_bit) { + if (pad->type == GC_DDR) { for (i = 0; i < 4; i++) input_report_key(dev, gc_psx_ddr_btn[i], ~data[0] & (0x10 << i)); @@ -647,7 +682,8 @@ static void gc_psx_report_one(struct gc *gc, struct input_dev *dev, break; case GC_PSX_NORMAL: - if (gc->pads[GC_DDR] & status_bit) { + + if (pad->type == GC_DDR) { for (i = 0; i < 4; i++) input_report_key(dev, gc_psx_ddr_btn[i], ~data[0] & (0x10 << i)); @@ -679,7 +715,7 @@ static void gc_psx_report_one(struct gc *gc, struct input_dev *dev, break; - case 0: /* not a pad, ignore */ + default: /* not a pad, ignore */ break; } } @@ -688,15 +724,15 @@ static void gc_psx_process_packet(struct gc *gc) { unsigned char data[GC_MAX_DEVICES][GC_PSX_BYTES]; unsigned char id[GC_MAX_DEVICES]; + struct gc_pad *pad; int i; gc_psx_read_packet(gc, data, id); for (i = 0; i < GC_MAX_DEVICES; i++) { - - if (gc->dev[i]) - gc_psx_report_one(gc, gc->dev[i], - id[i], gc_status_bit[i], data[i]); + pad = &gc->pads[i]; + if (pad->type == GC_PSX || pad->type == GC_DDR) + gc_psx_report_one(pad, id[i], data[i]); } } @@ -712,28 +748,31 @@ static void gc_timer(unsigned long private) * N64 pads - must be read first, any read confuses them for 200 us */ - if (gc->pads[GC_N64]) + if (gc->pad_count[GC_N64]) gc_n64_process_packet(gc); /* * NES and SNES pads or mouse */ - if (gc->pads[GC_NES] || gc->pads[GC_SNES] || gc->pads[GC_SNESMOUSE]) + if (gc->pad_count[GC_NES] || + gc->pad_count[GC_SNES] || + gc->pad_count[GC_SNESMOUSE]) { gc_nes_process_packet(gc); + } /* * Multi and Multi2 joysticks */ - if (gc->pads[GC_MULTI] || gc->pads[GC_MULTI2]) + if (gc->pad_count[GC_MULTI] || gc->pad_count[GC_MULTI2]) gc_multi_process_packet(gc); /* * PSX controllers */ - if (gc->pads[GC_PSX] || gc->pads[GC_DDR]) + if (gc->pad_count[GC_PSX] || gc->pad_count[GC_DDR]) gc_psx_process_packet(gc); mod_timer(&gc->timer, jiffies + GC_REFRESH_TIME); @@ -773,26 +812,29 @@ static void gc_close(struct input_dev *dev) static int __init gc_setup_pad(struct gc *gc, int idx, int pad_type) { + struct gc_pad *pad = &gc->pads[idx]; struct input_dev *input_dev; int i; int err; - if (!pad_type) - return 0; - if (pad_type < 1 || pad_type > GC_MAX) { printk(KERN_WARNING "gamecon.c: Pad type %d unknown\n", pad_type); return -EINVAL; } - gc->dev[idx] = input_dev = input_allocate_device(); + pad->dev = input_dev = input_allocate_device(); if (!input_dev) { printk(KERN_ERR "gamecon.c: Not enough memory for input device\n"); return -ENOMEM; } + pad->type = pad_type; + + snprintf(pad->phys, sizeof(pad->phys), + "%s/input%d", gc->pd->port->name, idx); + input_dev->name = gc_names[pad_type]; - input_dev->phys = gc->phys[idx]; + input_dev->phys = pad->phys; input_dev->id.bustype = BUS_PARPORT; input_dev->id.vendor = 0x0001; input_dev->id.product = pad_type; @@ -811,8 +853,7 @@ static int __init gc_setup_pad(struct gc *gc, int idx, int pad_type) } else input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL); - gc->pads[0] |= gc_status_bit[idx]; - gc->pads[pad_type] |= gc_status_bit[idx]; + gc->pad_count[pad_type]++; switch (pad_type) { @@ -828,8 +869,7 @@ static int __init gc_setup_pad(struct gc *gc, int idx, int pad_type) err = gc_n64_init_ff(input_dev, idx); if (err) { printk(KERN_WARNING "gamecon.c: Failed to initiate rumble for N64 device %d\n", idx); - input_free_device(input_dev); - return err; + goto err_free_dev; } break; @@ -873,7 +913,16 @@ static int __init gc_setup_pad(struct gc *gc, int idx, int pad_type) break; } + err = input_register_device(pad->dev); + if (err) + goto err_free_dev; + return 0; + +err_free_dev: + input_free_device(pad->dev); + pad->dev = NULL; + return err; } static struct gc __init *gc_probe(int parport, int *pads, int n_pads) @@ -882,6 +931,7 @@ static struct gc __init *gc_probe(int parport, int *pads, int n_pads) struct parport *pp; struct pardevice *pd; int i; + int count = 0; int err; pp = parport_find_number(parport); @@ -913,18 +963,14 @@ static struct gc __init *gc_probe(int parport, int *pads, int n_pads) if (!pads[i]) continue; - snprintf(gc->phys[i], sizeof(gc->phys[i]), - "%s/input%d", gc->pd->port->name, i); err = gc_setup_pad(gc, i, pads[i]); if (err) goto err_unreg_devs; - err = input_register_device(gc->dev[i]); - if (err) - goto err_free_dev; + count++; } - if (!gc->pads[0]) { + if (count == 0) { printk(KERN_ERR "gamecon.c: No valid devices specified\n"); err = -EINVAL; goto err_free_gc; @@ -933,12 +979,10 @@ static struct gc __init *gc_probe(int parport, int *pads, int n_pads) parport_put_port(pp); return gc; - err_free_dev: - input_free_device(gc->dev[i]); err_unreg_devs: while (--i >= 0) - if (gc->dev[i]) - input_unregister_device(gc->dev[i]); + if (gc->pads[i].dev) + input_unregister_device(gc->pads[i].dev); err_free_gc: kfree(gc); err_unreg_pardev: @@ -954,8 +998,8 @@ static void gc_remove(struct gc *gc) int i; for (i = 0; i < GC_MAX_DEVICES; i++) - if (gc->dev[i]) - input_unregister_device(gc->dev[i]); + if (gc->pads[i].dev) + input_unregister_device(gc->pads[i].dev); parport_unregister_device(gc->pd); kfree(gc); } -- cgit v1.2.3 From af930d646251a6d3f4fd80c5fe158177487f43b7 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Sun, 21 Feb 2010 20:55:09 -0800 Subject: Input: gamecon - constify some of the setup structures Tested-by: Scott Moreau Signed-off-by: Dmitry Torokhov --- drivers/input/joystick/gamecon.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'drivers/input') diff --git a/drivers/input/joystick/gamecon.c b/drivers/input/joystick/gamecon.c index e9c6647e1f74..9ba65eae5f68 100644 --- a/drivers/input/joystick/gamecon.c +++ b/drivers/input/joystick/gamecon.c @@ -99,9 +99,9 @@ struct gc_subdev { static struct gc *gc_base[3]; -static int gc_status_bit[] = { 0x40, 0x80, 0x20, 0x10, 0x08 }; +static const int gc_status_bit[] = { 0x40, 0x80, 0x20, 0x10, 0x08 }; -static char *gc_names[] = { +static const char *gc_names[] = { NULL, "SNES pad", "NES pad", "NES FourPort", "Multisystem joystick", "Multisystem 2-button joystick", "N64 controller", "PSX controller", "PSX DDR controller", "SNES mouse" @@ -111,8 +111,8 @@ static char *gc_names[] = { * N64 support. */ -static unsigned char gc_n64_bytes[] = { 0, 1, 13, 15, 14, 12, 10, 11, 2, 3 }; -static short gc_n64_btn[] = { +static const unsigned char gc_n64_bytes[] = { 0, 1, 13, 15, 14, 12, 10, 11, 2, 3 }; +static const short gc_n64_btn[] = { BTN_A, BTN_B, BTN_C, BTN_X, BTN_Y, BTN_Z, BTN_TL, BTN_TR, BTN_TRIGGER, BTN_START }; @@ -339,9 +339,9 @@ static int __init gc_n64_init_ff(struct input_dev *dev, int i) #define GC_NES_CLOCK 0x01 #define GC_NES_LATCH 0x02 -static unsigned char gc_nes_bytes[] = { 0, 1, 2, 3 }; -static unsigned char gc_snes_bytes[] = { 8, 0, 2, 3, 9, 1, 10, 11 }; -static short gc_snes_btn[] = { +static const unsigned char gc_nes_bytes[] = { 0, 1, 2, 3 }; +static const unsigned char gc_snes_bytes[] = { 8, 0, 2, 3, 9, 1, 10, 11 }; +static const short gc_snes_btn[] = { BTN_A, BTN_B, BTN_SELECT, BTN_START, BTN_X, BTN_Y, BTN_TL, BTN_TR }; @@ -547,14 +547,14 @@ static int gc_psx_delay = GC_PSX_DELAY; module_param_named(psx_delay, gc_psx_delay, uint, 0); MODULE_PARM_DESC(psx_delay, "Delay when accessing Sony PSX controller (usecs)"); -static short gc_psx_abs[] = { +static const short gc_psx_abs[] = { ABS_X, ABS_Y, ABS_RX, ABS_RY, ABS_HAT0X, ABS_HAT0Y }; -static short gc_psx_btn[] = { +static const short gc_psx_btn[] = { BTN_TL, BTN_TR, BTN_TL2, BTN_TR2, BTN_A, BTN_B, BTN_X, BTN_Y, BTN_START, BTN_SELECT, BTN_THUMBL, BTN_THUMBR }; -static short gc_psx_ddr_btn[] = { BTN_0, BTN_1, BTN_2, BTN_3 }; +static const short gc_psx_ddr_btn[] = { BTN_0, BTN_1, BTN_2, BTN_3 }; /* * gc_psx_command() writes 8bit command and reads 8bit data from -- cgit v1.2.3 From a1e1274747b2741188b554e35dc5d4056ef7beac Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Sun, 21 Feb 2010 20:55:31 -0800 Subject: Input: gamecon - use pr_err() and friends Tested-by: Scott Moreau Signed-off-by: Dmitry Torokhov --- drivers/input/joystick/gamecon.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) (limited to 'drivers/input') diff --git a/drivers/input/joystick/gamecon.c b/drivers/input/joystick/gamecon.c index 9ba65eae5f68..ae998d99a5ae 100644 --- a/drivers/input/joystick/gamecon.c +++ b/drivers/input/joystick/gamecon.c @@ -30,6 +30,8 @@ * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include @@ -818,13 +820,13 @@ static int __init gc_setup_pad(struct gc *gc, int idx, int pad_type) int err; if (pad_type < 1 || pad_type > GC_MAX) { - printk(KERN_WARNING "gamecon.c: Pad type %d unknown\n", pad_type); + pr_err("Pad type %d unknown\n", pad_type); return -EINVAL; } pad->dev = input_dev = input_allocate_device(); if (!input_dev) { - printk(KERN_ERR "gamecon.c: Not enough memory for input device\n"); + pr_err("Not enough memory for input device\n"); return -ENOMEM; } @@ -868,7 +870,7 @@ static int __init gc_setup_pad(struct gc *gc, int idx, int pad_type) err = gc_n64_init_ff(input_dev, idx); if (err) { - printk(KERN_WARNING "gamecon.c: Failed to initiate rumble for N64 device %d\n", idx); + pr_warning("Failed to initiate rumble for N64 device %d\n", idx); goto err_free_dev; } @@ -936,21 +938,21 @@ static struct gc __init *gc_probe(int parport, int *pads, int n_pads) pp = parport_find_number(parport); if (!pp) { - printk(KERN_ERR "gamecon.c: no such parport\n"); + pr_err("no such parport %d\n", parport); err = -EINVAL; goto err_out; } pd = parport_register_device(pp, "gamecon", NULL, NULL, NULL, PARPORT_DEV_EXCL, NULL); if (!pd) { - printk(KERN_ERR "gamecon.c: parport busy already - lp.o loaded?\n"); + pr_err("parport busy already - lp.o loaded?\n"); err = -EBUSY; goto err_put_pp; } gc = kzalloc(sizeof(struct gc), GFP_KERNEL); if (!gc) { - printk(KERN_ERR "gamecon.c: Not enough memory\n"); + pr_err("Not enough memory\n"); err = -ENOMEM; goto err_unreg_pardev; } @@ -971,7 +973,7 @@ static struct gc __init *gc_probe(int parport, int *pads, int n_pads) } if (count == 0) { - printk(KERN_ERR "gamecon.c: No valid devices specified\n"); + pr_err("No valid devices specified\n"); err = -EINVAL; goto err_free_gc; } @@ -1015,7 +1017,7 @@ static int __init gc_init(void) continue; if (gc_cfg[i].nargs < 2) { - printk(KERN_ERR "gamecon.c: at least one device must be specified\n"); + pr_err("at least one device must be specified\n"); err = -EINVAL; break; } -- cgit v1.2.3 From 197d4db752e67160d79fed09968c2140376a80a3 Mon Sep 17 00:00:00 2001 From: David Härdeman Date: Wed, 24 Feb 2010 02:08:29 -0800 Subject: Input: winbond-cir - fix suspend/resume MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This fixes suspend/resume problem with the driver caused by the fact that ACPI _DIS method would completely power off the SP3 module leaving the output lines (including IRQ lines) in an undefined state. This could cause spurious interrupts and requires reinitializing hardware from scratch during resume. This fixes: http://bugzilla.kernel.org/show_bug.cgi?id=15257 Signed-off-by: David Härdeman Signed-off-by: Dmitry Torokhov --- drivers/input/misc/winbond-cir.c | 213 +++++++++++++++++++-------------------- 1 file changed, 104 insertions(+), 109 deletions(-) (limited to 'drivers/input') diff --git a/drivers/input/misc/winbond-cir.c b/drivers/input/misc/winbond-cir.c index c8f5a9a3fa14..cbec3dfdd42b 100644 --- a/drivers/input/misc/winbond-cir.c +++ b/drivers/input/misc/winbond-cir.c @@ -538,6 +538,7 @@ wbcir_reset_irdata(struct wbcir_data *data) data->irdata_count = 0; data->irdata_off = 0; data->irdata_error = 0; + data->idle_count = 0; } /* Adds one bit of irdata */ @@ -1006,7 +1007,6 @@ wbcir_irq_handler(int irqno, void *cookie) } wbcir_reset_irdata(data); - data->idle_count = 0; } out: @@ -1018,7 +1018,7 @@ out: /***************************************************************************** * - * SUSPEND/RESUME FUNCTIONS + * SETUP/INIT/SUSPEND/RESUME FUNCTIONS * *****************************************************************************/ @@ -1197,7 +1197,16 @@ finish: } /* Disable interrupts */ + wbcir_select_bank(data, WBCIR_BANK_0); outb(WBCIR_IRQ_NONE, data->sbase + WBCIR_REG_SP3_IER); + + /* + * ACPI will set the HW disable bit for SP3 which means that the + * output signals are left in an undefined state which may cause + * spurious interrupts which we need to ignore until the hardware + * is reinitialized. + */ + disable_irq(data->irq); } static int @@ -1207,37 +1216,15 @@ wbcir_suspend(struct pnp_dev *device, pm_message_t state) return 0; } -static int -wbcir_resume(struct pnp_dev *device) -{ - struct wbcir_data *data = pnp_get_drvdata(device); - - /* Clear BUFF_EN, Clear END_EN, Clear MATCH_EN */ - wbcir_set_bits(data->wbase + WBCIR_REG_WCEIR_EV_EN, 0x00, 0x07); - - /* Clear CEIR_EN */ - wbcir_set_bits(data->wbase + WBCIR_REG_WCEIR_CTL, 0x00, 0x01); - - /* Enable interrupts */ - wbcir_reset_irdata(data); - outb(WBCIR_IRQ_RX | WBCIR_IRQ_ERR, data->sbase + WBCIR_REG_SP3_IER); - - return 0; -} - - - -/***************************************************************************** - * - * SETUP/INIT FUNCTIONS - * - *****************************************************************************/ - static void -wbcir_cfg_ceir(struct wbcir_data *data) +wbcir_init_hw(struct wbcir_data *data) { u8 tmp; + /* Disable interrupts */ + wbcir_select_bank(data, WBCIR_BANK_0); + outb(WBCIR_IRQ_NONE, data->sbase + WBCIR_REG_SP3_IER); + /* Set PROT_SEL, RX_INV, Clear CEIR_EN (needed for the led) */ tmp = protocol << 4; if (invert) @@ -1264,6 +1251,93 @@ wbcir_cfg_ceir(struct wbcir_data *data) * set SP3_IRRX_SW to binary 01, helpfully not documented */ outb(0x10, data->ebase + WBCIR_REG_ECEIR_CTS); + + /* Enable extended mode */ + wbcir_select_bank(data, WBCIR_BANK_2); + outb(WBCIR_EXT_ENABLE, data->sbase + WBCIR_REG_SP3_EXCR1); + + /* + * Configure baud generator, IR data will be sampled at + * a bitrate of: (24Mhz * prescaler) / (divisor * 16). + * + * The ECIR registers include a flag to change the + * 24Mhz clock freq to 48Mhz. + * + * It's not documented in the specs, but fifo levels + * other than 16 seems to be unsupported. + */ + + /* prescaler 1.0, tx/rx fifo lvl 16 */ + outb(0x30, data->sbase + WBCIR_REG_SP3_EXCR2); + + /* Set baud divisor to generate one byte per bit/cell */ + switch (protocol) { + case IR_PROTOCOL_RC5: + outb(0xA7, data->sbase + WBCIR_REG_SP3_BGDL); + break; + case IR_PROTOCOL_RC6: + outb(0x53, data->sbase + WBCIR_REG_SP3_BGDL); + break; + case IR_PROTOCOL_NEC: + outb(0x69, data->sbase + WBCIR_REG_SP3_BGDL); + break; + } + outb(0x00, data->sbase + WBCIR_REG_SP3_BGDH); + + /* Set CEIR mode */ + wbcir_select_bank(data, WBCIR_BANK_0); + outb(0xC0, data->sbase + WBCIR_REG_SP3_MCR); + inb(data->sbase + WBCIR_REG_SP3_LSR); /* Clear LSR */ + inb(data->sbase + WBCIR_REG_SP3_MSR); /* Clear MSR */ + + /* Disable RX demod, run-length encoding/decoding, set freq span */ + wbcir_select_bank(data, WBCIR_BANK_7); + outb(0x10, data->sbase + WBCIR_REG_SP3_RCCFG); + + /* Disable timer */ + wbcir_select_bank(data, WBCIR_BANK_4); + outb(0x00, data->sbase + WBCIR_REG_SP3_IRCR1); + + /* Enable MSR interrupt, Clear AUX_IRX */ + wbcir_select_bank(data, WBCIR_BANK_5); + outb(0x00, data->sbase + WBCIR_REG_SP3_IRCR2); + + /* Disable CRC */ + wbcir_select_bank(data, WBCIR_BANK_6); + outb(0x20, data->sbase + WBCIR_REG_SP3_IRCR3); + + /* Set RX/TX (de)modulation freq, not really used */ + wbcir_select_bank(data, WBCIR_BANK_7); + outb(0xF2, data->sbase + WBCIR_REG_SP3_IRRXDC); + outb(0x69, data->sbase + WBCIR_REG_SP3_IRTXMC); + + /* Set invert and pin direction */ + if (invert) + outb(0x10, data->sbase + WBCIR_REG_SP3_IRCFG4); + else + outb(0x00, data->sbase + WBCIR_REG_SP3_IRCFG4); + + /* Set FIFO thresholds (RX = 8, TX = 3), reset RX/TX */ + wbcir_select_bank(data, WBCIR_BANK_0); + outb(0x97, data->sbase + WBCIR_REG_SP3_FCR); + + /* Clear AUX status bits */ + outb(0xE0, data->sbase + WBCIR_REG_SP3_ASCR); + + /* Enable interrupts */ + wbcir_reset_irdata(data); + outb(WBCIR_IRQ_RX | WBCIR_IRQ_ERR, data->sbase + WBCIR_REG_SP3_IER); +} + +static int +wbcir_resume(struct pnp_dev *device) +{ + struct wbcir_data *data = pnp_get_drvdata(device); + + wbcir_init_hw(data); + enable_irq(data->irq); + + return 0; } static int __devinit @@ -1393,86 +1467,7 @@ wbcir_probe(struct pnp_dev *device, const struct pnp_device_id *dev_id) device_init_wakeup(&device->dev, 1); - wbcir_cfg_ceir(data); - - /* Disable interrupts */ - wbcir_select_bank(data, WBCIR_BANK_0); - outb(WBCIR_IRQ_NONE, data->sbase + WBCIR_REG_SP3_IER); - - /* Enable extended mode */ - wbcir_select_bank(data, WBCIR_BANK_2); - outb(WBCIR_EXT_ENABLE, data->sbase + WBCIR_REG_SP3_EXCR1); - - /* - * Configure baud generator, IR data will be sampled at - * a bitrate of: (24Mhz * prescaler) / (divisor * 16). - * - * The ECIR registers include a flag to change the - * 24Mhz clock freq to 48Mhz. - * - * It's not documented in the specs, but fifo levels - * other than 16 seems to be unsupported. - */ - - /* prescaler 1.0, tx/rx fifo lvl 16 */ - outb(0x30, data->sbase + WBCIR_REG_SP3_EXCR2); - - /* Set baud divisor to generate one byte per bit/cell */ - switch (protocol) { - case IR_PROTOCOL_RC5: - outb(0xA7, data->sbase + WBCIR_REG_SP3_BGDL); - break; - case IR_PROTOCOL_RC6: - outb(0x53, data->sbase + WBCIR_REG_SP3_BGDL); - break; - case IR_PROTOCOL_NEC: - outb(0x69, data->sbase + WBCIR_REG_SP3_BGDL); - break; - } - outb(0x00, data->sbase + WBCIR_REG_SP3_BGDH); - - /* Set CEIR mode */ - wbcir_select_bank(data, WBCIR_BANK_0); - outb(0xC0, data->sbase + WBCIR_REG_SP3_MCR); - inb(data->sbase + WBCIR_REG_SP3_LSR); /* Clear LSR */ - inb(data->sbase + WBCIR_REG_SP3_MSR); /* Clear MSR */ - - /* Disable RX demod, run-length encoding/decoding, set freq span */ - wbcir_select_bank(data, WBCIR_BANK_7); - outb(0x10, data->sbase + WBCIR_REG_SP3_RCCFG); - - /* Disable timer */ - wbcir_select_bank(data, WBCIR_BANK_4); - outb(0x00, data->sbase + WBCIR_REG_SP3_IRCR1); - - /* Enable MSR interrupt, Clear AUX_IRX */ - wbcir_select_bank(data, WBCIR_BANK_5); - outb(0x00, data->sbase + WBCIR_REG_SP3_IRCR2); - - /* Disable CRC */ - wbcir_select_bank(data, WBCIR_BANK_6); - outb(0x20, data->sbase + WBCIR_REG_SP3_IRCR3); - - /* Set RX/TX (de)modulation freq, not really used */ - wbcir_select_bank(data, WBCIR_BANK_7); - outb(0xF2, data->sbase + WBCIR_REG_SP3_IRRXDC); - outb(0x69, data->sbase + WBCIR_REG_SP3_IRTXMC); - - /* Set invert and pin direction */ - if (invert) - outb(0x10, data->sbase + WBCIR_REG_SP3_IRCFG4); - else - outb(0x00, data->sbase + WBCIR_REG_SP3_IRCFG4); - - /* Set FIFO thresholds (RX = 8, TX = 3), reset RX/TX */ - wbcir_select_bank(data, WBCIR_BANK_0); - outb(0x97, data->sbase + WBCIR_REG_SP3_FCR); - - /* Clear AUX status bits */ - outb(0xE0, data->sbase + WBCIR_REG_SP3_ASCR); - - /* Enable interrupts */ - outb(WBCIR_IRQ_RX | WBCIR_IRQ_ERR, data->sbase + WBCIR_REG_SP3_IER); + wbcir_init_hw(data); return 0; -- cgit v1.2.3 From 91143379b01b2020d8878d627ebe9dfb9d6eb4c8 Mon Sep 17 00:00:00 2001 From: Grazvydas Ignotas Date: Thu, 25 Feb 2010 02:04:56 -0800 Subject: Input: ads7846 - add regulator support The ADS7846/TSC2046 touchscreen controllers can (and usually are) connected to various regulators for power, so add regulator support. Valid regulator will now be required, so boards without complete regulator setup should either disable regulator framework or enable CONFIG_REGULATOR_DUMMY. Signed-off-by: Grazvydas Ignotas Acked-by: Mark Brown Signed-off-by: Dmitry Torokhov --- drivers/input/touchscreen/ads7846.c | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) (limited to 'drivers/input') diff --git a/drivers/input/touchscreen/ads7846.c b/drivers/input/touchscreen/ads7846.c index 52d2ca147d8f..8b05d8e97543 100644 --- a/drivers/input/touchscreen/ads7846.c +++ b/drivers/input/touchscreen/ads7846.c @@ -27,6 +27,7 @@ #include #include #include +#include #include /* @@ -85,6 +86,7 @@ struct ads7846 { char name[32]; struct spi_device *spi; + struct regulator *reg; #if defined(CONFIG_HWMON) || defined(CONFIG_HWMON_MODULE) struct attribute_group *attr_group; @@ -788,6 +790,8 @@ static void ads7846_disable(struct ads7846 *ts) } } + regulator_disable(ts->reg); + /* we know the chip's in lowpower mode since we always * leave it that way after every request */ @@ -799,6 +803,8 @@ static void ads7846_enable(struct ads7846 *ts) if (!ts->disabled) return; + regulator_enable(ts->reg); + ts->disabled = 0; ts->irq_disabled = 0; enable_irq(ts->spi->irq); @@ -1139,6 +1145,19 @@ static int __devinit ads7846_probe(struct spi_device *spi) ts->last_msg = m; + ts->reg = regulator_get(&spi->dev, "vcc"); + if (IS_ERR(ts->reg)) { + dev_err(&spi->dev, "unable to get regulator: %ld\n", + PTR_ERR(ts->reg)); + goto err_free_gpio; + } + + err = regulator_enable(ts->reg); + if (err) { + dev_err(&spi->dev, "unable to enable regulator: %d\n", err); + goto err_put_regulator; + } + if (request_irq(spi->irq, ads7846_irq, IRQF_TRIGGER_FALLING, spi->dev.driver->name, ts)) { dev_info(&spi->dev, @@ -1148,7 +1167,7 @@ static int __devinit ads7846_probe(struct spi_device *spi) spi->dev.driver->name, ts); if (err) { dev_dbg(&spi->dev, "irq %d busy?\n", spi->irq); - goto err_free_gpio; + goto err_disable_regulator; } } @@ -1180,6 +1199,10 @@ static int __devinit ads7846_probe(struct spi_device *spi) ads784x_hwmon_unregister(spi, ts); err_free_irq: free_irq(spi->irq, ts); + err_disable_regulator: + regulator_disable(ts->reg); + err_put_regulator: + regulator_put(ts->reg); err_free_gpio: if (ts->gpio_pendown != -1) gpio_free(ts->gpio_pendown); @@ -1208,6 +1231,9 @@ static int __devexit ads7846_remove(struct spi_device *spi) /* suspend left the IRQ disabled */ enable_irq(ts->spi->irq); + regulator_disable(ts->reg); + regulator_put(ts->reg); + if (ts->gpio_pendown != -1) gpio_free(ts->gpio_pendown); -- cgit v1.2.3 From 4b70858ba8d4537daf782defebe5f2ff80ccef2b Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Fri, 26 Feb 2010 00:22:04 -0800 Subject: Input: atkbd - release previously reserved keycodes 248 - 254 Keycodes in 248 - 254 range were reserved for special needs (scrolling) of atkbd driver. Now that the driver has been switched to use unsigned short keycodes instead of unsigned char we can release this range back into pull. We keep code 255 (ATKBD_KEY_NULL) reserved since users may have been using it to silence keys they do not care about since atkbd silently drops scancodes mapped to this keycode. Signed-off-by: Dmitry Torokhov --- drivers/input/keyboard/atkbd.c | 26 +++++++++++++++----------- include/linux/input.h | 2 +- 2 files changed, 16 insertions(+), 12 deletions(-) (limited to 'drivers/input') diff --git a/drivers/input/keyboard/atkbd.c b/drivers/input/keyboard/atkbd.c index 326875be192e..d358ef8623f4 100644 --- a/drivers/input/keyboard/atkbd.c +++ b/drivers/input/keyboard/atkbd.c @@ -153,16 +153,16 @@ static const unsigned short atkbd_unxlate_table[128] = { #define ATKBD_RET_HANGEUL 0xf2 #define ATKBD_RET_ERR 0xff -#define ATKBD_KEY_UNKNOWN 0 +#define ATKBD_KEY_UNKNOWN 0 #define ATKBD_KEY_NULL 255 -#define ATKBD_SCR_1 254 -#define ATKBD_SCR_2 253 -#define ATKBD_SCR_4 252 -#define ATKBD_SCR_8 251 -#define ATKBD_SCR_CLICK 250 -#define ATKBD_SCR_LEFT 249 -#define ATKBD_SCR_RIGHT 248 +#define ATKBD_SCR_1 0xfffe +#define ATKBD_SCR_2 0xfffd +#define ATKBD_SCR_4 0xfffc +#define ATKBD_SCR_8 0xfffb +#define ATKBD_SCR_CLICK 0xfffa +#define ATKBD_SCR_LEFT 0xfff9 +#define ATKBD_SCR_RIGHT 0xfff8 #define ATKBD_SPECIAL ATKBD_SCR_RIGHT @@ -177,7 +177,7 @@ static const unsigned short atkbd_unxlate_table[128] = { #define ATKBD_XL_HANJA 0x20 static const struct { - unsigned char keycode; + unsigned short keycode; unsigned char set2; } atkbd_scroll_keys[] = { { ATKBD_SCR_1, 0xc5 }, @@ -1074,9 +1074,13 @@ static void atkbd_set_device_attrs(struct atkbd *atkbd) input_dev->keycodesize = sizeof(unsigned short); input_dev->keycodemax = ARRAY_SIZE(atkbd_set2_keycode); - for (i = 0; i < ATKBD_KEYMAP_SIZE; i++) - if (atkbd->keycode[i] && atkbd->keycode[i] < ATKBD_SPECIAL) + for (i = 0; i < ATKBD_KEYMAP_SIZE; i++) { + if (atkbd->keycode[i] != KEY_RESERVED && + atkbd->keycode[i] != ATKBD_KEY_NULL && + atkbd->keycode[i] < ATKBD_SPECIAL) { __set_bit(atkbd->keycode[i], input_dev->keybit); + } + } } /* diff --git a/include/linux/input.h b/include/linux/input.h index 828c3feb7213..b1a74fb2e436 100644 --- a/include/linux/input.h +++ b/include/linux/input.h @@ -377,7 +377,7 @@ struct input_absinfo { #define KEY_WIMAX 246 -/* Range 248 - 255 is reserved for special needs of AT keyboard driver */ +/* Code 255 is reserved for special needs of AT keyboard driver */ #define BTN_MISC 0x100 #define BTN_0 0x100 -- cgit v1.2.3 From da8065ac3ea29d1bfdb5a163be346fbe35066f8d Mon Sep 17 00:00:00 2001 From: Eric Miao Date: Thu, 4 Feb 2010 17:13:55 -0800 Subject: [ARM] locomo: avoid unnecessary cascaded keyboard IRQ It is not necessary and is over-complicated for IRQ_LOCOMO_KEY to be a cascaded IRQ of IRQ_LOCOMO_KEY_BASE. Removed and introduced locomokbd_{open,close} for masking/unmasking of the keyboard IRQ. Signed-off-by: Eric Miao --- arch/arm/common/locomo.c | 63 +++----------------------------- arch/arm/mach-pxa/include/mach/irqs.h | 3 +- arch/arm/mach-sa1100/include/mach/irqs.h | 3 +- drivers/input/keyboard/locomokbd.c | 32 +++++++++++++++- 4 files changed, 39 insertions(+), 62 deletions(-) (limited to 'drivers/input') diff --git a/arch/arm/common/locomo.c b/arch/arm/common/locomo.c index bd36c778c819..96cd0730167d 100644 --- a/arch/arm/common/locomo.c +++ b/arch/arm/common/locomo.c @@ -143,12 +143,10 @@ static struct locomo_dev_info locomo_devices[] = { * IRQ_LOCOMO_*_BASE and those handlers generate more interrupts * * hardware irq reads LOCOMO_ICR & 0x0f00 - * IRQ_LOCOMO_KEY_BASE + * IRQ_LOCOMO_KEY * IRQ_LOCOMO_GPIO_BASE * IRQ_LOCOMO_LT_BASE * IRQ_LOCOMO_SPI_BASE - * IRQ_LOCOMO_KEY_BASE reads LOCOMO_KIC & 0x0001 - * IRQ_LOCOMO_KEY * IRQ_LOCOMO_GPIO_BASE reads LOCOMO_GIR & LOCOMO_GPD & 0xffff * IRQ_LOCOMO_GPIO[0-15] * IRQ_LOCOMO_LT_BASE reads LOCOMO_LTINT & 0x0001 @@ -160,8 +158,7 @@ static struct locomo_dev_info locomo_devices[] = { * IRQ_LOCOMO_SPI_TEND */ -#define LOCOMO_IRQ_START (IRQ_LOCOMO_KEY_BASE) -#define LOCOMO_IRQ_KEY_START (IRQ_LOCOMO_KEY) +#define LOCOMO_IRQ_START (IRQ_LOCOMO_KEY) #define LOCOMO_IRQ_GPIO_START (IRQ_LOCOMO_GPIO0) #define LOCOMO_IRQ_LT_START (IRQ_LOCOMO_LT) #define LOCOMO_IRQ_SPI_START (IRQ_LOCOMO_SPI_RFR) @@ -218,49 +215,6 @@ static struct irq_chip locomo_chip = { .unmask = locomo_unmask_irq, }; -static void locomo_key_handler(unsigned int irq, struct irq_desc *desc) -{ - void __iomem *mapbase = get_irq_chip_data(irq); - - if (locomo_readl(mapbase + LOCOMO_KEYBOARD + LOCOMO_KIC) & 0x0001) { - generic_handle_irq(LOCOMO_IRQ_KEY_START); - } -} - -static void locomo_key_ack_irq(unsigned int irq) -{ - void __iomem *mapbase = get_irq_chip_data(irq); - unsigned int r; - r = locomo_readl(mapbase + LOCOMO_KEYBOARD + LOCOMO_KIC); - r &= ~(0x0100 << (irq - LOCOMO_IRQ_KEY_START)); - locomo_writel(r, mapbase + LOCOMO_KEYBOARD + LOCOMO_KIC); -} - -static void locomo_key_mask_irq(unsigned int irq) -{ - void __iomem *mapbase = get_irq_chip_data(irq); - unsigned int r; - r = locomo_readl(mapbase + LOCOMO_KEYBOARD + LOCOMO_KIC); - r &= ~(0x0010 << (irq - LOCOMO_IRQ_KEY_START)); - locomo_writel(r, mapbase + LOCOMO_KEYBOARD + LOCOMO_KIC); -} - -static void locomo_key_unmask_irq(unsigned int irq) -{ - void __iomem *mapbase = get_irq_chip_data(irq); - unsigned int r; - r = locomo_readl(mapbase + LOCOMO_KEYBOARD + LOCOMO_KIC); - r |= (0x0010 << (irq - LOCOMO_IRQ_KEY_START)); - locomo_writel(r, mapbase + LOCOMO_KEYBOARD + LOCOMO_KIC); -} - -static struct irq_chip locomo_key_chip = { - .name = "LOCOMO-key", - .ack = locomo_key_ack_irq, - .mask = locomo_key_mask_irq, - .unmask = locomo_key_unmask_irq, -}; - static void locomo_gpio_handler(unsigned int irq, struct irq_desc *desc) { int req, i; @@ -468,9 +422,10 @@ static void locomo_setup_irq(struct locomo *lchip) set_irq_chained_handler(lchip->irq, locomo_handler); /* Install handlers for IRQ_LOCOMO_*_BASE */ - set_irq_chip(IRQ_LOCOMO_KEY_BASE, &locomo_chip); - set_irq_chip_data(IRQ_LOCOMO_KEY_BASE, irqbase); - set_irq_chained_handler(IRQ_LOCOMO_KEY_BASE, locomo_key_handler); + set_irq_chip(IRQ_LOCOMO_KEY, &locomo_chip); + set_irq_chip_data(IRQ_LOCOMO_KEY, irqbase); + set_irq_handler(IRQ_LOCOMO_KEY, handle_edge_irq); + set_irq_flags(IRQ_LOCOMO_KEY, IRQF_VALID | IRQF_PROBE); set_irq_chip(IRQ_LOCOMO_GPIO_BASE, &locomo_chip); set_irq_chip_data(IRQ_LOCOMO_GPIO_BASE, irqbase); @@ -484,12 +439,6 @@ static void locomo_setup_irq(struct locomo *lchip) set_irq_chip_data(IRQ_LOCOMO_SPI_BASE, irqbase); set_irq_chained_handler(IRQ_LOCOMO_SPI_BASE, locomo_spi_handler); - /* install handlers for IRQ_LOCOMO_KEY_BASE generated interrupts */ - set_irq_chip(LOCOMO_IRQ_KEY_START, &locomo_key_chip); - set_irq_chip_data(LOCOMO_IRQ_KEY_START, irqbase); - set_irq_handler(LOCOMO_IRQ_KEY_START, handle_edge_irq); - set_irq_flags(LOCOMO_IRQ_KEY_START, IRQF_VALID | IRQF_PROBE); - /* install handlers for IRQ_LOCOMO_GPIO_BASE generated interrupts */ for (irq = LOCOMO_IRQ_GPIO_START; irq < LOCOMO_IRQ_GPIO_START + 16; irq++) { set_irq_chip(irq, &locomo_gpio_chip); diff --git a/arch/arm/mach-pxa/include/mach/irqs.h b/arch/arm/mach-pxa/include/mach/irqs.h index 3677a9af9c87..33a4f33de271 100644 --- a/arch/arm/mach-pxa/include/mach/irqs.h +++ b/arch/arm/mach-pxa/include/mach/irqs.h @@ -188,7 +188,6 @@ #define IRQ_S1_BVD1_STSCHG (IRQ_BOARD_END + 54) #define IRQ_LOCOMO_START (IRQ_BOARD_END) -#define IRQ_LOCOMO_KEY (IRQ_BOARD_END + 0) #define IRQ_LOCOMO_GPIO0 (IRQ_BOARD_END + 1) #define IRQ_LOCOMO_GPIO1 (IRQ_BOARD_END + 2) #define IRQ_LOCOMO_GPIO2 (IRQ_BOARD_END + 3) @@ -274,7 +273,7 @@ #define BALLOON3_S0_CD_IRQ IRQ_GPIO(BALLOON3_GPIO_S0_CD) /* LoCoMo Interrupts (CONFIG_SHARP_LOCOMO) */ -#define IRQ_LOCOMO_KEY_BASE (IRQ_BOARD_START + 0) +#define IRQ_LOCOMO_KEY (IRQ_BOARD_START + 0) #define IRQ_LOCOMO_GPIO_BASE (IRQ_BOARD_START + 1) #define IRQ_LOCOMO_LT_BASE (IRQ_BOARD_START + 2) #define IRQ_LOCOMO_SPI_BASE (IRQ_BOARD_START + 3) diff --git a/arch/arm/mach-sa1100/include/mach/irqs.h b/arch/arm/mach-sa1100/include/mach/irqs.h index ae81f80b0cf9..9731c7814a32 100644 --- a/arch/arm/mach-sa1100/include/mach/irqs.h +++ b/arch/arm/mach-sa1100/include/mach/irqs.h @@ -121,7 +121,6 @@ #define IRQ_S1_BVD1_STSCHG (IRQ_BOARD_END + 54) #define IRQ_LOCOMO_START (IRQ_BOARD_END) -#define IRQ_LOCOMO_KEY (IRQ_BOARD_END + 0) #define IRQ_LOCOMO_GPIO0 (IRQ_BOARD_END + 1) #define IRQ_LOCOMO_GPIO1 (IRQ_BOARD_END + 2) #define IRQ_LOCOMO_GPIO2 (IRQ_BOARD_END + 3) @@ -168,7 +167,7 @@ #define IRQ_NEPONSET_SA1111 (IRQ_BOARD_START + 2) /* LoCoMo Interrupts (CONFIG_SHARP_LOCOMO) */ -#define IRQ_LOCOMO_KEY_BASE (IRQ_BOARD_START + 0) +#define IRQ_LOCOMO_KEY (IRQ_BOARD_START + 0) #define IRQ_LOCOMO_GPIO_BASE (IRQ_BOARD_START + 1) #define IRQ_LOCOMO_LT_BASE (IRQ_BOARD_START + 2) #define IRQ_LOCOMO_SPI_BASE (IRQ_BOARD_START + 3) diff --git a/drivers/input/keyboard/locomokbd.c b/drivers/input/keyboard/locomokbd.c index 9caed30f3bbb..b1ab29861e1c 100644 --- a/drivers/input/keyboard/locomokbd.c +++ b/drivers/input/keyboard/locomokbd.c @@ -192,11 +192,18 @@ static void locomokbd_scankeyboard(struct locomokbd *locomokbd) static irqreturn_t locomokbd_interrupt(int irq, void *dev_id) { struct locomokbd *locomokbd = dev_id; + u16 r; + + r = locomo_readl(locomokbd->base + LOCOMO_KIC); + if ((r & 0x0001) == 0) + return IRQ_HANDLED; + + locomo_writel(r & ~0x0100, locomokbd->base + LOCOMO_KIC); /* Ack */ + /** wait chattering delay **/ udelay(100); locomokbd_scankeyboard(locomokbd); - return IRQ_HANDLED; } @@ -210,6 +217,25 @@ static void locomokbd_timer_callback(unsigned long data) locomokbd_scankeyboard(locomokbd); } +static int locomokbd_open(struct input_dev *dev) +{ + struct locomokbd *locomokbd = input_get_drvdata(dev); + u16 r; + + r = locomo_readl(locomokbd->base + LOCOMO_KIC) | 0x0010; + locomo_writel(r, locomokbd->base + LOCOMO_KIC); + return 0; +} + +static void locomokbd_close(struct input_dev *dev) +{ + struct locomokbd *locomokbd = input_get_drvdata(dev); + u16 r; + + r = locomo_readl(locomokbd->base + LOCOMO_KIC) & ~0x0010; + locomo_writel(r, locomokbd->base + LOCOMO_KIC); +} + static int __devinit locomokbd_probe(struct locomo_dev *dev) { struct locomokbd *locomokbd; @@ -253,6 +279,8 @@ static int __devinit locomokbd_probe(struct locomo_dev *dev) input_dev->id.vendor = 0x0001; input_dev->id.product = 0x0001; input_dev->id.version = 0x0100; + input_dev->open = locomokbd_open; + input_dev->close = locomokbd_close; input_dev->dev.parent = &dev->dev; input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP) | @@ -261,6 +289,8 @@ static int __devinit locomokbd_probe(struct locomo_dev *dev) input_dev->keycodesize = sizeof(locomokbd_keycode[0]); input_dev->keycodemax = ARRAY_SIZE(locomokbd_keycode); + input_set_drvdata(input_dev, locomokbd); + memcpy(locomokbd->keycode, locomokbd_keycode, sizeof(locomokbd->keycode)); for (i = 0; i < LOCOMOKBD_NUMKEYS; i++) set_bit(locomokbd->keycode[i], input_dev->keybit); -- cgit v1.2.3 From 57e413d95b0f92b9a5569408ddc3441e0f20e856 Mon Sep 17 00:00:00 2001 From: Ping Cheng Date: Mon, 1 Mar 2010 23:50:24 -0800 Subject: Input: wacom - replace WACOM_PKGLEN_PENABLED Replacing WACOM_PKGLEN_PENABLED with WACOM_PKGLEN_GRAPHIRE since they both represent the same value, 8. This value will be used for both Tablet PC and Bamboo with touch devices. Signed-off-by: Ping Cheng Signed-off-by: Dmitry Torokhov --- drivers/input/tablet/wacom_sys.c | 4 ++-- drivers/input/tablet/wacom_wac.c | 2 +- drivers/input/tablet/wacom_wac.h | 1 - 3 files changed, 3 insertions(+), 4 deletions(-) (limited to 'drivers/input') diff --git a/drivers/input/tablet/wacom_sys.c b/drivers/input/tablet/wacom_sys.c index a1770e6feeec..8b5d2873f0c4 100644 --- a/drivers/input/tablet/wacom_sys.c +++ b/drivers/input/tablet/wacom_sys.c @@ -371,7 +371,7 @@ static int wacom_parse_hid(struct usb_interface *intf, struct hid_descriptor *hi } else if (pen) { /* penabled only accepts exact bytes of data */ if (features->type == TABLETPC2FG) - features->pktlen = WACOM_PKGLEN_PENABLED; + features->pktlen = WACOM_PKGLEN_GRAPHIRE; features->device_type = BTN_TOOL_PEN; features->x_max = wacom_le16_to_cpu(&report[i + 3]); @@ -410,7 +410,7 @@ static int wacom_parse_hid(struct usb_interface *intf, struct hid_descriptor *hi } else if (pen) { /* penabled only accepts exact bytes of data */ if (features->type == TABLETPC2FG) - features->pktlen = WACOM_PKGLEN_PENABLED; + features->pktlen = WACOM_PKGLEN_GRAPHIRE; features->device_type = BTN_TOOL_PEN; features->y_max = wacom_le16_to_cpu(&report[i + 3]); diff --git a/drivers/input/tablet/wacom_wac.c b/drivers/input/tablet/wacom_wac.c index 3d81443e683a..4a852d815c68 100644 --- a/drivers/input/tablet/wacom_wac.c +++ b/drivers/input/tablet/wacom_wac.c @@ -1028,7 +1028,7 @@ static const struct wacom_features wacom_features_0x93 = static const struct wacom_features wacom_features_0x9A = { "Wacom ISDv4 9A", WACOM_PKGLEN_GRAPHIRE, 26202, 16325, 255, 0, TABLETPC }; static const struct wacom_features wacom_features_0x9F = - { "Wacom ISDv4 9F", WACOM_PKGLEN_PENABLED, 26202, 16325, 255, 0, TABLETPC }; + { "Wacom ISDv4 9F", WACOM_PKGLEN_GRAPHIRE, 26202, 16325, 255, 0, TABLETPC }; static const struct wacom_features wacom_features_0xE2 = { "Wacom ISDv4 E2", WACOM_PKGLEN_TPC2FG, 26202, 16325, 255, 0, TABLETPC2FG }; static const struct wacom_features wacom_features_0xE3 = diff --git a/drivers/input/tablet/wacom_wac.h b/drivers/input/tablet/wacom_wac.h index 8590b1e8ec37..b50cf04e61a8 100644 --- a/drivers/input/tablet/wacom_wac.h +++ b/drivers/input/tablet/wacom_wac.h @@ -17,7 +17,6 @@ #define WACOM_PKGLEN_GRAPHIRE 8 #define WACOM_PKGLEN_BBFUN 9 #define WACOM_PKGLEN_INTUOS 10 -#define WACOM_PKGLEN_PENABLED 8 #define WACOM_PKGLEN_TPC1FG 5 #define WACOM_PKGLEN_TPC2FG 14 -- cgit v1.2.3 From 5bc923c505926af927d4f3011da92c243787d6a7 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Fri, 5 Mar 2010 00:31:33 -0800 Subject: Input: gamecon - fix off by one range check It should be >= GC_MAX not > GC_MAX. Signed-off-by: Dan Carpenter Signed-off-by: Dmitry Torokhov --- drivers/input/joystick/gamecon.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/input') diff --git a/drivers/input/joystick/gamecon.c b/drivers/input/joystick/gamecon.c index ae998d99a5ae..7a55714a1486 100644 --- a/drivers/input/joystick/gamecon.c +++ b/drivers/input/joystick/gamecon.c @@ -819,7 +819,7 @@ static int __init gc_setup_pad(struct gc *gc, int idx, int pad_type) int i; int err; - if (pad_type < 1 || pad_type > GC_MAX) { + if (pad_type < 1 || pad_type >= GC_MAX) { pr_err("Pad type %d unknown\n", pad_type); return -EINVAL; } -- cgit v1.2.3 From 776943fd6f104a6e8457dc95a17282e69e963666 Mon Sep 17 00:00:00 2001 From: Ping Cheng Date: Thu, 4 Mar 2010 21:50:59 -0800 Subject: Input: wacom - merge out and in prox events Process out and in prox events for Graphire and Tablet PC devices in the same loop to simplify the data parsing logic. Signed-off-by: Ping Cheng Signed-off-by: Dmitry Torokhov --- drivers/input/tablet/wacom_wac.c | 163 ++++++++++++++------------------------- 1 file changed, 59 insertions(+), 104 deletions(-) (limited to 'drivers/input') diff --git a/drivers/input/tablet/wacom_wac.c b/drivers/input/tablet/wacom_wac.c index 4a852d815c68..b3ba3437a2eb 100644 --- a/drivers/input/tablet/wacom_wac.c +++ b/drivers/input/tablet/wacom_wac.c @@ -155,19 +155,19 @@ static int wacom_graphire_irq(struct wacom_wac *wacom, void *wcombo) { struct wacom_features *features = &wacom->features; unsigned char *data = wacom->data; - int x, y, rw; - static int penData = 0; + int x, y, prox; + int rw = 0; + int retval = 0; if (data[0] != WACOM_REPORT_PENABLED) { dbg("wacom_graphire_irq: received unknown report #%d", data[0]); - return 0; + goto exit; } - if (data[1] & 0x80) { - /* in prox and not a pad data */ - penData = 1; - - switch ((data[1] >> 5) & 3) { + prox = data[1] & 0x80; + if (prox || wacom->id[0]) { + if (prox) { + switch ((data[1] >> 5) & 3) { case 0: /* Pen */ wacom->tool[0] = BTN_TOOL_PEN; @@ -181,23 +181,13 @@ static int wacom_graphire_irq(struct wacom_wac *wacom, void *wcombo) case 2: /* Mouse with wheel */ wacom_report_key(wcombo, BTN_MIDDLE, data[1] & 0x04); - if (features->type == WACOM_G4 || features->type == WACOM_MO) { - rw = data[7] & 0x04 ? (data[7] & 0x03)-4 : (data[7] & 0x03); - wacom_report_rel(wcombo, REL_WHEEL, -rw); - } else - wacom_report_rel(wcombo, REL_WHEEL, -(signed char) data[6]); /* fall through */ case 3: /* Mouse without wheel */ wacom->tool[0] = BTN_TOOL_MOUSE; wacom->id[0] = CURSOR_DEVICE_ID; - wacom_report_key(wcombo, BTN_LEFT, data[1] & 0x01); - wacom_report_key(wcombo, BTN_RIGHT, data[1] & 0x02); - if (features->type == WACOM_G4 || features->type == WACOM_MO) - wacom_report_abs(wcombo, ABS_DISTANCE, data[6] & 0x3f); - else - wacom_report_abs(wcombo, ABS_DISTANCE, data[7] & 0x3f); break; + } } x = wacom_le16_to_cpu(&data[2]); y = wacom_le16_to_cpu(&data[4]); @@ -208,36 +198,32 @@ static int wacom_graphire_irq(struct wacom_wac *wacom, void *wcombo) wacom_report_key(wcombo, BTN_TOUCH, data[1] & 0x01); wacom_report_key(wcombo, BTN_STYLUS, data[1] & 0x02); wacom_report_key(wcombo, BTN_STYLUS2, data[1] & 0x04); - } - wacom_report_abs(wcombo, ABS_MISC, wacom->id[0]); /* report tool id */ - wacom_report_key(wcombo, wacom->tool[0], 1); - } else if (wacom->id[0]) { - wacom_report_abs(wcombo, ABS_X, 0); - wacom_report_abs(wcombo, ABS_Y, 0); - if (wacom->tool[0] == BTN_TOOL_MOUSE) { - wacom_report_key(wcombo, BTN_LEFT, 0); - wacom_report_key(wcombo, BTN_RIGHT, 0); - wacom_report_abs(wcombo, ABS_DISTANCE, 0); } else { - wacom_report_abs(wcombo, ABS_PRESSURE, 0); - wacom_report_key(wcombo, BTN_TOUCH, 0); - wacom_report_key(wcombo, BTN_STYLUS, 0); - wacom_report_key(wcombo, BTN_STYLUS2, 0); + wacom_report_key(wcombo, BTN_LEFT, data[1] & 0x01); + wacom_report_key(wcombo, BTN_RIGHT, data[1] & 0x02); + if (features->type == WACOM_G4 || + features->type == WACOM_MO) { + wacom_report_abs(wcombo, ABS_DISTANCE, data[6] & 0x3f); + rw = (signed)(data[7] & 0x04) - (data[7] & 0x03); + } else { + wacom_report_abs(wcombo, ABS_DISTANCE, data[7] & 0x3f); + rw = -(signed)data[6]; + } + wacom_report_rel(wcombo, REL_WHEEL, rw); } - wacom->id[0] = 0; - wacom_report_abs(wcombo, ABS_MISC, 0); /* reset tool id */ - wacom_report_key(wcombo, wacom->tool[0], 0); + + if (!prox) + wacom->id[0] = 0; + wacom_report_abs(wcombo, ABS_MISC, wacom->id[0]); /* report tool id */ + wacom_report_key(wcombo, wacom->tool[0], prox); + wacom_input_sync(wcombo); /* sync last event */ } /* send pad data */ switch (features->type) { case WACOM_G4: - if (data[7] & 0xf8) { - if (penData) { - wacom_input_sync(wcombo); /* sync last event */ - if (!wacom->id[0]) - penData = 0; - } + prox = data[7] & 0xf8; + if (prox || wacom->id[1]) { wacom->id[1] = PAD_DEVICE_ID; wacom_report_key(wcombo, BTN_0, (data[7] & 0x40)); wacom_report_key(wcombo, BTN_4, (data[7] & 0x80)); @@ -245,29 +231,16 @@ static int wacom_graphire_irq(struct wacom_wac *wacom, void *wcombo) wacom_report_rel(wcombo, REL_WHEEL, rw); wacom_report_key(wcombo, BTN_TOOL_FINGER, 0xf0); wacom_report_abs(wcombo, ABS_MISC, wacom->id[1]); - wacom_input_event(wcombo, EV_MSC, MSC_SERIAL, 0xf0); - } else if (wacom->id[1]) { - if (penData) { - wacom_input_sync(wcombo); /* sync last event */ - if (!wacom->id[0]) - penData = 0; - } - wacom->id[1] = 0; - wacom_report_key(wcombo, BTN_0, (data[7] & 0x40)); - wacom_report_key(wcombo, BTN_4, (data[7] & 0x80)); - wacom_report_rel(wcombo, REL_WHEEL, 0); - wacom_report_key(wcombo, BTN_TOOL_FINGER, 0); - wacom_report_abs(wcombo, ABS_MISC, 0); + if (!prox) + wacom->id[1] = 0; + wacom_report_abs(wcombo, ABS_MISC, wacom->id[1]); wacom_input_event(wcombo, EV_MSC, MSC_SERIAL, 0xf0); } + retval = 1; break; case WACOM_MO: - if ((data[7] & 0xf8) || (data[8] & 0xff)) { - if (penData) { - wacom_input_sync(wcombo); /* sync last event */ - if (!wacom->id[0]) - penData = 0; - } + prox = (data[7] & 0xf8) || data[8]; + if (prox || wacom->id[1]) { wacom->id[1] = PAD_DEVICE_ID; wacom_report_key(wcombo, BTN_0, (data[7] & 0x08)); wacom_report_key(wcombo, BTN_1, (data[7] & 0x20)); @@ -275,27 +248,16 @@ static int wacom_graphire_irq(struct wacom_wac *wacom, void *wcombo) wacom_report_key(wcombo, BTN_5, (data[7] & 0x40)); wacom_report_abs(wcombo, ABS_WHEEL, (data[8] & 0x7f)); wacom_report_key(wcombo, BTN_TOOL_FINGER, 0xf0); + if (!prox) + wacom->id[1] = 0; wacom_report_abs(wcombo, ABS_MISC, wacom->id[1]); wacom_input_event(wcombo, EV_MSC, MSC_SERIAL, 0xf0); - } else if (wacom->id[1]) { - if (penData) { - wacom_input_sync(wcombo); /* sync last event */ - if (!wacom->id[0]) - penData = 0; - } - wacom->id[1] = 0; - wacom_report_key(wcombo, BTN_0, (data[7] & 0x08)); - wacom_report_key(wcombo, BTN_1, (data[7] & 0x20)); - wacom_report_key(wcombo, BTN_4, (data[7] & 0x10)); - wacom_report_key(wcombo, BTN_5, (data[7] & 0x40)); - wacom_report_abs(wcombo, ABS_WHEEL, (data[8] & 0x7f)); - wacom_report_key(wcombo, BTN_TOOL_FINGER, 0); - wacom_report_abs(wcombo, ABS_MISC, 0); - wacom_input_event(wcombo, EV_MSC, MSC_SERIAL, 0xf0); } + retval = 1; break; } - return 1; +exit: + return retval; } static int wacom_intuos_inout(struct wacom_wac *wacom, void *wcombo) @@ -636,9 +598,9 @@ static int wacom_intuos_irq(struct wacom_wac *wacom, void *wcombo) static void wacom_tpc_finger_in(struct wacom_wac *wacom, void *wcombo, char *data, int idx) { wacom_report_abs(wcombo, ABS_X, - (data[2 + idx * 2] & 0xff) | ((data[3 + idx * 2] & 0x7f) << 8)); + data[2 + idx * 2] | ((data[3 + idx * 2] & 0x7f) << 8)); wacom_report_abs(wcombo, ABS_Y, - (data[6 + idx * 2] & 0xff) | ((data[7 + idx * 2] & 0x7f) << 8)); + data[6 + idx * 2] | ((data[7 + idx * 2] & 0x7f) << 8)); wacom_report_abs(wcombo, ABS_MISC, wacom->id[0]); wacom_report_key(wcombo, wacom->tool[idx], 1); if (idx) @@ -782,31 +744,24 @@ static int wacom_tpc_irq(struct wacom_wac *wacom, void *wcombo) touchInProx = 0; - if (prox) { /* in prox */ - if (!wacom->id[0]) { - /* Going into proximity select tool */ - wacom->tool[0] = (data[1] & 0x0c) ? BTN_TOOL_RUBBER : BTN_TOOL_PEN; - if (wacom->tool[0] == BTN_TOOL_PEN) - wacom->id[0] = STYLUS_DEVICE_ID; - else - wacom->id[0] = ERASER_DEVICE_ID; - } - wacom_report_key(wcombo, BTN_STYLUS, data[1] & 0x02); - wacom_report_key(wcombo, BTN_STYLUS2, data[1] & 0x10); - wacom_report_abs(wcombo, ABS_X, wacom_le16_to_cpu(&data[2])); - wacom_report_abs(wcombo, ABS_Y, wacom_le16_to_cpu(&data[4])); - pressure = ((data[7] & 0x01) << 8) | data[6]; - if (pressure < 0) - pressure = features->pressure_max + pressure + 1; - wacom_report_abs(wcombo, ABS_PRESSURE, pressure); - wacom_report_key(wcombo, BTN_TOUCH, data[1] & 0x05); - } else { - wacom_report_abs(wcombo, ABS_X, 0); - wacom_report_abs(wcombo, ABS_Y, 0); - wacom_report_abs(wcombo, ABS_PRESSURE, 0); - wacom_report_key(wcombo, BTN_STYLUS, 0); - wacom_report_key(wcombo, BTN_STYLUS2, 0); - wacom_report_key(wcombo, BTN_TOUCH, 0); + if (!wacom->id[0]) { /* first in prox */ + /* Going into proximity select tool */ + wacom->tool[0] = (data[1] & 0x0c) ? BTN_TOOL_RUBBER : BTN_TOOL_PEN; + if (wacom->tool[0] == BTN_TOOL_PEN) + wacom->id[0] = STYLUS_DEVICE_ID; + else + wacom->id[0] = ERASER_DEVICE_ID; + } + wacom_report_key(wcombo, BTN_STYLUS, data[1] & 0x02); + wacom_report_key(wcombo, BTN_STYLUS2, data[1] & 0x10); + wacom_report_abs(wcombo, ABS_X, wacom_le16_to_cpu(&data[2])); + wacom_report_abs(wcombo, ABS_Y, wacom_le16_to_cpu(&data[4])); + pressure = ((data[7] & 0x01) << 8) | data[6]; + if (pressure < 0) + pressure = features->pressure_max + pressure + 1; + wacom_report_abs(wcombo, ABS_PRESSURE, pressure); + wacom_report_key(wcombo, BTN_TOUCH, data[1] & 0x05); + if (!prox) { /* out-prox */ wacom->id[0] = 0; /* pen is out so touch can be enabled now */ touchInProx = 1; -- cgit v1.2.3 From 2a83319182afe9ba7d958180b3bd3a32a9e3d1be Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Fri, 5 Mar 2010 13:44:26 -0800 Subject: input/mc13783-ts: don't use deprecated mc13783 API calls MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit mc13783_ackirq is deprecated, use the drop in replacement mc13783_irq_ack. Signed-off-by: Uwe Kleine-König Cc: Alessandro Zummo Cc: Paul Gortmaker Cc: Valentin Longchamp Cc: Sascha Hauer Cc: Samuel Ortiz Acked-by: Dmitry Torokhov Cc: Luotao Fu Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/input/touchscreen/mc13783_ts.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/input') diff --git a/drivers/input/touchscreen/mc13783_ts.c b/drivers/input/touchscreen/mc13783_ts.c index be115b3b65eb..be54fd639aca 100644 --- a/drivers/input/touchscreen/mc13783_ts.c +++ b/drivers/input/touchscreen/mc13783_ts.c @@ -44,7 +44,7 @@ static irqreturn_t mc13783_ts_handler(int irq, void *data) { struct mc13783_ts_priv *priv = data; - mc13783_ackirq(priv->mc13783, irq); + mc13783_irq_ack(priv->mc13783, irq); /* * Kick off reading coordinates. Note that if work happens already @@ -135,7 +135,7 @@ static int mc13783_ts_open(struct input_dev *dev) mc13783_lock(priv->mc13783); - mc13783_ackirq(priv->mc13783, MC13783_IRQ_TS); + mc13783_irq_ack(priv->mc13783, MC13783_IRQ_TS); ret = mc13783_irq_request(priv->mc13783, MC13783_IRQ_TS, mc13783_ts_handler, MC13783_TS_NAME, priv); -- cgit v1.2.3 From 866a98ae6e1a9768cd25fe1185481569c7e4b4a9 Mon Sep 17 00:00:00 2001 From: Haojian Zhuang Date: Tue, 15 Dec 2009 16:06:17 -0500 Subject: input: Enable touch on 88pm860x Enable touchscreen driver for the 88pm860x multi function core. Signed-off-by: Haojian Zhuang Acked-by: Dmitry Torokhov Signed-off-by: Samuel Ortiz --- drivers/input/touchscreen/88pm860x-ts.c | 241 ++++++++++++++++++++++++++++++++ drivers/input/touchscreen/Kconfig | 12 ++ drivers/input/touchscreen/Makefile | 1 + include/linux/mfd/88pm860x.h | 1 + 4 files changed, 255 insertions(+) create mode 100644 drivers/input/touchscreen/88pm860x-ts.c (limited to 'drivers/input') diff --git a/drivers/input/touchscreen/88pm860x-ts.c b/drivers/input/touchscreen/88pm860x-ts.c new file mode 100644 index 000000000000..56254d2a1f6e --- /dev/null +++ b/drivers/input/touchscreen/88pm860x-ts.c @@ -0,0 +1,241 @@ +/* + * Touchscreen driver for Marvell 88PM860x + * + * Copyright (C) 2009 Marvell International Ltd. + * Haojian Zhuang + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#include +#include +#include +#include +#include +#include + +#define MEAS_LEN (8) +#define ACCURATE_BIT (12) + +/* touch register */ +#define MEAS_EN3 (0x52) + +#define MEAS_TSIX_1 (0x8D) +#define MEAS_TSIX_2 (0x8E) +#define MEAS_TSIY_1 (0x8F) +#define MEAS_TSIY_2 (0x90) +#define MEAS_TSIZ1_1 (0x91) +#define MEAS_TSIZ1_2 (0x92) +#define MEAS_TSIZ2_1 (0x93) +#define MEAS_TSIZ2_2 (0x94) + +/* bit definitions of touch */ +#define MEAS_PD_EN (1 << 3) +#define MEAS_TSIX_EN (1 << 4) +#define MEAS_TSIY_EN (1 << 5) +#define MEAS_TSIZ1_EN (1 << 6) +#define MEAS_TSIZ2_EN (1 << 7) + +struct pm860x_touch { + struct input_dev *idev; + struct i2c_client *i2c; + struct pm860x_chip *chip; + int irq; + int res_x; /* resistor of Xplate */ +}; + +static irqreturn_t pm860x_touch_handler(int irq, void *data) +{ + struct pm860x_touch *touch = data; + struct pm860x_chip *chip = touch->chip; + unsigned char buf[MEAS_LEN]; + int x, y, pen_down; + int z1, z2, rt = 0; + int ret; + + pm860x_mask_irq(chip, irq); + ret = pm860x_bulk_read(touch->i2c, MEAS_TSIX_1, MEAS_LEN, buf); + if (ret < 0) + goto out; + + pen_down = buf[1] & (1 << 6); + x = ((buf[0] & 0xFF) << 4) | (buf[1] & 0x0F); + y = ((buf[2] & 0xFF) << 4) | (buf[3] & 0x0F); + z1 = ((buf[4] & 0xFF) << 4) | (buf[5] & 0x0F); + z2 = ((buf[6] & 0xFF) << 4) | (buf[7] & 0x0F); + + if (pen_down) { + if ((x != 0) && (z1 != 0) && (touch->res_x != 0)) { + rt = z2 / z1 - 1; + rt = (rt * touch->res_x * x) >> ACCURATE_BIT; + dev_dbg(chip->dev, "z1:%d, z2:%d, rt:%d\n", + z1, z2, rt); + } + input_report_abs(touch->idev, ABS_X, x); + input_report_abs(touch->idev, ABS_Y, y); + input_report_abs(touch->idev, ABS_PRESSURE, rt); + input_report_key(touch->idev, BTN_TOUCH, 1); + dev_dbg(chip->dev, "pen down at [%d, %d].\n", x, y); + } else { + input_report_abs(touch->idev, ABS_PRESSURE, 0); + input_report_key(touch->idev, BTN_TOUCH, 0); + dev_dbg(chip->dev, "pen release\n"); + } + input_sync(touch->idev); + pm860x_unmask_irq(chip, irq); + +out: + return IRQ_HANDLED; +} + +static int pm860x_touch_open(struct input_dev *dev) +{ + struct pm860x_touch *touch = input_get_drvdata(dev); + struct pm860x_chip *chip = touch->chip; + int data, ret; + + data = MEAS_PD_EN | MEAS_TSIX_EN | MEAS_TSIY_EN + | MEAS_TSIZ1_EN | MEAS_TSIZ2_EN; + ret = pm860x_set_bits(touch->i2c, MEAS_EN3, data, data); + if (ret < 0) + goto out; + pm860x_unmask_irq(chip, touch->irq); + return 0; +out: + return ret; +} + +static void pm860x_touch_close(struct input_dev *dev) +{ + struct pm860x_touch *touch = input_get_drvdata(dev); + struct pm860x_chip *chip = touch->chip; + int data; + + data = MEAS_PD_EN | MEAS_TSIX_EN | MEAS_TSIY_EN + | MEAS_TSIZ1_EN | MEAS_TSIZ2_EN; + pm860x_set_bits(touch->i2c, MEAS_EN3, data, 0); + pm860x_mask_irq(chip, touch->irq); +} + +static int __devinit pm860x_touch_probe(struct platform_device *pdev) +{ + struct pm860x_chip *chip = dev_get_drvdata(pdev->dev.parent); + struct pm860x_platform_data *pm860x_pdata = \ + pdev->dev.parent->platform_data; + struct pm860x_touch_pdata *pdata = NULL; + struct pm860x_touch *touch; + int irq, ret; + + irq = platform_get_irq(pdev, 0); + if (irq < 0) { + dev_err(&pdev->dev, "No IRQ resource!\n"); + return -EINVAL; + } + + if (!pm860x_pdata) { + dev_err(&pdev->dev, "platform data is missing\n"); + return -EINVAL; + } + + pdata = pm860x_pdata->touch; + if (!pdata) { + dev_err(&pdev->dev, "touchscreen data is missing\n"); + return -EINVAL; + } + + touch = kzalloc(sizeof(struct pm860x_touch), GFP_KERNEL); + if (touch == NULL) + return -ENOMEM; + dev_set_drvdata(&pdev->dev, touch); + + touch->idev = input_allocate_device(); + if (touch->idev == NULL) { + dev_err(&pdev->dev, "Failed to allocate input device!\n"); + ret = -ENOMEM; + goto out; + } + + touch->idev->name = "88pm860x-touch"; + touch->idev->phys = "88pm860x/input0"; + touch->idev->id.bustype = BUS_I2C; + touch->idev->dev.parent = &pdev->dev; + touch->idev->open = pm860x_touch_open; + touch->idev->close = pm860x_touch_close; + touch->chip = chip; + touch->i2c = (chip->id == CHIP_PM8607) ? chip->client : chip->companion; + touch->irq = irq; + touch->res_x = pdata->res_x; + input_set_drvdata(touch->idev, touch); + + ret = pm860x_request_irq(chip, irq, pm860x_touch_handler, touch); + if (ret < 0) + goto out_irq; + + __set_bit(EV_ABS, touch->idev->evbit); + __set_bit(ABS_X, touch->idev->absbit); + __set_bit(ABS_Y, touch->idev->absbit); + __set_bit(ABS_PRESSURE, touch->idev->absbit); + __set_bit(EV_SYN, touch->idev->evbit); + __set_bit(EV_KEY, touch->idev->evbit); + __set_bit(BTN_TOUCH, touch->idev->keybit); + + input_set_abs_params(touch->idev, ABS_X, 0, 1 << ACCURATE_BIT, 0, 0); + input_set_abs_params(touch->idev, ABS_Y, 0, 1 << ACCURATE_BIT, 0, 0); + input_set_abs_params(touch->idev, ABS_PRESSURE, 0, 1 << ACCURATE_BIT, + 0, 0); + + ret = input_register_device(touch->idev); + if (ret < 0) { + dev_err(chip->dev, "Failed to register touch!\n"); + goto out_rg; + } + + platform_set_drvdata(pdev, touch); + return 0; +out_rg: + pm860x_free_irq(chip, irq); +out_irq: + input_free_device(touch->idev); +out: + kfree(touch); + return ret; +} + +static int __devexit pm860x_touch_remove(struct platform_device *pdev) +{ + struct pm860x_touch *touch = platform_get_drvdata(pdev); + + input_unregister_device(touch->idev); + pm860x_free_irq(touch->chip, touch->irq); + platform_set_drvdata(pdev, NULL); + kfree(touch); + return 0; +} + +static struct platform_driver pm860x_touch_driver = { + .driver = { + .name = "88pm860x-touch", + .owner = THIS_MODULE, + }, + .probe = pm860x_touch_probe, + .remove = __devexit_p(pm860x_touch_remove), +}; + +static int __init pm860x_touch_init(void) +{ + return platform_driver_register(&pm860x_touch_driver); +} +module_init(pm860x_touch_init); + +static void __exit pm860x_touch_exit(void) +{ + platform_driver_unregister(&pm860x_touch_driver); +} +module_exit(pm860x_touch_exit); + +MODULE_DESCRIPTION("Touchscreen driver for Marvell Semiconductor 88PM860x"); +MODULE_AUTHOR("Haojian Zhuang "); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:88pm860x-touch"); + diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig index 6457e060ae49..7208654a94ae 100644 --- a/drivers/input/touchscreen/Kconfig +++ b/drivers/input/touchscreen/Kconfig @@ -11,6 +11,18 @@ menuconfig INPUT_TOUCHSCREEN if INPUT_TOUCHSCREEN +config TOUCHSCREEN_88PM860X + tristate "Marvell 88PM860x touchscreen" + depends on MFD_88PM860X + help + Say Y here if you have a 88PM860x PMIC and want to enable + support for the built-in touchscreen. + + If unsure, say N. + + To compile this driver as a module, choose M here: the + module will be called 88pm860x-ts. + config TOUCHSCREEN_ADS7846 tristate "ADS7846/TSC2046 and ADS7843 based touchscreens" depends on SPI_MASTER diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile index d61a3b4def9a..7fef7d5cca23 100644 --- a/drivers/input/touchscreen/Makefile +++ b/drivers/input/touchscreen/Makefile @@ -6,6 +6,7 @@ wm97xx-ts-y := wm97xx-core.o +obj-$(CONFIG_TOUCHSCREEN_88PM860X) += 88pm860x-ts.o obj-$(CONFIG_TOUCHSCREEN_AD7877) += ad7877.o obj-$(CONFIG_TOUCHSCREEN_AD7879) += ad7879.o obj-$(CONFIG_TOUCHSCREEN_ADS7846) += ads7846.o diff --git a/include/linux/mfd/88pm860x.h b/include/linux/mfd/88pm860x.h index d7edf11784f5..80bc82a7ac96 100644 --- a/include/linux/mfd/88pm860x.h +++ b/include/linux/mfd/88pm860x.h @@ -343,6 +343,7 @@ struct pm860x_touch_pdata { int tsi_prebias; /* time, slot */ int pen_prebias; /* time, slot */ int pen_prechg; /* time, slot */ + int res_x; /* resistor of Xplate */ unsigned long flags; }; -- cgit v1.2.3 From 2afa62ea76027b00e472ddb672191e6e15425b43 Mon Sep 17 00:00:00 2001 From: Haojian Zhuang Date: Mon, 8 Feb 2010 05:02:00 -0500 Subject: mfd: Use genirq in 88pm860x Use genirq to simplify IRQ handling in 88pm860x. Remove the interface of mask/free IRQs on 88pm860x. All these work is taken by genirq. Update the touchscreen driver of 88pm860x since IRQ handling is changed. Signed-off-by: Haojian Zhuang Signed-off-by: Samuel Ortiz --- drivers/input/touchscreen/88pm860x-ts.c | 15 +- drivers/mfd/88pm860x-core.c | 408 +++++++++++++++++++++++--------- include/linux/mfd/88pm860x.h | 30 +-- 3 files changed, 311 insertions(+), 142 deletions(-) (limited to 'drivers/input') diff --git a/drivers/input/touchscreen/88pm860x-ts.c b/drivers/input/touchscreen/88pm860x-ts.c index 56254d2a1f6e..286bb490a9f2 100644 --- a/drivers/input/touchscreen/88pm860x-ts.c +++ b/drivers/input/touchscreen/88pm860x-ts.c @@ -54,7 +54,6 @@ static irqreturn_t pm860x_touch_handler(int irq, void *data) int z1, z2, rt = 0; int ret; - pm860x_mask_irq(chip, irq); ret = pm860x_bulk_read(touch->i2c, MEAS_TSIX_1, MEAS_LEN, buf); if (ret < 0) goto out; @@ -83,7 +82,6 @@ static irqreturn_t pm860x_touch_handler(int irq, void *data) dev_dbg(chip->dev, "pen release\n"); } input_sync(touch->idev); - pm860x_unmask_irq(chip, irq); out: return IRQ_HANDLED; @@ -92,7 +90,6 @@ out: static int pm860x_touch_open(struct input_dev *dev) { struct pm860x_touch *touch = input_get_drvdata(dev); - struct pm860x_chip *chip = touch->chip; int data, ret; data = MEAS_PD_EN | MEAS_TSIX_EN | MEAS_TSIY_EN @@ -100,7 +97,6 @@ static int pm860x_touch_open(struct input_dev *dev) ret = pm860x_set_bits(touch->i2c, MEAS_EN3, data, data); if (ret < 0) goto out; - pm860x_unmask_irq(chip, touch->irq); return 0; out: return ret; @@ -109,13 +105,11 @@ out: static void pm860x_touch_close(struct input_dev *dev) { struct pm860x_touch *touch = input_get_drvdata(dev); - struct pm860x_chip *chip = touch->chip; int data; data = MEAS_PD_EN | MEAS_TSIX_EN | MEAS_TSIY_EN | MEAS_TSIZ1_EN | MEAS_TSIZ2_EN; pm860x_set_bits(touch->i2c, MEAS_EN3, data, 0); - pm860x_mask_irq(chip, touch->irq); } static int __devinit pm860x_touch_probe(struct platform_device *pdev) @@ -164,11 +158,12 @@ static int __devinit pm860x_touch_probe(struct platform_device *pdev) touch->idev->close = pm860x_touch_close; touch->chip = chip; touch->i2c = (chip->id == CHIP_PM8607) ? chip->client : chip->companion; - touch->irq = irq; + touch->irq = irq + chip->irq_base; touch->res_x = pdata->res_x; input_set_drvdata(touch->idev, touch); - ret = pm860x_request_irq(chip, irq, pm860x_touch_handler, touch); + ret = request_threaded_irq(touch->irq, NULL, pm860x_touch_handler, + IRQF_ONESHOT, "touch", touch); if (ret < 0) goto out_irq; @@ -194,7 +189,7 @@ static int __devinit pm860x_touch_probe(struct platform_device *pdev) platform_set_drvdata(pdev, touch); return 0; out_rg: - pm860x_free_irq(chip, irq); + free_irq(touch->irq, touch); out_irq: input_free_device(touch->idev); out: @@ -207,7 +202,7 @@ static int __devexit pm860x_touch_remove(struct platform_device *pdev) struct pm860x_touch *touch = platform_get_drvdata(pdev); input_unregister_device(touch->idev); - pm860x_free_irq(touch->chip, touch->irq); + free_irq(touch->irq, touch); platform_set_drvdata(pdev, NULL); kfree(touch); return 0; diff --git a/drivers/mfd/88pm860x-core.c b/drivers/mfd/88pm860x-core.c index 16f0dca707a7..6a14d2b1ccf0 100644 --- a/drivers/mfd/88pm860x-core.c +++ b/drivers/mfd/88pm860x-core.c @@ -12,11 +12,14 @@ #include #include #include +#include #include #include #include #include +#define INT_STATUS_NUM 3 + char pm860x_backlight_name[][MFD_NAME_SIZE] = { "backlight-0", "backlight-1", @@ -119,6 +122,42 @@ static struct mfd_cell touch_devs[] = { .flags = IORESOURCE_IO, \ } +static struct resource power_supply_resources[] = { + { + .name = "88pm860x-power", + .start = PM8607_IRQ_CHG, + .end = PM8607_IRQ_CHG, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct mfd_cell power_devs[] = { + { + .name = "88pm860x-power", + .num_resources = 1, + .resources = &power_supply_resources[0], + .id = -1, + }, +}; + +static struct resource onkey_resources[] = { + { + .name = "88pm860x-onkey", + .start = PM8607_IRQ_ONKEY, + .end = PM8607_IRQ_ONKEY, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct mfd_cell onkey_devs[] = { + { + .name = "88pm860x-onkey", + .num_resources = 1, + .resources = &onkey_resources[0], + .id = -1, + }, +}; + static struct resource regulator_resources[] = { PM8607_REG_RESOURCE(BUCK1, BUCK1), PM8607_REG_RESOURCE(BUCK2, BUCK2), @@ -163,129 +202,224 @@ static struct mfd_cell regulator_devs[] = { PM8607_REG_DEVS(ldo14, LDO14), }; -#define CHECK_IRQ(irq) \ -do { \ - if ((irq < 0) || (irq >= PM860X_NUM_IRQ)) \ - return -EINVAL; \ -} while (0) - -/* IRQs only occur on 88PM8607 */ -int pm860x_mask_irq(struct pm860x_chip *chip, int irq) -{ - struct i2c_client *i2c = (chip->id == CHIP_PM8607) ? chip->client \ - : chip->companion; - int offset, data, ret; - - CHECK_IRQ(irq); - - offset = (irq >> 3) + PM8607_INT_MASK_1; - data = 1 << (irq % 8); - ret = pm860x_set_bits(i2c, offset, data, 0); +struct pm860x_irq_data { + int reg; + int mask_reg; + int enable; /* enable or not */ + int offs; /* bit offset in mask register */ +}; - return ret; -} -EXPORT_SYMBOL(pm860x_mask_irq); +static struct pm860x_irq_data pm860x_irqs[] = { + [PM8607_IRQ_ONKEY] = { + .reg = PM8607_INT_STATUS1, + .mask_reg = PM8607_INT_MASK_1, + .offs = 1 << 0, + }, + [PM8607_IRQ_EXTON] = { + .reg = PM8607_INT_STATUS1, + .mask_reg = PM8607_INT_MASK_1, + .offs = 1 << 1, + }, + [PM8607_IRQ_CHG] = { + .reg = PM8607_INT_STATUS1, + .mask_reg = PM8607_INT_MASK_1, + .offs = 1 << 2, + }, + [PM8607_IRQ_BAT] = { + .reg = PM8607_INT_STATUS1, + .mask_reg = PM8607_INT_MASK_1, + .offs = 1 << 3, + }, + [PM8607_IRQ_RTC] = { + .reg = PM8607_INT_STATUS1, + .mask_reg = PM8607_INT_MASK_1, + .offs = 1 << 4, + }, + [PM8607_IRQ_CC] = { + .reg = PM8607_INT_STATUS1, + .mask_reg = PM8607_INT_MASK_1, + .offs = 1 << 5, + }, + [PM8607_IRQ_VBAT] = { + .reg = PM8607_INT_STATUS2, + .mask_reg = PM8607_INT_MASK_2, + .offs = 1 << 0, + }, + [PM8607_IRQ_VCHG] = { + .reg = PM8607_INT_STATUS2, + .mask_reg = PM8607_INT_MASK_2, + .offs = 1 << 1, + }, + [PM8607_IRQ_VSYS] = { + .reg = PM8607_INT_STATUS2, + .mask_reg = PM8607_INT_MASK_2, + .offs = 1 << 2, + }, + [PM8607_IRQ_TINT] = { + .reg = PM8607_INT_STATUS2, + .mask_reg = PM8607_INT_MASK_2, + .offs = 1 << 3, + }, + [PM8607_IRQ_GPADC0] = { + .reg = PM8607_INT_STATUS2, + .mask_reg = PM8607_INT_MASK_2, + .offs = 1 << 4, + }, + [PM8607_IRQ_GPADC1] = { + .reg = PM8607_INT_STATUS2, + .mask_reg = PM8607_INT_MASK_2, + .offs = 1 << 5, + }, + [PM8607_IRQ_GPADC2] = { + .reg = PM8607_INT_STATUS2, + .mask_reg = PM8607_INT_MASK_2, + .offs = 1 << 6, + }, + [PM8607_IRQ_GPADC3] = { + .reg = PM8607_INT_STATUS2, + .mask_reg = PM8607_INT_MASK_2, + .offs = 1 << 7, + }, + [PM8607_IRQ_AUDIO_SHORT] = { + .reg = PM8607_INT_STATUS3, + .mask_reg = PM8607_INT_MASK_3, + .offs = 1 << 0, + }, + [PM8607_IRQ_PEN] = { + .reg = PM8607_INT_STATUS3, + .mask_reg = PM8607_INT_MASK_3, + .offs = 1 << 1, + }, + [PM8607_IRQ_HEADSET] = { + .reg = PM8607_INT_STATUS3, + .mask_reg = PM8607_INT_MASK_3, + .offs = 1 << 2, + }, + [PM8607_IRQ_HOOK] = { + .reg = PM8607_INT_STATUS3, + .mask_reg = PM8607_INT_MASK_3, + .offs = 1 << 3, + }, + [PM8607_IRQ_MICIN] = { + .reg = PM8607_INT_STATUS3, + .mask_reg = PM8607_INT_MASK_3, + .offs = 1 << 4, + }, + [PM8607_IRQ_CHG_FAIL] = { + .reg = PM8607_INT_STATUS3, + .mask_reg = PM8607_INT_MASK_3, + .offs = 1 << 5, + }, + [PM8607_IRQ_CHG_DONE] = { + .reg = PM8607_INT_STATUS3, + .mask_reg = PM8607_INT_MASK_3, + .offs = 1 << 6, + }, + [PM8607_IRQ_CHG_FAULT] = { + .reg = PM8607_INT_STATUS3, + .mask_reg = PM8607_INT_MASK_3, + .offs = 1 << 7, + }, +}; -int pm860x_unmask_irq(struct pm860x_chip *chip, int irq) +static inline struct pm860x_irq_data *irq_to_pm860x(struct pm860x_chip *chip, + int irq) { - struct i2c_client *i2c = (chip->id == CHIP_PM8607) ? chip->client \ - : chip->companion; - int offset, data, ret; - - CHECK_IRQ(irq); - - offset = (irq >> 3) + PM8607_INT_MASK_1; - data = 1 << (irq % 8); - ret = pm860x_set_bits(i2c, offset, data, data); - - return ret; + return &pm860x_irqs[irq - chip->irq_base]; } -EXPORT_SYMBOL(pm860x_unmask_irq); -#define INT_STATUS_NUM (3) - -static irqreturn_t pm8607_irq_thread(int irq, void *data) +static irqreturn_t pm860x_irq(int irq, void *data) { - DECLARE_BITMAP(irq_status, PM860X_NUM_IRQ); struct pm860x_chip *chip = data; - struct i2c_client *i2c = (chip->id == CHIP_PM8607) ? chip->client \ - : chip->companion; - unsigned char status_buf[INT_STATUS_NUM << 1]; - unsigned long value; - int i, ret; - - irq_status[0] = 0; - - /* read out status register */ - ret = pm860x_bulk_read(i2c, PM8607_INT_STATUS1, - INT_STATUS_NUM << 1, status_buf); - if (ret < 0) - goto out; - if (chip->irq_mode) { - /* 0, clear by read. 1, clear by write */ - ret = pm860x_bulk_write(i2c, PM8607_INT_STATUS1, - INT_STATUS_NUM, status_buf); - if (ret < 0) - goto out; - } - - /* clear masked interrupt status */ - for (i = 0, value = 0; i < INT_STATUS_NUM; i++) { - status_buf[i] &= status_buf[i + INT_STATUS_NUM]; - irq_status[0] |= status_buf[i] << (i * 8); - } - - while (!bitmap_empty(irq_status, PM860X_NUM_IRQ)) { - irq = find_first_bit(irq_status, PM860X_NUM_IRQ); - clear_bit(irq, irq_status); - dev_dbg(chip->dev, "Servicing IRQ #%d\n", irq); - - mutex_lock(&chip->irq_lock); - if (chip->irq[irq].handler) - chip->irq[irq].handler(irq, chip->irq[irq].data); - else { - pm860x_mask_irq(chip, irq); - dev_err(chip->dev, "Nobody cares IRQ %d. " - "Now mask it.\n", irq); - for (i = 0; i < (INT_STATUS_NUM << 1); i++) { - dev_err(chip->dev, "status[%d]:%x\n", i, - status_buf[i]); - } + struct pm860x_irq_data *irq_data; + struct i2c_client *i2c; + int read_reg = -1, value = 0; + int i; + + i2c = (chip->id == CHIP_PM8607) ? chip->client : chip->companion; + for (i = 0; i < ARRAY_SIZE(pm860x_irqs); i++) { + irq_data = &pm860x_irqs[i]; + if (read_reg != irq_data->reg) { + read_reg = irq_data->reg; + value = pm860x_reg_read(i2c, irq_data->reg); } - mutex_unlock(&chip->irq_lock); + if (value & irq_data->enable) + handle_nested_irq(chip->irq_base + i); } -out: return IRQ_HANDLED; } -int pm860x_request_irq(struct pm860x_chip *chip, int irq, - irq_handler_t handler, void *data) +static void pm860x_irq_lock(unsigned int irq) { - CHECK_IRQ(irq); - if (!handler) - return -EINVAL; + struct pm860x_chip *chip = get_irq_chip_data(irq); mutex_lock(&chip->irq_lock); - chip->irq[irq].handler = handler; - chip->irq[irq].data = data; - mutex_unlock(&chip->irq_lock); - - return 0; } -EXPORT_SYMBOL(pm860x_request_irq); -int pm860x_free_irq(struct pm860x_chip *chip, int irq) +static void pm860x_irq_sync_unlock(unsigned int irq) { - CHECK_IRQ(irq); + struct pm860x_chip *chip = get_irq_chip_data(irq); + struct pm860x_irq_data *irq_data; + struct i2c_client *i2c; + static unsigned char cached[3] = {0x0, 0x0, 0x0}; + unsigned char mask[3]; + int i; + + i2c = (chip->id == CHIP_PM8607) ? chip->client : chip->companion; + /* Load cached value. In initial, all IRQs are masked */ + for (i = 0; i < 3; i++) + mask[i] = cached[i]; + for (i = 0; i < ARRAY_SIZE(pm860x_irqs); i++) { + irq_data = &pm860x_irqs[i]; + switch (irq_data->mask_reg) { + case PM8607_INT_MASK_1: + mask[0] &= ~irq_data->offs; + mask[0] |= irq_data->enable; + break; + case PM8607_INT_MASK_2: + mask[1] &= ~irq_data->offs; + mask[1] |= irq_data->enable; + break; + case PM8607_INT_MASK_3: + mask[2] &= ~irq_data->offs; + mask[2] |= irq_data->enable; + break; + default: + dev_err(chip->dev, "wrong IRQ\n"); + break; + } + } + /* update mask into registers */ + for (i = 0; i < 3; i++) { + if (mask[i] != cached[i]) { + cached[i] = mask[i]; + pm860x_reg_write(i2c, PM8607_INT_MASK_1 + i, mask[i]); + } + } - mutex_lock(&chip->irq_lock); - chip->irq[irq].handler = NULL; - chip->irq[irq].data = NULL; mutex_unlock(&chip->irq_lock); +} - return 0; +static void pm860x_irq_enable(unsigned int irq) +{ + struct pm860x_chip *chip = get_irq_chip_data(irq); + pm860x_irqs[irq - chip->irq_base].enable + = pm860x_irqs[irq - chip->irq_base].offs; } -EXPORT_SYMBOL(pm860x_free_irq); + +static void pm860x_irq_disable(unsigned int irq) +{ + struct pm860x_chip *chip = get_irq_chip_data(irq); + pm860x_irqs[irq - chip->irq_base].enable = 0; +} + +static struct irq_chip pm860x_irq_chip = { + .name = "88pm860x", + .bus_lock = pm860x_irq_lock, + .bus_sync_unlock = pm860x_irq_sync_unlock, + .enable = pm860x_irq_enable, + .disable = pm860x_irq_disable, +}; static int __devinit device_gpadc_init(struct pm860x_chip *chip, struct pm860x_platform_data *pdata) @@ -348,9 +482,15 @@ static int __devinit device_irq_init(struct pm860x_chip *chip, struct i2c_client *i2c = (chip->id == CHIP_PM8607) ? chip->client \ : chip->companion; unsigned char status_buf[INT_STATUS_NUM]; - int data, mask, ret = -EINVAL; + unsigned long flags = IRQF_TRIGGER_FALLING | IRQF_ONESHOT; + struct irq_desc *desc; + int i, data, mask, ret = -EINVAL; + int __irq; - mutex_init(&chip->irq_lock); + if (!pdata || !pdata->irq_base) { + dev_warn(chip->dev, "No interrupt support on IRQ base\n"); + return -EINVAL; + } mask = PM8607_B0_MISC1_INV_INT | PM8607_B0_MISC1_INT_CLEAR | PM8607_B0_MISC1_INT_MASK; @@ -389,25 +529,45 @@ static int __devinit device_irq_init(struct pm860x_chip *chip, if (ret < 0) goto out; - memset(chip->irq, 0, sizeof(struct pm860x_irq) * PM860X_NUM_IRQ); - - ret = request_threaded_irq(i2c->irq, NULL, pm8607_irq_thread, - IRQF_ONESHOT | IRQF_TRIGGER_LOW, - "88PM8607", chip); - if (ret < 0) { - dev_err(chip->dev, "Failed to request IRQ #%d.\n", i2c->irq); + mutex_init(&chip->irq_lock); + chip->irq_base = pdata->irq_base; + chip->core_irq = i2c->irq; + if (!chip->core_irq) goto out; + + desc = irq_to_desc(chip->core_irq); + + /* register IRQ by genirq */ + for (i = 0; i < ARRAY_SIZE(pm860x_irqs); i++) { + __irq = i + chip->irq_base; + set_irq_chip_data(__irq, chip); + set_irq_chip_and_handler(__irq, &pm860x_irq_chip, + handle_edge_irq); + set_irq_nested_thread(__irq, 1); +#ifdef CONFIG_ARM + set_irq_flags(__irq, IRQF_VALID); +#else + set_irq_noprobe(__irq); +#endif } - chip->chip_irq = i2c->irq; + + ret = request_threaded_irq(chip->core_irq, NULL, pm860x_irq, flags, + "88pm860x", chip); + if (ret) { + dev_err(chip->dev, "Failed to request IRQ: %d\n", ret); + chip->core_irq = 0; + } + return 0; out: + chip->core_irq = 0; return ret; } static void __devexit device_irq_exit(struct pm860x_chip *chip) { - if (chip->chip_irq >= 0) - free_irq(chip->chip_irq, chip); + if (chip->core_irq) + free_irq(chip->core_irq, chip); } static void __devinit device_8606_init(struct pm860x_chip *chip, @@ -513,6 +673,26 @@ static void __devinit device_8607_init(struct pm860x_chip *chip, goto out_dev; } } + + if (pdata && pdata->power) { + ret = mfd_add_devices(chip->dev, 0, &power_devs[0], + ARRAY_SIZE(power_devs), + &power_supply_resources[0], 0); + if (ret < 0) { + dev_err(chip->dev, "Failed to add power supply " + "subdev\n"); + goto out_dev; + } + } + + ret = mfd_add_devices(chip->dev, 0, &onkey_devs[0], + ARRAY_SIZE(onkey_devs), + &onkey_resources[0], 0); + if (ret < 0) { + dev_err(chip->dev, "Failed to add onkey subdev\n"); + goto out_dev; + } + return; out_dev: mfd_remove_devices(chip->dev); @@ -524,7 +704,7 @@ out: int pm860x_device_init(struct pm860x_chip *chip, struct pm860x_platform_data *pdata) { - chip->chip_irq = -EINVAL; + chip->core_irq = 0; switch (chip->id) { case CHIP_PM8606: diff --git a/include/linux/mfd/88pm860x.h b/include/linux/mfd/88pm860x.h index 80bc82a7ac96..73f92c5feea2 100644 --- a/include/linux/mfd/88pm860x.h +++ b/include/linux/mfd/88pm860x.h @@ -262,12 +262,13 @@ enum { /* Interrupt Number in 88PM8607 */ enum { - PM8607_IRQ_ONKEY = 0, + PM8607_IRQ_ONKEY, PM8607_IRQ_EXTON, PM8607_IRQ_CHG, PM8607_IRQ_BAT, PM8607_IRQ_RTC, - PM8607_IRQ_VBAT = 8, + PM8607_IRQ_CC, + PM8607_IRQ_VBAT, PM8607_IRQ_VCHG, PM8607_IRQ_VSYS, PM8607_IRQ_TINT, @@ -275,7 +276,7 @@ enum { PM8607_IRQ_GPADC1, PM8607_IRQ_GPADC2, PM8607_IRQ_GPADC3, - PM8607_IRQ_AUDIO_SHORT = 16, + PM8607_IRQ_AUDIO_SHORT, PM8607_IRQ_PEN, PM8607_IRQ_HEADSET, PM8607_IRQ_HOOK, @@ -291,26 +292,19 @@ enum { PM8607_CHIP_B0 = 0x48, }; -#define PM860X_NUM_IRQ 24 - -struct pm860x_irq { - irq_handler_t handler; - void *data; -}; - struct pm860x_chip { struct device *dev; struct mutex io_lock; struct mutex irq_lock; struct i2c_client *client; struct i2c_client *companion; /* companion chip client */ - struct pm860x_irq irq[PM860X_NUM_IRQ]; int buck3_double; /* DVC ramp slope double */ unsigned short companion_addr; int id; int irq_mode; - int chip_irq; + int irq_base; + int core_irq; unsigned char chip_version; }; @@ -347,14 +341,20 @@ struct pm860x_touch_pdata { unsigned long flags; }; +struct pm860x_power_pdata { + unsigned fast_charge; /* charge current */ +}; + struct pm860x_platform_data { struct pm860x_backlight_pdata *backlight; struct pm860x_led_pdata *led; struct pm860x_touch_pdata *touch; + struct pm860x_power_pdata *power; unsigned short companion_addr; /* I2C address of companion chip */ int i2c_port; /* Controlled by GI2C or PI2C */ int irq_mode; /* Clear interrupt by read/write(0/1) */ + int irq_base; /* IRQ base number of 88pm860x */ struct regulator_init_data *regulator[PM8607_MAX_REGULATOR]; }; @@ -368,12 +368,6 @@ extern int pm860x_bulk_write(struct i2c_client *, int, int, unsigned char *); extern int pm860x_set_bits(struct i2c_client *, int, unsigned char, unsigned char); -extern int pm860x_mask_irq(struct pm860x_chip *, int); -extern int pm860x_unmask_irq(struct pm860x_chip *, int); -extern int pm860x_request_irq(struct pm860x_chip *, int, - irq_handler_t handler, void *); -extern int pm860x_free_irq(struct pm860x_chip *, int); - extern int pm860x_device_init(struct pm860x_chip *chip, struct pm860x_platform_data *pdata); extern void pm860x_device_exit(struct pm860x_chip *chip); -- cgit v1.2.3 From 6985403138b74ad28c8ddac8baf88869556bec9a Mon Sep 17 00:00:00 2001 From: Haojian Zhuang Date: Wed, 3 Feb 2010 15:40:59 -0500 Subject: input: Support onkey in 88pm860x Signed-off-by: Haojian Zhuang Acked-by: Dmitry Torokhov Signed-off-by: Samuel Ortiz --- drivers/input/misc/88pm860x_onkey.c | 155 ++++++++++++++++++++++++++++++++++++ drivers/input/misc/Kconfig | 10 +++ drivers/input/misc/Makefile | 1 + 3 files changed, 166 insertions(+) create mode 100644 drivers/input/misc/88pm860x_onkey.c (limited to 'drivers/input') diff --git a/drivers/input/misc/88pm860x_onkey.c b/drivers/input/misc/88pm860x_onkey.c new file mode 100644 index 000000000000..69a48e8701b9 --- /dev/null +++ b/drivers/input/misc/88pm860x_onkey.c @@ -0,0 +1,155 @@ +/* + * 88pm860x_onkey.c - Marvell 88PM860x ONKEY driver + * + * Copyright (C) 2009-2010 Marvell International Ltd. + * Haojian Zhuang + * + * This file is subject to the terms and conditions of the GNU General + * Public License. See the file "COPYING" in the main directory of this + * archive for more details. + * + * 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 + */ + +#include +#include +#include +#include +#include +#include +#include + +#define PM8607_WAKEUP 0x0b + +#define LONG_ONKEY_EN (1 << 1) +#define ONKEY_STATUS (1 << 0) + +struct pm860x_onkey_info { + struct input_dev *idev; + struct pm860x_chip *chip; + struct i2c_client *i2c; + struct device *dev; + int irq; +}; + +/* 88PM860x gives us an interrupt when ONKEY is held */ +static irqreturn_t pm860x_onkey_handler(int irq, void *data) +{ + struct pm860x_onkey_info *info = data; + int ret; + + ret = pm860x_reg_read(info->i2c, PM8607_STATUS_2); + ret &= ONKEY_STATUS; + input_report_key(info->idev, KEY_POWER, ret); + input_sync(info->idev); + + /* Enable 8-second long onkey detection */ + pm860x_set_bits(info->i2c, PM8607_WAKEUP, 3, LONG_ONKEY_EN); + return IRQ_HANDLED; +} + +static int __devinit pm860x_onkey_probe(struct platform_device *pdev) +{ + struct pm860x_chip *chip = dev_get_drvdata(pdev->dev.parent); + struct pm860x_onkey_info *info; + int irq, ret; + + irq = platform_get_irq(pdev, 0); + if (irq < 0) { + dev_err(&pdev->dev, "No IRQ resource!\n"); + return -EINVAL; + } + + info = kzalloc(sizeof(struct pm860x_onkey_info), GFP_KERNEL); + if (!info) + return -ENOMEM; + info->chip = chip; + info->i2c = (chip->id == CHIP_PM8607) ? chip->client : chip->companion; + info->dev = &pdev->dev; + info->irq = irq + chip->irq_base; + + info->idev = input_allocate_device(); + if (!info->idev) { + dev_err(chip->dev, "Failed to allocate input dev\n"); + ret = -ENOMEM; + goto out; + } + + info->idev->name = "88pm860x_on"; + info->idev->phys = "88pm860x_on/input0"; + info->idev->id.bustype = BUS_I2C; + info->idev->dev.parent = &pdev->dev; + info->irq = irq; + info->idev->evbit[0] = BIT_MASK(EV_KEY); + info->idev->keybit[BIT_WORD(KEY_POWER)] = BIT_MASK(KEY_POWER); + + ret = input_register_device(info->idev); + if (ret) { + dev_err(chip->dev, "Can't register input device: %d\n", ret); + goto out_reg; + } + + ret = request_threaded_irq(info->irq, NULL, pm860x_onkey_handler, + IRQF_ONESHOT, "onkey", info); + if (ret < 0) { + dev_err(chip->dev, "Failed to request IRQ: #%d: %d\n", + info->irq, ret); + goto out_irq; + } + + platform_set_drvdata(pdev, info); + return 0; + +out_irq: + input_unregister_device(info->idev); + kfree(info); + return ret; + +out_reg: + input_free_device(info->idev); +out: + kfree(info); + return ret; +} + +static int __devexit pm860x_onkey_remove(struct platform_device *pdev) +{ + struct pm860x_onkey_info *info = platform_get_drvdata(pdev); + + free_irq(info->irq, info); + input_unregister_device(info->idev); + kfree(info); + return 0; +} + +static struct platform_driver pm860x_onkey_driver = { + .driver = { + .name = "88pm860x-onkey", + .owner = THIS_MODULE, + }, + .probe = pm860x_onkey_probe, + .remove = __devexit_p(pm860x_onkey_remove), +}; + +static int __init pm860x_onkey_init(void) +{ + return platform_driver_register(&pm860x_onkey_driver); +} +module_init(pm860x_onkey_init); + +static void __exit pm860x_onkey_exit(void) +{ + platform_driver_unregister(&pm860x_onkey_driver); +} +module_exit(pm860x_onkey_exit); + +MODULE_DESCRIPTION("Marvell 88PM860x ONKEY driver"); +MODULE_AUTHOR("Haojian Zhuang "); +MODULE_LICENSE("GPL"); diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig index 16ec5233441c..7097bfe581d7 100644 --- a/drivers/input/misc/Kconfig +++ b/drivers/input/misc/Kconfig @@ -12,6 +12,16 @@ menuconfig INPUT_MISC if INPUT_MISC +config INPUT_88PM860X_ONKEY + tristate "88PM860x ONKEY support" + depends on MFD_88PM860X + help + Support the ONKEY of Marvell 88PM860x PMICs as an input device + reporting power button status. + + To compile this driver as a module, choose M here: the module + will be called 88pm860x_onkey. + config INPUT_PCSPKR tristate "PC Speaker support" depends on PCSPKR_PLATFORM diff --git a/drivers/input/misc/Makefile b/drivers/input/misc/Makefile index a8b84854fb7b..b611615e24ad 100644 --- a/drivers/input/misc/Makefile +++ b/drivers/input/misc/Makefile @@ -4,6 +4,7 @@ # Each configuration option enables a list of files. +obj-$(CONFIG_INPUT_88PM860X_ONKEY) += 88pm860x_onkey.o obj-$(CONFIG_INPUT_APANEL) += apanel.o obj-$(CONFIG_INPUT_ATI_REMOTE) += ati_remote.o obj-$(CONFIG_INPUT_ATI_REMOTE2) += ati_remote2.o -- cgit v1.2.3 From ec62e1c8dd2f9b2a833b48d4a2f58f0c5e07384c Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Mon, 8 Mar 2010 22:37:09 -0800 Subject: Input: i8042 - use platfrom_create_bundle() helper Signed-off-by: Dmitry Torokhov --- drivers/input/serio/i8042.c | 24 ++++++++---------------- 1 file changed, 8 insertions(+), 16 deletions(-) (limited to 'drivers/input') diff --git a/drivers/input/serio/i8042.c b/drivers/input/serio/i8042.c index b54aee7cd9e3..fce8ab7e89a1 100644 --- a/drivers/input/serio/i8042.c +++ b/drivers/input/serio/i8042.c @@ -1386,6 +1386,8 @@ static int __init i8042_probe(struct platform_device *dev) { int error; + i8042_platform_device = dev; + error = i8042_controller_selftest(); if (error) return error; @@ -1421,6 +1423,7 @@ static int __init i8042_probe(struct platform_device *dev) i8042_free_aux_ports(); /* in case KBD failed but AUX not */ i8042_free_irqs(); i8042_controller_reset(); + i8042_platform_device = NULL; return error; } @@ -1430,6 +1433,7 @@ static int __devexit i8042_remove(struct platform_device *dev) i8042_unregister_ports(); i8042_free_irqs(); i8042_controller_reset(); + i8042_platform_device = NULL; return 0; } @@ -1448,6 +1452,7 @@ static struct platform_driver i8042_driver = { static int __init i8042_init(void) { + struct platform_device *pdev; int err; dbg_init(); @@ -1460,31 +1465,18 @@ static int __init i8042_init(void) if (err) goto err_platform_exit; - i8042_platform_device = platform_device_alloc("i8042", -1); - if (!i8042_platform_device) { - err = -ENOMEM; + pdev = platform_create_bundle(&i8042_driver, i8042_probe, NULL, 0, NULL, 0); + if (IS_ERR(pdev)) { + err = PTR_ERR(pdev); goto err_platform_exit; } - err = platform_device_add(i8042_platform_device); - if (err) - goto err_free_device; - - err = platform_driver_probe(&i8042_driver, i8042_probe); - if (err) - goto err_del_device; - panic_blink = i8042_panic_blink; return 0; - err_del_device: - platform_device_del(i8042_platform_device); - err_free_device: - platform_device_put(i8042_platform_device); err_platform_exit: i8042_platform_exit(); - return err; } -- cgit v1.2.3 From 58b939959d228681208ba997595411fddc860849 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Mon, 8 Mar 2010 22:37:10 -0800 Subject: Input: scancode in get/set_keycodes should be unsigned MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The HID layer has some scan codes of the form 0xffbc0000 for logitech devices which do not work if scancode is typed as signed int, so we need to switch to unsigned it instead. While at it keycode being signed does not make much sense either. Acked-by: Márton Németh Acked-by: Matthew Garrett Acked-by: Jiri Kosina Signed-off-by: Dmitry Torokhov --- drivers/hid/hid-input.c | 24 ++++++++++++------------ drivers/input/evdev.c | 2 +- drivers/input/input.c | 20 +++++++++----------- drivers/input/misc/ati_remote2.c | 14 +++++++------- drivers/input/misc/winbond-cir.c | 12 +++++------- drivers/input/sparse-keymap.c | 6 ++++-- drivers/media/IR/ir-keytable.c | 4 ++-- drivers/media/dvb/dvb-usb/dvb-usb-remote.c | 4 ++-- drivers/platform/x86/dell-wmi.c | 16 +++++++--------- drivers/platform/x86/hp-wmi.c | 15 +++++++-------- drivers/platform/x86/panasonic-laptop.c | 15 +++++++-------- drivers/platform/x86/topstar-laptop.c | 13 ++++++------- drivers/platform/x86/toshiba_acpi.c | 17 +++++++---------- include/linux/input.h | 20 ++++++++++++-------- 14 files changed, 88 insertions(+), 94 deletions(-) (limited to 'drivers/input') diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c index 79d9edd0bdfa..7a0d2e4661a1 100644 --- a/drivers/hid/hid-input.c +++ b/drivers/hid/hid-input.c @@ -68,22 +68,25 @@ static const struct { #define map_key_clear(c) hid_map_usage_clear(hidinput, usage, &bit, \ &max, EV_KEY, (c)) -static inline int match_scancode(int code, int scancode) +static inline int match_scancode(unsigned int code, unsigned int scancode) { if (scancode == 0) return 1; - return ((code & (HID_USAGE_PAGE | HID_USAGE)) == scancode); + + return (code & (HID_USAGE_PAGE | HID_USAGE)) == scancode; } -static inline int match_keycode(int code, int keycode) +static inline int match_keycode(unsigned int code, unsigned int keycode) { if (keycode == 0) return 1; - return (code == keycode); + + return code == keycode; } static struct hid_usage *hidinput_find_key(struct hid_device *hid, - int scancode, int keycode) + unsigned int scancode, + unsigned int keycode) { int i, j, k; struct hid_report *report; @@ -105,8 +108,8 @@ static struct hid_usage *hidinput_find_key(struct hid_device *hid, return NULL; } -static int hidinput_getkeycode(struct input_dev *dev, int scancode, - int *keycode) +static int hidinput_getkeycode(struct input_dev *dev, + unsigned int scancode, unsigned int *keycode) { struct hid_device *hid = input_get_drvdata(dev); struct hid_usage *usage; @@ -119,16 +122,13 @@ static int hidinput_getkeycode(struct input_dev *dev, int scancode, return -EINVAL; } -static int hidinput_setkeycode(struct input_dev *dev, int scancode, - int keycode) +static int hidinput_setkeycode(struct input_dev *dev, + unsigned int scancode, unsigned int keycode) { struct hid_device *hid = input_get_drvdata(dev); struct hid_usage *usage; int old_keycode; - if (keycode < 0 || keycode > KEY_MAX) - return -EINVAL; - usage = hidinput_find_key(hid, scancode, 0); if (usage) { old_keycode = usage->code; diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c index 9f9816baeb97..2ee6c7a68bdc 100644 --- a/drivers/input/evdev.c +++ b/drivers/input/evdev.c @@ -515,7 +515,7 @@ static long evdev_do_ioctl(struct file *file, unsigned int cmd, struct input_absinfo abs; struct ff_effect effect; int __user *ip = (int __user *)p; - int i, t, u, v; + unsigned int i, t, u, v; int error; switch (cmd) { diff --git a/drivers/input/input.c b/drivers/input/input.c index 41168d5f8c17..e2dd8858e19d 100644 --- a/drivers/input/input.c +++ b/drivers/input/input.c @@ -582,7 +582,8 @@ static int input_fetch_keycode(struct input_dev *dev, int scancode) } static int input_default_getkeycode(struct input_dev *dev, - int scancode, int *keycode) + unsigned int scancode, + unsigned int *keycode) { if (!dev->keycodesize) return -EINVAL; @@ -596,7 +597,8 @@ static int input_default_getkeycode(struct input_dev *dev, } static int input_default_setkeycode(struct input_dev *dev, - int scancode, int keycode) + unsigned int scancode, + unsigned int keycode) { int old_keycode; int i; @@ -654,11 +656,9 @@ static int input_default_setkeycode(struct input_dev *dev, * This function should be called by anyone interested in retrieving current * keymap. Presently keyboard and evdev handlers use it. */ -int input_get_keycode(struct input_dev *dev, int scancode, int *keycode) +int input_get_keycode(struct input_dev *dev, + unsigned int scancode, unsigned int *keycode) { - if (scancode < 0) - return -EINVAL; - return dev->getkeycode(dev, scancode, keycode); } EXPORT_SYMBOL(input_get_keycode); @@ -672,16 +672,14 @@ EXPORT_SYMBOL(input_get_keycode); * This function should be called by anyone needing to update current * keymap. Presently keyboard and evdev handlers use it. */ -int input_set_keycode(struct input_dev *dev, int scancode, int keycode) +int input_set_keycode(struct input_dev *dev, + unsigned int scancode, unsigned int keycode) { unsigned long flags; int old_keycode; int retval; - if (scancode < 0) - return -EINVAL; - - if (keycode < 0 || keycode > KEY_MAX) + if (keycode > KEY_MAX) return -EINVAL; spin_lock_irqsave(&dev->event_lock, flags); diff --git a/drivers/input/misc/ati_remote2.c b/drivers/input/misc/ati_remote2.c index 0501f0e65157..15be5430bc6d 100644 --- a/drivers/input/misc/ati_remote2.c +++ b/drivers/input/misc/ati_remote2.c @@ -474,10 +474,11 @@ static void ati_remote2_complete_key(struct urb *urb) } static int ati_remote2_getkeycode(struct input_dev *idev, - int scancode, int *keycode) + unsigned int scancode, unsigned int *keycode) { struct ati_remote2 *ar2 = input_get_drvdata(idev); - int index, mode; + unsigned int mode; + int index; mode = scancode >> 8; if (mode > ATI_REMOTE2_PC || !((1 << mode) & ar2->mode_mask)) @@ -491,10 +492,12 @@ static int ati_remote2_getkeycode(struct input_dev *idev, return 0; } -static int ati_remote2_setkeycode(struct input_dev *idev, int scancode, int keycode) +static int ati_remote2_setkeycode(struct input_dev *idev, + unsigned int scancode, unsigned int keycode) { struct ati_remote2 *ar2 = input_get_drvdata(idev); - int index, mode, old_keycode; + unsigned int mode, old_keycode; + int index; mode = scancode >> 8; if (mode > ATI_REMOTE2_PC || !((1 << mode) & ar2->mode_mask)) @@ -504,9 +507,6 @@ static int ati_remote2_setkeycode(struct input_dev *idev, int scancode, int keyc if (index < 0) return -EINVAL; - if (keycode < KEY_RESERVED || keycode > KEY_MAX) - return -EINVAL; - old_keycode = ar2->keycode[mode][index]; ar2->keycode[mode][index] = keycode; __set_bit(keycode, idev->keybit); diff --git a/drivers/input/misc/winbond-cir.c b/drivers/input/misc/winbond-cir.c index cbec3dfdd42b..9c155a43abc2 100644 --- a/drivers/input/misc/winbond-cir.c +++ b/drivers/input/misc/winbond-cir.c @@ -385,26 +385,24 @@ wbcir_do_getkeycode(struct wbcir_data *data, u32 scancode) } static int -wbcir_getkeycode(struct input_dev *dev, int scancode, int *keycode) +wbcir_getkeycode(struct input_dev *dev, + unsigned int scancode, unsigned int *keycode) { struct wbcir_data *data = input_get_drvdata(dev); - *keycode = (int)wbcir_do_getkeycode(data, (u32)scancode); + *keycode = wbcir_do_getkeycode(data, scancode); return 0; } static int -wbcir_setkeycode(struct input_dev *dev, int sscancode, int keycode) +wbcir_setkeycode(struct input_dev *dev, + unsigned int scancode, unsigned int keycode) { struct wbcir_data *data = input_get_drvdata(dev); struct wbcir_keyentry *keyentry; struct wbcir_keyentry *new_keyentry; unsigned long flags; unsigned int old_keycode = KEY_RESERVED; - u32 scancode = (u32)sscancode; - - if (keycode < 0 || keycode > KEY_MAX) - return -EINVAL; new_keyentry = kmalloc(sizeof(*new_keyentry), GFP_KERNEL); if (!new_keyentry) diff --git a/drivers/input/sparse-keymap.c b/drivers/input/sparse-keymap.c index fbd3987af57f..e6bde55e5203 100644 --- a/drivers/input/sparse-keymap.c +++ b/drivers/input/sparse-keymap.c @@ -64,7 +64,8 @@ struct key_entry *sparse_keymap_entry_from_keycode(struct input_dev *dev, EXPORT_SYMBOL(sparse_keymap_entry_from_keycode); static int sparse_keymap_getkeycode(struct input_dev *dev, - int scancode, int *keycode) + unsigned int scancode, + unsigned int *keycode) { const struct key_entry *key = sparse_keymap_entry_from_scancode(dev, scancode); @@ -78,7 +79,8 @@ static int sparse_keymap_getkeycode(struct input_dev *dev, } static int sparse_keymap_setkeycode(struct input_dev *dev, - int scancode, int keycode) + unsigned int scancode, + unsigned int keycode) { struct key_entry *key; int old_keycode; diff --git a/drivers/media/IR/ir-keytable.c b/drivers/media/IR/ir-keytable.c index 0903f539bf68..0a3b4ed38e48 100644 --- a/drivers/media/IR/ir-keytable.c +++ b/drivers/media/IR/ir-keytable.c @@ -123,7 +123,7 @@ static int ir_copy_table(struct ir_scancode_table *destin, * If the key is not found, returns -EINVAL, otherwise, returns 0. */ static int ir_getkeycode(struct input_dev *dev, - int scancode, int *keycode) + unsigned int scancode, unsigned int *keycode) { int elem; struct ir_input_dev *ir_dev = input_get_drvdata(dev); @@ -291,7 +291,7 @@ static int ir_insert_key(struct ir_scancode_table *rc_tab, * If the key is not found, returns -EINVAL, otherwise, returns 0. */ static int ir_setkeycode(struct input_dev *dev, - int scancode, int keycode) + unsigned int scancode, unsigned int keycode) { int rc = 0; struct ir_input_dev *ir_dev = input_get_drvdata(dev); diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-remote.c b/drivers/media/dvb/dvb-usb/dvb-usb-remote.c index a03ef7efec9a..852fe89539cf 100644 --- a/drivers/media/dvb/dvb-usb/dvb-usb-remote.c +++ b/drivers/media/dvb/dvb-usb/dvb-usb-remote.c @@ -9,7 +9,7 @@ #include static int dvb_usb_getkeycode(struct input_dev *dev, - int scancode, int *keycode) + unsigned int scancode, unsigned int *keycode) { struct dvb_usb_device *d = input_get_drvdata(dev); @@ -39,7 +39,7 @@ static int dvb_usb_getkeycode(struct input_dev *dev, } static int dvb_usb_setkeycode(struct input_dev *dev, - int scancode, int keycode) + unsigned int scancode, unsigned int keycode) { struct dvb_usb_device *d = input_get_drvdata(dev); diff --git a/drivers/platform/x86/dell-wmi.c b/drivers/platform/x86/dell-wmi.c index 1b1dddbd5744..bed764e3ea2a 100644 --- a/drivers/platform/x86/dell-wmi.c +++ b/drivers/platform/x86/dell-wmi.c @@ -142,7 +142,7 @@ static struct key_entry *dell_wmi_keymap = dell_legacy_wmi_keymap; static struct input_dev *dell_wmi_input_dev; -static struct key_entry *dell_wmi_get_entry_by_scancode(int code) +static struct key_entry *dell_wmi_get_entry_by_scancode(unsigned int code) { struct key_entry *key; @@ -153,7 +153,7 @@ static struct key_entry *dell_wmi_get_entry_by_scancode(int code) return NULL; } -static struct key_entry *dell_wmi_get_entry_by_keycode(int keycode) +static struct key_entry *dell_wmi_get_entry_by_keycode(unsigned int keycode) { struct key_entry *key; @@ -164,8 +164,8 @@ static struct key_entry *dell_wmi_get_entry_by_keycode(int keycode) return NULL; } -static int dell_wmi_getkeycode(struct input_dev *dev, int scancode, - int *keycode) +static int dell_wmi_getkeycode(struct input_dev *dev, + unsigned int scancode, unsigned int *keycode) { struct key_entry *key = dell_wmi_get_entry_by_scancode(scancode); @@ -177,13 +177,11 @@ static int dell_wmi_getkeycode(struct input_dev *dev, int scancode, return -EINVAL; } -static int dell_wmi_setkeycode(struct input_dev *dev, int scancode, int keycode) +static int dell_wmi_setkeycode(struct input_dev *dev, + unsigned int scancode, unsigned int keycode) { struct key_entry *key; - int old_keycode; - - if (keycode < 0 || keycode > KEY_MAX) - return -EINVAL; + unsigned int old_keycode; key = dell_wmi_get_entry_by_scancode(scancode); if (key && key->type == KE_KEY) { diff --git a/drivers/platform/x86/hp-wmi.c b/drivers/platform/x86/hp-wmi.c index 7ccf33c08967..56086363becc 100644 --- a/drivers/platform/x86/hp-wmi.c +++ b/drivers/platform/x86/hp-wmi.c @@ -278,7 +278,7 @@ static DEVICE_ATTR(als, S_IRUGO | S_IWUSR, show_als, set_als); static DEVICE_ATTR(dock, S_IRUGO, show_dock, NULL); static DEVICE_ATTR(tablet, S_IRUGO, show_tablet, NULL); -static struct key_entry *hp_wmi_get_entry_by_scancode(int code) +static struct key_entry *hp_wmi_get_entry_by_scancode(unsigned int code) { struct key_entry *key; @@ -289,7 +289,7 @@ static struct key_entry *hp_wmi_get_entry_by_scancode(int code) return NULL; } -static struct key_entry *hp_wmi_get_entry_by_keycode(int keycode) +static struct key_entry *hp_wmi_get_entry_by_keycode(unsigned int keycode) { struct key_entry *key; @@ -300,7 +300,8 @@ static struct key_entry *hp_wmi_get_entry_by_keycode(int keycode) return NULL; } -static int hp_wmi_getkeycode(struct input_dev *dev, int scancode, int *keycode) +static int hp_wmi_getkeycode(struct input_dev *dev, + unsigned int scancode, unsigned int *keycode) { struct key_entry *key = hp_wmi_get_entry_by_scancode(scancode); @@ -312,13 +313,11 @@ static int hp_wmi_getkeycode(struct input_dev *dev, int scancode, int *keycode) return -EINVAL; } -static int hp_wmi_setkeycode(struct input_dev *dev, int scancode, int keycode) +static int hp_wmi_setkeycode(struct input_dev *dev, + unsigned int scancode, unsigned int keycode) { struct key_entry *key; - int old_keycode; - - if (keycode < 0 || keycode > KEY_MAX) - return -EINVAL; + unsigned int old_keycode; key = hp_wmi_get_entry_by_scancode(scancode); if (key && key->type == KE_KEY) { diff --git a/drivers/platform/x86/panasonic-laptop.c b/drivers/platform/x86/panasonic-laptop.c index fe7cf0188acc..c9fc479fc290 100644 --- a/drivers/platform/x86/panasonic-laptop.c +++ b/drivers/platform/x86/panasonic-laptop.c @@ -200,7 +200,7 @@ static struct acpi_driver acpi_pcc_driver = { }; #define KEYMAP_SIZE 11 -static const int initial_keymap[KEYMAP_SIZE] = { +static const unsigned int initial_keymap[KEYMAP_SIZE] = { /* 0 */ KEY_RESERVED, /* 1 */ KEY_BRIGHTNESSDOWN, /* 2 */ KEY_BRIGHTNESSUP, @@ -222,7 +222,7 @@ struct pcc_acpi { struct acpi_device *device; struct input_dev *input_dev; struct backlight_device *backlight; - int keymap[KEYMAP_SIZE]; + unsigned int keymap[KEYMAP_SIZE]; }; struct pcc_keyinput { @@ -445,7 +445,8 @@ static struct attribute_group pcc_attr_group = { /* hotkey input device driver */ -static int pcc_getkeycode(struct input_dev *dev, int scancode, int *keycode) +static int pcc_getkeycode(struct input_dev *dev, + unsigned int scancode, unsigned int *keycode) { struct pcc_acpi *pcc = input_get_drvdata(dev); @@ -457,7 +458,7 @@ static int pcc_getkeycode(struct input_dev *dev, int scancode, int *keycode) return 0; } -static int keymap_get_by_keycode(struct pcc_acpi *pcc, int keycode) +static int keymap_get_by_keycode(struct pcc_acpi *pcc, unsigned int keycode) { int i; @@ -469,7 +470,8 @@ static int keymap_get_by_keycode(struct pcc_acpi *pcc, int keycode) return 0; } -static int pcc_setkeycode(struct input_dev *dev, int scancode, int keycode) +static int pcc_setkeycode(struct input_dev *dev, + unsigned int scancode, unsigned int keycode) { struct pcc_acpi *pcc = input_get_drvdata(dev); int oldkeycode; @@ -477,9 +479,6 @@ static int pcc_setkeycode(struct input_dev *dev, int scancode, int keycode) if (scancode >= ARRAY_SIZE(pcc->keymap)) return -EINVAL; - if (keycode < 0 || keycode > KEY_MAX) - return -EINVAL; - oldkeycode = pcc->keymap[scancode]; pcc->keymap[scancode] = keycode; diff --git a/drivers/platform/x86/topstar-laptop.c b/drivers/platform/x86/topstar-laptop.c index 02f3d4e9e666..4d6516fded7e 100644 --- a/drivers/platform/x86/topstar-laptop.c +++ b/drivers/platform/x86/topstar-laptop.c @@ -46,7 +46,7 @@ static struct tps_key_entry topstar_keymap[] = { { } }; -static struct tps_key_entry *tps_get_key_by_scancode(int code) +static struct tps_key_entry *tps_get_key_by_scancode(unsigned int code) { struct tps_key_entry *key; @@ -57,7 +57,7 @@ static struct tps_key_entry *tps_get_key_by_scancode(int code) return NULL; } -static struct tps_key_entry *tps_get_key_by_keycode(int code) +static struct tps_key_entry *tps_get_key_by_keycode(unsigned int code) { struct tps_key_entry *key; @@ -126,7 +126,8 @@ static int acpi_topstar_fncx_switch(struct acpi_device *device, bool state) return 0; } -static int topstar_getkeycode(struct input_dev *dev, int scancode, int *keycode) +static int topstar_getkeycode(struct input_dev *dev, + unsigned int scancode, unsigned int *keycode) { struct tps_key_entry *key = tps_get_key_by_scancode(scancode); @@ -137,14 +138,12 @@ static int topstar_getkeycode(struct input_dev *dev, int scancode, int *keycode) return 0; } -static int topstar_setkeycode(struct input_dev *dev, int scancode, int keycode) +static int topstar_setkeycode(struct input_dev *dev, + unsigned int scancode, unsigned int keycode) { struct tps_key_entry *key; int old_keycode; - if (keycode < 0 || keycode > KEY_MAX) - return -EINVAL; - key = tps_get_key_by_scancode(scancode); if (!key) diff --git a/drivers/platform/x86/toshiba_acpi.c b/drivers/platform/x86/toshiba_acpi.c index 405b969734d6..789240d1b577 100644 --- a/drivers/platform/x86/toshiba_acpi.c +++ b/drivers/platform/x86/toshiba_acpi.c @@ -745,7 +745,7 @@ static struct backlight_ops toshiba_backlight_data = { .update_status = set_lcd_status, }; -static struct key_entry *toshiba_acpi_get_entry_by_scancode(int code) +static struct key_entry *toshiba_acpi_get_entry_by_scancode(unsigned int code) { struct key_entry *key; @@ -756,7 +756,7 @@ static struct key_entry *toshiba_acpi_get_entry_by_scancode(int code) return NULL; } -static struct key_entry *toshiba_acpi_get_entry_by_keycode(int code) +static struct key_entry *toshiba_acpi_get_entry_by_keycode(unsigned int code) { struct key_entry *key; @@ -767,8 +767,8 @@ static struct key_entry *toshiba_acpi_get_entry_by_keycode(int code) return NULL; } -static int toshiba_acpi_getkeycode(struct input_dev *dev, int scancode, - int *keycode) +static int toshiba_acpi_getkeycode(struct input_dev *dev, + unsigned int scancode, unsigned int *keycode) { struct key_entry *key = toshiba_acpi_get_entry_by_scancode(scancode); @@ -780,14 +780,11 @@ static int toshiba_acpi_getkeycode(struct input_dev *dev, int scancode, return -EINVAL; } -static int toshiba_acpi_setkeycode(struct input_dev *dev, int scancode, - int keycode) +static int toshiba_acpi_setkeycode(struct input_dev *dev, + unsigned int scancode, unsigned int keycode) { struct key_entry *key; - int old_keycode; - - if (keycode < 0 || keycode > KEY_MAX) - return -EINVAL; + unsigned int old_keycode; key = toshiba_acpi_get_entry_by_scancode(scancode); if (key && key->type == KE_KEY) { diff --git a/include/linux/input.h b/include/linux/input.h index dc24effb6d0e..7ed2251b33f1 100644 --- a/include/linux/input.h +++ b/include/linux/input.h @@ -58,10 +58,10 @@ struct input_absinfo { #define EVIOCGVERSION _IOR('E', 0x01, int) /* get driver version */ #define EVIOCGID _IOR('E', 0x02, struct input_id) /* get device ID */ -#define EVIOCGREP _IOR('E', 0x03, int[2]) /* get repeat settings */ -#define EVIOCSREP _IOW('E', 0x03, int[2]) /* set repeat settings */ -#define EVIOCGKEYCODE _IOR('E', 0x04, int[2]) /* get keycode */ -#define EVIOCSKEYCODE _IOW('E', 0x04, int[2]) /* set keycode */ +#define EVIOCGREP _IOR('E', 0x03, unsigned int[2]) /* get repeat settings */ +#define EVIOCSREP _IOW('E', 0x03, unsigned int[2]) /* set repeat settings */ +#define EVIOCGKEYCODE _IOR('E', 0x04, unsigned int[2]) /* get keycode */ +#define EVIOCSKEYCODE _IOW('E', 0x04, unsigned int[2]) /* set keycode */ #define EVIOCGNAME(len) _IOC(_IOC_READ, 'E', 0x06, len) /* get device name */ #define EVIOCGPHYS(len) _IOC(_IOC_READ, 'E', 0x07, len) /* get physical location */ @@ -1142,8 +1142,10 @@ struct input_dev { unsigned int keycodemax; unsigned int keycodesize; void *keycode; - int (*setkeycode)(struct input_dev *dev, int scancode, int keycode); - int (*getkeycode)(struct input_dev *dev, int scancode, int *keycode); + int (*setkeycode)(struct input_dev *dev, + unsigned int scancode, unsigned int keycode); + int (*getkeycode)(struct input_dev *dev, + unsigned int scancode, unsigned int *keycode); struct ff_device *ff; @@ -1415,8 +1417,10 @@ static inline void input_set_abs_params(struct input_dev *dev, int axis, int min dev->absbit[BIT_WORD(axis)] |= BIT_MASK(axis); } -int input_get_keycode(struct input_dev *dev, int scancode, int *keycode); -int input_set_keycode(struct input_dev *dev, int scancode, int keycode); +int input_get_keycode(struct input_dev *dev, + unsigned int scancode, unsigned int *keycode); +int input_set_keycode(struct input_dev *dev, + unsigned int scancode, unsigned int keycode); extern struct class input_class; -- cgit v1.2.3 From 3e6e15a862a0bc20128497bbdc54254cdec21835 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Mon, 8 Mar 2010 23:42:46 -0800 Subject: Input: enable remote wakeup for PNP i8042 keyboard ports This patch (as1355) enables remote wakeup by default on PNP i8042 keyboard ports. Signed-off-by: Alan Stern Signed-off-by: Dmitry Torokhov --- drivers/input/serio/i8042-x86ia64io.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers/input') diff --git a/drivers/input/serio/i8042-x86ia64io.h b/drivers/input/serio/i8042-x86ia64io.h index 2a5982e532f8..3696cab40598 100644 --- a/drivers/input/serio/i8042-x86ia64io.h +++ b/drivers/input/serio/i8042-x86ia64io.h @@ -624,6 +624,9 @@ static int i8042_pnp_kbd_probe(struct pnp_dev *dev, const struct pnp_device_id * strlcat(i8042_pnp_kbd_name, pnp_dev_name(dev), sizeof(i8042_pnp_kbd_name)); } + /* Keyboard ports are always supposed to be wakeup-enabled */ + device_set_wakeup_enable(&dev->dev, true); + i8042_pnp_kbd_devices++; return 0; } -- cgit v1.2.3 From 3dd1b39497b6820219581af16e6a8831a582bb3a Mon Sep 17 00:00:00 2001 From: Jari Vanhala Date: Tue, 9 Mar 2010 00:29:46 -0800 Subject: Input: add driver for TWL4030 vibrator device TWL4030 Vibrator implemented via Force Feedback interface. This uses MFD TWL4030 codec and own dynamic workqueue. Signed-off-by: Jari Vanhala Signed-off-by: Dmitry Torokhov --- drivers/input/misc/Kconfig | 11 ++ drivers/input/misc/Makefile | 1 + drivers/input/misc/twl4030-vibra.c | 297 +++++++++++++++++++++++++++++++++++++ 3 files changed, 309 insertions(+) create mode 100644 drivers/input/misc/twl4030-vibra.c (limited to 'drivers/input') diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig index 7097bfe581d7..23140a3bb8e0 100644 --- a/drivers/input/misc/Kconfig +++ b/drivers/input/misc/Kconfig @@ -214,6 +214,17 @@ config INPUT_TWL4030_PWRBUTTON To compile this driver as a module, choose M here. The module will be called twl4030_pwrbutton. +config INPUT_TWL4030_VIBRA + tristate "Support for TWL4030 Vibrator" + depends on TWL4030_CORE + select TWL4030_CODEC + select INPUT_FF_MEMLESS + help + This option enables support for TWL4030 Vibrator Driver. + + To compile this driver as a module, choose M here. The module will + be called twl4030_vibra. + config INPUT_UINPUT tristate "User level driver support" help diff --git a/drivers/input/misc/Makefile b/drivers/input/misc/Makefile index b611615e24ad..7e95a5d474dc 100644 --- a/drivers/input/misc/Makefile +++ b/drivers/input/misc/Makefile @@ -26,6 +26,7 @@ obj-$(CONFIG_INPUT_GPIO_ROTARY_ENCODER) += rotary_encoder.o obj-$(CONFIG_INPUT_SGI_BTNS) += sgi_btns.o obj-$(CONFIG_INPUT_SPARCSPKR) += sparcspkr.o obj-$(CONFIG_INPUT_TWL4030_PWRBUTTON) += twl4030-pwrbutton.o +obj-$(CONFIG_INPUT_TWL4030_VIBRA) += twl4030-vibra.o obj-$(CONFIG_INPUT_UINPUT) += uinput.o obj-$(CONFIG_INPUT_WINBOND_CIR) += winbond-cir.o obj-$(CONFIG_INPUT_WISTRON_BTNS) += wistron_btns.o diff --git a/drivers/input/misc/twl4030-vibra.c b/drivers/input/misc/twl4030-vibra.c new file mode 100644 index 000000000000..2fb79e064da3 --- /dev/null +++ b/drivers/input/misc/twl4030-vibra.c @@ -0,0 +1,297 @@ +/* + * twl4030-vibra.c - TWL4030 Vibrator driver + * + * Copyright (C) 2008-2010 Nokia Corporation + * + * Written by Henrik Saari + * Updates by Felipe Balbi + * Input by Jari Vanhala + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * 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., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + */ + +#include +#include +#include +#include +#include +#include +#include + +/* MODULE ID2 */ +#define LEDEN 0x00 + +/* ForceFeedback */ +#define EFFECT_DIR_180_DEG 0x8000 /* range is 0 - 0xFFFF */ + +struct vibra_info { + struct device *dev; + struct input_dev *input_dev; + + struct workqueue_struct *workqueue; + struct work_struct play_work; + + bool enabled; + int speed; + int direction; + + bool coexist; +}; + +static void vibra_disable_leds(void) +{ + u8 reg; + + /* Disable LEDA & LEDB, cannot be used with vibra (PWM) */ + twl_i2c_read_u8(TWL4030_MODULE_LED, ®, LEDEN); + reg &= ~0x03; + twl_i2c_write_u8(TWL4030_MODULE_LED, LEDEN, reg); +} + +/* Powers H-Bridge and enables audio clk */ +static void vibra_enable(struct vibra_info *info) +{ + u8 reg; + + twl4030_codec_enable_resource(TWL4030_CODEC_RES_POWER); + + /* turn H-Bridge on */ + twl_i2c_read_u8(TWL4030_MODULE_AUDIO_VOICE, + ®, TWL4030_REG_VIBRA_CTL); + twl_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE, + (reg | TWL4030_VIBRA_EN), TWL4030_REG_VIBRA_CTL); + + twl4030_codec_enable_resource(TWL4030_CODEC_RES_APLL); + + info->enabled = true; +} + +static void vibra_disable(struct vibra_info *info) +{ + u8 reg; + + /* Power down H-Bridge */ + twl_i2c_read_u8(TWL4030_MODULE_AUDIO_VOICE, + ®, TWL4030_REG_VIBRA_CTL); + twl_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE, + (reg & ~TWL4030_VIBRA_EN), TWL4030_REG_VIBRA_CTL); + + twl4030_codec_disable_resource(TWL4030_CODEC_RES_POWER); + twl4030_codec_disable_resource(TWL4030_CODEC_RES_APLL); + + info->enabled = false; +} + +static void vibra_play_work(struct work_struct *work) +{ + struct vibra_info *info = container_of(work, + struct vibra_info, play_work); + int dir; + int pwm; + u8 reg; + + dir = info->direction; + pwm = info->speed; + + twl_i2c_read_u8(TWL4030_MODULE_AUDIO_VOICE, + ®, TWL4030_REG_VIBRA_CTL); + if (pwm && (!info->coexist || !(reg & TWL4030_VIBRA_SEL))) { + + if (!info->enabled) + vibra_enable(info); + + /* set vibra rotation direction */ + twl_i2c_read_u8(TWL4030_MODULE_AUDIO_VOICE, + ®, TWL4030_REG_VIBRA_CTL); + reg = (dir) ? (reg | TWL4030_VIBRA_DIR) : + (reg & ~TWL4030_VIBRA_DIR); + twl_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE, + reg, TWL4030_REG_VIBRA_CTL); + + /* set PWM, 1 = max, 255 = min */ + twl_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE, + 256 - pwm, TWL4030_REG_VIBRA_SET); + } else { + if (info->enabled) + vibra_disable(info); + } +} + +/*** Input/ForceFeedback ***/ + +static int vibra_play(struct input_dev *input, void *data, + struct ff_effect *effect) +{ + struct vibra_info *info = input_get_drvdata(input); + + info->speed = effect->u.rumble.strong_magnitude >> 8; + if (!info->speed) + info->speed = effect->u.rumble.weak_magnitude >> 9; + info->direction = effect->direction < EFFECT_DIR_180_DEG ? 0 : 1; + queue_work(info->workqueue, &info->play_work); + return 0; +} + +static int twl4030_vibra_open(struct input_dev *input) +{ + struct vibra_info *info = input_get_drvdata(input); + + info->workqueue = create_singlethread_workqueue("vibra"); + if (info->workqueue == NULL) { + dev_err(&input->dev, "couldn't create workqueue\n"); + return -ENOMEM; + } + return 0; +} + +static void twl4030_vibra_close(struct input_dev *input) +{ + struct vibra_info *info = input_get_drvdata(input); + + cancel_work_sync(&info->play_work); + INIT_WORK(&info->play_work, vibra_play_work); /* cleanup */ + destroy_workqueue(info->workqueue); + info->workqueue = NULL; + + if (info->enabled) + vibra_disable(info); +} + +/*** Module ***/ +#if CONFIG_PM +static int twl4030_vibra_suspend(struct device *dev) +{ + struct platform_device *pdev = to_platform_device(dev); + struct vibra_info *info = platform_get_drvdata(pdev); + + if (info->enabled) + vibra_disable(info); + + return 0; +} + +static int twl4030_vibra_resume(struct device *dev) +{ + vibra_disable_leds(); + return 0; +} + +static SIMPLE_DEV_PM_OPS(twl4030_vibra_pm_ops, + twl4030_vibra_suspend, twl4030_vibra_resume); +#endif + +static int __devinit twl4030_vibra_probe(struct platform_device *pdev) +{ + struct twl4030_codec_vibra_data *pdata = pdev->dev.platform_data; + struct vibra_info *info; + int ret; + + if (!pdata) { + dev_dbg(&pdev->dev, "platform_data not available\n"); + return -EINVAL; + } + + info = kzalloc(sizeof(*info), GFP_KERNEL); + if (!info) + return -ENOMEM; + + info->dev = &pdev->dev; + info->coexist = pdata->coexist; + INIT_WORK(&info->play_work, vibra_play_work); + + info->input_dev = input_allocate_device(); + if (info->input_dev == NULL) { + dev_err(&pdev->dev, "couldn't allocate input device\n"); + ret = -ENOMEM; + goto err_kzalloc; + } + + input_set_drvdata(info->input_dev, info); + + info->input_dev->name = "twl4030:vibrator"; + info->input_dev->id.version = 1; + info->input_dev->dev.parent = pdev->dev.parent; + info->input_dev->open = twl4030_vibra_open; + info->input_dev->close = twl4030_vibra_close; + __set_bit(FF_RUMBLE, info->input_dev->ffbit); + + ret = input_ff_create_memless(info->input_dev, NULL, vibra_play); + if (ret < 0) { + dev_dbg(&pdev->dev, "couldn't register vibrator to FF\n"); + goto err_ialloc; + } + + ret = input_register_device(info->input_dev); + if (ret < 0) { + dev_dbg(&pdev->dev, "couldn't register input device\n"); + goto err_iff; + } + + vibra_disable_leds(); + + platform_set_drvdata(pdev, info); + return 0; + +err_iff: + input_ff_destroy(info->input_dev); +err_ialloc: + input_free_device(info->input_dev); +err_kzalloc: + kfree(info); + return ret; +} + +static int __devexit twl4030_vibra_remove(struct platform_device *pdev) +{ + struct vibra_info *info = platform_get_drvdata(pdev); + + /* this also free ff-memless and calls close if needed */ + input_unregister_device(info->input_dev); + kfree(info); + platform_set_drvdata(pdev, NULL); + + return 0; +} + +static struct platform_driver twl4030_vibra_driver = { + .probe = twl4030_vibra_probe, + .remove = __devexit_p(twl4030_vibra_remove), + .driver = { + .name = "twl4030_codec_vibra", + .owner = THIS_MODULE, +#ifdef CONFIG_PM + .pm = &twl4030_vibra_pm_ops, +#endif + }, +}; + +static int __init twl4030_vibra_init(void) +{ + return platform_driver_register(&twl4030_vibra_driver); +} +module_init(twl4030_vibra_init); + +static void __exit twl4030_vibra_exit(void) +{ + platform_driver_unregister(&twl4030_vibra_driver); +} +module_exit(twl4030_vibra_exit); + +MODULE_ALIAS("platform:twl4030_codec_vibra"); + +MODULE_DESCRIPTION("TWL4030 Vibra driver"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Nokia Corporation"); -- cgit v1.2.3 From c90c6a885ac9827921e8f94f3ce4360ae11148f1 Mon Sep 17 00:00:00 2001 From: Thadeu Lima de Souza Cascardo Date: Tue, 9 Mar 2010 20:38:47 -0800 Subject: Input: mousedev - remove BKL There's no need for BKL in mousedev, relevan protection is provided by a private mutex. Signed-off-by: Thadeu Lima de Souza Cascardo Acked-by: Arnd Bergmann Signed-off-by: Dmitry Torokhov --- drivers/input/mousedev.c | 6 ------ 1 file changed, 6 deletions(-) (limited to 'drivers/input') diff --git a/drivers/input/mousedev.c b/drivers/input/mousedev.c index a13d80f7da17..f34b22bce4ff 100644 --- a/drivers/input/mousedev.c +++ b/drivers/input/mousedev.c @@ -15,7 +15,6 @@ #include #include -#include #include #include #include @@ -542,10 +541,8 @@ static int mousedev_open(struct inode *inode, struct file *file) if (i >= MOUSEDEV_MINORS) return -ENODEV; - lock_kernel(); error = mutex_lock_interruptible(&mousedev_table_mutex); if (error) { - unlock_kernel(); return error; } mousedev = mousedev_table[i]; @@ -554,7 +551,6 @@ static int mousedev_open(struct inode *inode, struct file *file) mutex_unlock(&mousedev_table_mutex); if (!mousedev) { - unlock_kernel(); return -ENODEV; } @@ -575,7 +571,6 @@ static int mousedev_open(struct inode *inode, struct file *file) goto err_free_client; file->private_data = client; - unlock_kernel(); return 0; err_free_client: @@ -583,7 +578,6 @@ static int mousedev_open(struct inode *inode, struct file *file) kfree(client); err_put_mousedev: put_device(&mousedev->dev); - unlock_kernel(); return error; } -- cgit v1.2.3 From 77554b4d1fac6a66d4e624a6e36c020a4f5b6b64 Mon Sep 17 00:00:00 2001 From: Thadeu Lima de Souza Cascardo Date: Tue, 9 Mar 2010 20:38:47 -0800 Subject: Input: serio_raw - remove BKL serio_raw open function already uses a mutex. Also change formatting a bit. Signed-off-by: Thadeu Lima de Souza Cascardo Acked-by: Arnd Bergmann Signed-off-by: Dmitry Torokhov --- drivers/input/serio/serio_raw.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) (limited to 'drivers/input') diff --git a/drivers/input/serio/serio_raw.c b/drivers/input/serio/serio_raw.c index 27fdaaffbb40..998664854440 100644 --- a/drivers/input/serio/serio_raw.c +++ b/drivers/input/serio/serio_raw.c @@ -81,12 +81,12 @@ static int serio_raw_open(struct inode *inode, struct file *file) struct serio_raw_list *list; int retval = 0; - lock_kernel(); retval = mutex_lock_interruptible(&serio_raw_mutex); if (retval) - goto out_bkl; + return retval; - if (!(serio_raw = serio_raw_locate(iminor(inode)))) { + serio_raw = serio_raw_locate(iminor(inode)); + if (!serio_raw) { retval = -ENODEV; goto out; } @@ -96,7 +96,8 @@ static int serio_raw_open(struct inode *inode, struct file *file) goto out; } - if (!(list = kzalloc(sizeof(struct serio_raw_list), GFP_KERNEL))) { + list = kzalloc(sizeof(struct serio_raw_list), GFP_KERNEL); + if (!list) { retval = -ENOMEM; goto out; } @@ -109,8 +110,6 @@ static int serio_raw_open(struct inode *inode, struct file *file) out: mutex_unlock(&serio_raw_mutex); -out_bkl: - unlock_kernel(); return retval; } -- cgit v1.2.3 From 2f2177c8dadbcb08c14f796ac983c5475eca1bd3 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Tue, 9 Mar 2010 20:38:48 -0800 Subject: Input: remove BKL, fix input_open_file() locking Holding the BKL in input_open_file seems pointless because it does not protect against updates of input_table, and all open functions from the underlying drivers have proper mutex locking. This makes input_open_file take the input_mutex when accessing the table and no lock when calling into the lower function. Signed-off-by: Arnd Bergmann Acked-by: Thadeu Lima de Souza Cascardo Signed-off-by: Dmitry Torokhov --- drivers/input/input.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) (limited to 'drivers/input') diff --git a/drivers/input/input.c b/drivers/input/input.c index e2dd8858e19d..e2aad0a51826 100644 --- a/drivers/input/input.c +++ b/drivers/input/input.c @@ -1879,35 +1879,37 @@ static int input_open_file(struct inode *inode, struct file *file) const struct file_operations *old_fops, *new_fops = NULL; int err; - lock_kernel(); + err = mutex_lock_interruptible(&input_mutex); + if (err) + return err; + /* No load-on-demand here? */ handler = input_table[iminor(inode) >> 5]; - if (!handler || !(new_fops = fops_get(handler->fops))) { - err = -ENODEV; - goto out; - } + if (handler) + new_fops = fops_get(handler->fops); + + mutex_unlock(&input_mutex); /* * That's _really_ odd. Usually NULL ->open means "nothing special", * not "no device". Oh, well... */ - if (!new_fops->open) { + if (!new_fops || !new_fops->open) { fops_put(new_fops); err = -ENODEV; goto out; } + old_fops = file->f_op; file->f_op = new_fops; err = new_fops->open(inode, file); - if (err) { fops_put(file->f_op); file->f_op = fops_get(old_fops); } fops_put(old_fops); out: - unlock_kernel(); return err; } -- cgit v1.2.3 From eb8bff85c5bd5caef7c374ff32b86545029efb56 Mon Sep 17 00:00:00 2001 From: Thomas Bächler Date: Tue, 9 Mar 2010 20:38:48 -0800 Subject: Input: alps - add support for the touchpad on Toshiba Tecra A11-11L MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Thomas Bächler Cc: stable@kernel.org Signed-off-by: Dmitry Torokhov --- drivers/input/mouse/alps.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers/input') diff --git a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c index f93c2c0daf1f..f6dad83539e0 100644 --- a/drivers/input/mouse/alps.c +++ b/drivers/input/mouse/alps.c @@ -63,6 +63,8 @@ static const struct alps_model_info alps_model_data[] = { { { 0x62, 0x02, 0x14 }, 0xcf, 0xcf, ALPS_PASS | ALPS_DUALPOINT | ALPS_PS2_INTERLEAVED }, { { 0x73, 0x02, 0x50 }, 0xcf, 0xcf, ALPS_FOUR_BUTTONS }, /* Dell Vostro 1400 */ + { { 0x52, 0x01, 0x14 }, 0xff, 0xff, + ALPS_PASS | ALPS_DUALPOINT | ALPS_PS2_INTERLEAVED }, /* Toshiba Tecra A11-11L */ }; /* -- cgit v1.2.3 From 9e49f6c1339a7972e23a335c4c71a289b4c6f65b Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Tue, 9 Mar 2010 20:38:45 -0800 Subject: Input: bf54x-keys - fix system hang when pressing a key We need to use the nosync version of disable_irq so that we don't hang in the IRQ handler as we don't ACK the interrupt until later. This used to work regardless, but at some point, the IRQ behavior changed. Not sure when exactly. Signed-off-by: Mike Frysinger Signed-off-by: Dmitry Torokhov --- drivers/input/keyboard/bf54x-keys.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/input') diff --git a/drivers/input/keyboard/bf54x-keys.c b/drivers/input/keyboard/bf54x-keys.c index fe376a27fe57..593c052416b9 100644 --- a/drivers/input/keyboard/bf54x-keys.c +++ b/drivers/input/keyboard/bf54x-keys.c @@ -162,7 +162,7 @@ static irqreturn_t bfin_kpad_isr(int irq, void *dev_id) input_sync(input); if (bfin_kpad_get_keypressed(bf54x_kpad)) { - disable_irq(bf54x_kpad->irq); + disable_irq_nosync(bf54x_kpad->irq); bf54x_kpad->lastkey = key; mod_timer(&bf54x_kpad->timer, jiffies + bf54x_kpad->keyup_test_jiffies); -- cgit v1.2.3 From 06a09124b5ec65f81df66c56695d9a9ae04a0114 Mon Sep 17 00:00:00 2001 From: Michael Hennerich Date: Tue, 9 Mar 2010 20:38:45 -0800 Subject: Input: ads7846 - add support for AD7843 parts The AD7873 is almost identical to the ADS7846; the only difference is related to the Power Management bits PD0 and PD1. This results in a slightly different PENIRQ enable behavior. For the AD7873, VREF should be turned off during differential measurements. So, add the AD7873/43 to the list of driver supported devices, and prevent VREF usage during differential/ratiometric conversion modes. Signed-off-by: Michael Hennerich Signed-off-by: Mike Frysinger Signed-off-by: Dmitry Torokhov --- drivers/input/touchscreen/Kconfig | 9 +++++---- drivers/input/touchscreen/ads7846.c | 10 ++++++++++ include/linux/spi/ads7846.h | 2 +- 3 files changed, 16 insertions(+), 5 deletions(-) (limited to 'drivers/input') diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig index 7208654a94ae..8a8fa4d2d6a8 100644 --- a/drivers/input/touchscreen/Kconfig +++ b/drivers/input/touchscreen/Kconfig @@ -24,17 +24,18 @@ config TOUCHSCREEN_88PM860X module will be called 88pm860x-ts. config TOUCHSCREEN_ADS7846 - tristate "ADS7846/TSC2046 and ADS7843 based touchscreens" + tristate "ADS7846/TSC2046/AD7873 and AD(S)7843 based touchscreens" depends on SPI_MASTER depends on HWMON = n || HWMON help Say Y here if you have a touchscreen interface using the - ADS7846/TSC2046 or ADS7843 controller, and your board-specific - setup code includes that in its table of SPI devices. + ADS7846/TSC2046/AD7873 or ADS7843/AD7843 controller, + and your board-specific setup code includes that in its + table of SPI devices. If HWMON is selected, and the driver is told the reference voltage on your board, you will also get hwmon interfaces for the voltage - (and on ads7846/tsc2046, temperature) sensors of this chip. + (and on ads7846/tsc2046/ad7873, temperature) sensors of this chip. If unsure, say N (but it's safe to say "Y"). diff --git a/drivers/input/touchscreen/ads7846.c b/drivers/input/touchscreen/ads7846.c index 8b05d8e97543..d187be05955f 100644 --- a/drivers/input/touchscreen/ads7846.c +++ b/drivers/input/touchscreen/ads7846.c @@ -36,6 +36,7 @@ * TSC2046 is just newer ads7846 silicon. * Support for ads7843 tested on Atmel at91sam926x-EK. * Support for ads7845 has only been stubbed in. + * Support for Analog Devices AD7873 and AD7843 tested. * * IRQ handling needs a workaround because of a shortcoming in handling * edge triggered IRQs on some platforms like the OMAP1/2. These @@ -984,6 +985,15 @@ static int __devinit ads7846_probe(struct spi_device *spi) vref = pdata->keep_vref_on; + if (ts->model == 7873) { + /* The AD7873 is almost identical to the ADS7846 + * keep VREF off during differential/ratiometric + * conversion modes + */ + ts->model = 7846; + vref = 0; + } + /* set up the transfers to read touchscreen state; this assumes we * use formula #2 for pressure, not #3. */ diff --git a/include/linux/spi/ads7846.h b/include/linux/spi/ads7846.h index 51948eb6927a..5710c15d394a 100644 --- a/include/linux/spi/ads7846.h +++ b/include/linux/spi/ads7846.h @@ -12,7 +12,7 @@ enum ads7846_filter { }; struct ads7846_platform_data { - u16 model; /* 7843, 7845, 7846. */ + u16 model; /* 7843, 7845, 7846, 7873. */ u16 vref_delay_usecs; /* 0 for external vref; etc */ u16 vref_mv; /* external vref value, milliVolts */ bool keep_vref_on; /* set to keep vref on for differential -- cgit v1.2.3 From 4eb6f91b95e7618eae0103b6cba7c7f01f9d40f3 Mon Sep 17 00:00:00 2001 From: Michael Hennerich Date: Tue, 9 Mar 2010 20:38:47 -0800 Subject: Input: ad7877 - increase pen up imeout The time interval between consecutive interrupts depends on a number of tunables: first_conversion_delay, acquisition_time, averaging and foremost the pen_down_acc_interval. Since the mod_timer() action for the PEN UP event happens in the spi_async() callback function, latencies incurred by the spi bus drivers also need to be taken into account. So all in all, give the PEN UP event a bit more wiggle room and increase timeout to 100ms. Signed-off-by: Michael Hennerich Signed-off-by: Mike Frysinger Signed-off-by: Dmitry Torokhov --- drivers/input/touchscreen/ad7877.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/input') diff --git a/drivers/input/touchscreen/ad7877.c b/drivers/input/touchscreen/ad7877.c index eb83939c705e..e019d53d1ab4 100644 --- a/drivers/input/touchscreen/ad7877.c +++ b/drivers/input/touchscreen/ad7877.c @@ -46,7 +46,7 @@ #include #include -#define TS_PEN_UP_TIMEOUT msecs_to_jiffies(50) +#define TS_PEN_UP_TIMEOUT msecs_to_jiffies(100) #define MAX_SPI_FREQ_HZ 20000000 #define MAX_12BIT ((1<<12)-1) -- cgit v1.2.3 From 04b4b88cca0ebe3813b4b6f014fb6a0db380b137 Mon Sep 17 00:00:00 2001 From: Vadim Zaliva Date: Wed, 10 Mar 2010 23:41:00 -0800 Subject: Input: appletouch - fix integer overflow issue When reading data from Geyser 2 touchpads used on post Oct 2005 Apple PowerBooks the driver was casting X and Y coordinates values to 'signed char'. Testing on one of such PowerBooks I have noticed that touchpad always generates positive values, but some of them are greater that 127, and thus, when cast to 'signed char' being interpreted as a negative. Such bigger values have been observed infrequently, closer to the edges of a touchpad, so the problem was not very visible. Nevertheless, the patch would potentially improve touchpad driver accuracy. Signed-off-by: Vadim Zaliva Signed-off-by: Dmitry Torokhov --- drivers/input/mouse/appletouch.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/input') diff --git a/drivers/input/mouse/appletouch.c b/drivers/input/mouse/appletouch.c index 908b5b44052f..53ec7ddd1826 100644 --- a/drivers/input/mouse/appletouch.c +++ b/drivers/input/mouse/appletouch.c @@ -205,8 +205,8 @@ struct atp { bool overflow_warned; int x_old; /* last reported x/y, */ int y_old; /* used for smoothing */ - signed char xy_cur[ATP_XSENSORS + ATP_YSENSORS]; - signed char xy_old[ATP_XSENSORS + ATP_YSENSORS]; + u8 xy_cur[ATP_XSENSORS + ATP_YSENSORS]; + u8 xy_old[ATP_XSENSORS + ATP_YSENSORS]; int xy_acc[ATP_XSENSORS + ATP_YSENSORS]; int idlecount; /* number of empty packets */ struct work_struct work; @@ -531,7 +531,7 @@ static void atp_complete_geyser_1_2(struct urb *urb) for (i = 0; i < ATP_XSENSORS + ATP_YSENSORS; i++) { /* accumulate the change */ - signed char change = dev->xy_old[i] - dev->xy_cur[i]; + int change = dev->xy_old[i] - dev->xy_cur[i]; dev->xy_acc[i] -= change; /* prevent down drifting */ -- cgit v1.2.3 From fdba2bb1f2eed85085a0fe154e1acb82de3239f7 Mon Sep 17 00:00:00 2001 From: Ranjith Lohithakshan Date: Wed, 10 Mar 2010 23:41:22 -0800 Subject: Input: ads7846 - add wakeup support Add wakeup support to the ads7846 driver. Platforms can enable wakeup capability by setting the wakeup flag in ads7846_platform_data. With this patch the ads7846 driver can be used to wake the system from suspend. Signed-off-by: Ranjith Lohithakshan Signed-off-by: Dmitry Torokhov --- drivers/input/touchscreen/ads7846.c | 10 ++++++++++ include/linux/spi/ads7846.h | 1 + 2 files changed, 11 insertions(+) (limited to 'drivers/input') diff --git a/drivers/input/touchscreen/ads7846.c b/drivers/input/touchscreen/ads7846.c index d187be05955f..532279cda0e4 100644 --- a/drivers/input/touchscreen/ads7846.c +++ b/drivers/input/touchscreen/ads7846.c @@ -822,6 +822,9 @@ static int ads7846_suspend(struct spi_device *spi, pm_message_t message) spin_unlock_irq(&ts->lock); + if (device_may_wakeup(&ts->spi->dev)) + enable_irq_wake(ts->spi->irq); + return 0; } @@ -830,6 +833,9 @@ static int ads7846_resume(struct spi_device *spi) { struct ads7846 *ts = dev_get_drvdata(&spi->dev); + if (device_may_wakeup(&ts->spi->dev)) + disable_irq_wake(ts->spi->irq); + spin_lock_irq(&ts->lock); ts->is_suspended = 0; @@ -1201,6 +1207,8 @@ static int __devinit ads7846_probe(struct spi_device *spi) if (err) goto err_remove_attr_group; + device_init_wakeup(&spi->dev, pdata->wakeup); + return 0; err_remove_attr_group: @@ -1230,6 +1238,8 @@ static int __devexit ads7846_remove(struct spi_device *spi) { struct ads7846 *ts = dev_get_drvdata(&spi->dev); + device_init_wakeup(&spi->dev, false); + ads784x_hwmon_unregister(spi, ts); input_unregister_device(ts->input); diff --git a/include/linux/spi/ads7846.h b/include/linux/spi/ads7846.h index 5710c15d394a..b4ae570d3c98 100644 --- a/include/linux/spi/ads7846.h +++ b/include/linux/spi/ads7846.h @@ -53,5 +53,6 @@ struct ads7846_platform_data { int (*filter) (void *filter_data, int data_idx, int *val); void (*filter_cleanup)(void *filter_data); void (*wait_for_sync)(void); + bool wakeup; }; -- cgit v1.2.3 From afadb8e08c48d08b75f3caf8404742b13e6b3624 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Wed, 10 Mar 2010 23:41:33 -0800 Subject: Input: wm831x-on - convert to use genirq Now that the WM831x core has been converted to use genirq for the interrupt controller there is no need for the client drivers to use a WM831x-specific API rather than just calling genirq directly. Also fixes a leak of the IRQ during init failure - the error path free_irq() was using NULL rather than the driver data as the data pointer so free_irq() wouldn't have matched. Signed-off-by: Mark Brown Signed-off-by: Dmitry Torokhov --- drivers/input/misc/wm831x-on.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'drivers/input') diff --git a/drivers/input/misc/wm831x-on.c b/drivers/input/misc/wm831x-on.c index ba4f5dd7c60e..1e54bce72db5 100644 --- a/drivers/input/misc/wm831x-on.c +++ b/drivers/input/misc/wm831x-on.c @@ -97,8 +97,9 @@ static int __devinit wm831x_on_probe(struct platform_device *pdev) wm831x_on->dev->phys = "wm831x_on/input0"; wm831x_on->dev->dev.parent = &pdev->dev; - ret = wm831x_request_irq(wm831x, irq, wm831x_on_irq, - IRQF_TRIGGER_RISING, "wm831x_on", wm831x_on); + ret = request_threaded_irq(irq, NULL, wm831x_on_irq, + IRQF_TRIGGER_RISING, "wm831x_on", + wm831x_on); if (ret < 0) { dev_err(&pdev->dev, "Unable to request IRQ: %d\n", ret); goto err_input_dev; @@ -114,7 +115,7 @@ static int __devinit wm831x_on_probe(struct platform_device *pdev) return 0; err_irq: - wm831x_free_irq(wm831x, irq, NULL); + free_irq(irq, wm831x_on); err_input_dev: input_free_device(wm831x_on->dev); err: @@ -127,7 +128,7 @@ static int __devexit wm831x_on_remove(struct platform_device *pdev) struct wm831x_on *wm831x_on = platform_get_drvdata(pdev); int irq = platform_get_irq(pdev, 0); - wm831x_free_irq(wm831x_on->wm831x, irq, wm831x_on); + free_irq(irq, wm831x_on); cancel_delayed_work_sync(&wm831x_on->work); input_unregister_device(wm831x_on->dev); kfree(wm831x_on); -- cgit v1.2.3 From c91ed059a080c6f9a7ba525e5027c65d19115d15 Mon Sep 17 00:00:00 2001 From: Martin Buck Date: Sat, 13 Mar 2010 22:23:58 -0800 Subject: Input: ALPS - fix stuck buttons on some touchpads Enable button release event redirection to the device that got the button press not only for touchpads with interleaved protocols, but unconditionally for all Alps touchpads. This is required at least for the touchpads in Dell Inspiron 8200 and Latitude d630. Signed-off-by: Martin Buck Signed-off-by: Dmitry Torokhov --- drivers/input/mouse/alps.c | 47 +++++++++++++++++----------------------------- 1 file changed, 17 insertions(+), 30 deletions(-) (limited to 'drivers/input') diff --git a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c index f6dad83539e0..7490f1da4a53 100644 --- a/drivers/input/mouse/alps.c +++ b/drivers/input/mouse/alps.c @@ -120,40 +120,27 @@ static void alps_report_buttons(struct psmouse *psmouse, struct input_dev *dev1, struct input_dev *dev2, int left, int right, int middle) { - struct alps_data *priv = psmouse->private; - const struct alps_model_info *model = priv->i; - - if (model->flags & ALPS_PS2_INTERLEAVED) { - struct input_dev *dev; + struct input_dev *dev; - /* - * If shared button has already been reported on the - * other device (dev2) then this event should be also - * sent through that device. - */ - dev = test_bit(BTN_LEFT, dev2->key) ? dev2 : dev1; - input_report_key(dev, BTN_LEFT, left); + /* + * If shared button has already been reported on the + * other device (dev2) then this event should be also + * sent through that device. + */ + dev = test_bit(BTN_LEFT, dev2->key) ? dev2 : dev1; + input_report_key(dev, BTN_LEFT, left); - dev = test_bit(BTN_RIGHT, dev2->key) ? dev2 : dev1; - input_report_key(dev, BTN_RIGHT, right); + dev = test_bit(BTN_RIGHT, dev2->key) ? dev2 : dev1; + input_report_key(dev, BTN_RIGHT, right); - dev = test_bit(BTN_MIDDLE, dev2->key) ? dev2 : dev1; - input_report_key(dev, BTN_MIDDLE, middle); + dev = test_bit(BTN_MIDDLE, dev2->key) ? dev2 : dev1; + input_report_key(dev, BTN_MIDDLE, middle); - /* - * Sync the _other_ device now, we'll do the first - * device later once we report the rest of the events. - */ - input_sync(dev2); - } else { - /* - * For devices with non-interleaved packets we know what - * device buttons belong to so we can simply report them. - */ - input_report_key(dev1, BTN_LEFT, left); - input_report_key(dev1, BTN_RIGHT, right); - input_report_key(dev1, BTN_MIDDLE, middle); - } + /* + * Sync the _other_ device now, we'll do the first + * device later once we report the rest of the events. + */ + input_sync(dev2); } static void alps_process_packet(struct psmouse *psmouse) -- cgit v1.2.3 From 31968ecf584330b51a25b7bf881c2b632a02a3fb Mon Sep 17 00:00:00 2001 From: Christoph Fritz Date: Sat, 13 Mar 2010 22:26:23 -0800 Subject: Input: i8042 - add ALDI/MEDION netbook E1222 to qurik reset table ALDI/MEDION netbook E1222 needs to be in the reset quirk list for its touchpad's proper function. Reported-by: Michael Fischer Signed-off-by: Christoph Fritz Cc: stable@kernel.org Signed-off-by: Dmitry Torokhov --- drivers/input/serio/i8042-x86ia64io.h | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'drivers/input') diff --git a/drivers/input/serio/i8042-x86ia64io.h b/drivers/input/serio/i8042-x86ia64io.h index 3696cab40598..ead0494721d0 100644 --- a/drivers/input/serio/i8042-x86ia64io.h +++ b/drivers/input/serio/i8042-x86ia64io.h @@ -441,6 +441,13 @@ static const struct dmi_system_id __initconst i8042_dmi_reset_table[] = { DMI_MATCH(DMI_PRODUCT_NAME, "E1210"), }, }, + { + /* Medion Akoya E1222 */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "MEDION"), + DMI_MATCH(DMI_PRODUCT_NAME, "E122X"), + }, + }, { /* Mivvy M310 */ .matches = { -- cgit v1.2.3