From 83cb16727085b18191f45eb0ede6bf1f97d67a7a Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Wed, 14 Oct 2009 17:48:38 +0200 Subject: nvram: Drop the BKL from nvram_open() It's safe to remove the BKL from nvram_open(): there's no open() versus read() races: nvram_init() is very simple and race-free, it registers the device then puts it into /proc - there's no state init to race with. Cc: Wim Van Sebroeck Cc: Al Viro Cc: Frederic Weisbecker Cc: Thomas Gleixner LKML-Reference: <1255116426-7270-1-git-send-email-fweisbec@gmail.com> Signed-off-by: Ingo Molnar --- drivers/char/nvram.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'drivers') diff --git a/drivers/char/nvram.c b/drivers/char/nvram.c index 2100a8f7bd86..7cf4518c030f 100644 --- a/drivers/char/nvram.c +++ b/drivers/char/nvram.c @@ -329,14 +329,12 @@ static int nvram_ioctl(struct inode *inode, struct file *file, static int nvram_open(struct inode *inode, struct file *file) { - lock_kernel(); spin_lock(&nvram_state_lock); if ((nvram_open_cnt && (file->f_flags & O_EXCL)) || (nvram_open_mode & NVRAM_EXCL) || ((file->f_mode & FMODE_WRITE) && (nvram_open_mode & NVRAM_WRITE))) { spin_unlock(&nvram_state_lock); - unlock_kernel(); return -EBUSY; } @@ -347,7 +345,6 @@ static int nvram_open(struct inode *inode, struct file *file) nvram_open_cnt++; spin_unlock(&nvram_state_lock); - unlock_kernel(); return 0; } -- cgit v1.2.2 From b45d44e7e00c1726dac9437b66c05d3d27acb3f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicolas=20L=C3=A9veill=C3=A9?= 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') 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.2 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') 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.2 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 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) (limited to 'drivers') 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; } -- cgit v1.2.2 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') 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.2 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') 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.2 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 +----- 1 file changed, 1 insertion(+), 5 deletions(-) (limited to 'drivers') 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); -- cgit v1.2.2 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') 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.2 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') 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.2 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') 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.2 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') 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.2 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') 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.2 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') 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.2 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') 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.2 From ce7b39a181571ed5a87f3ca62d4cffe4835c6ae9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1rton=20N=C3=A9meth?= 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') 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.2 From ef9a16f15dccba6630d8860a964a4adef1a4ab98 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1rton=20N=C3=A9meth?= 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') 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.2 From a9844b18502bde376284e4ad83b04fa20eb5afa5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1rton=20N=C3=A9meth?= 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') 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.2 From 35c4b918a696f20cb775f1a65955c8ed0fe7c052 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1rton=20N=C3=A9meth?= 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') 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.2 From c6d5709384090de541158a6bba8d4ae50242ff94 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1rton=20N=C3=A9meth?= 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') 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.2 From 9cb3ce52ca45d089d5be90d2f34005296fc5a34e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1rton=20N=C3=A9meth?= 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') 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.2 From 3d447ec0e30043a2acd52704f5ed1da07a6f2d6e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1rton=20N=C3=A9meth?= Date: Sun, 10 Jan 2010 13:39:29 +0100 Subject: block: make PCI device id 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 is worth to make the initialization data also constant. The semantic match that finds this kind of pattern is as follows: (http://coccinelle.lip6.fr/) // @r@ disable decl_init,const_decl_init; identifier I1, I2, x; @@ struct I1 { ... const struct I2 *x; ... }; @s@ identifier r.I1, y; identifier r.x, E; @@ struct I1 y = { .x = E, }; @c@ identifier r.I2; identifier s.E; @@ const struct I2 E[] = ... ; @depends on !c@ identifier r.I2; identifier s.E; @@ + const struct I2 E[] = ...; // Signed-off-by: Márton Németh Cc: Julia Lawall Cc: cocci@diku.dk Signed-off-by: Jens Axboe --- drivers/block/DAC960.c | 2 +- drivers/block/sx8.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/block/DAC960.c b/drivers/block/DAC960.c index ce1fa923c414..7412b5d4f5f3 100644 --- a/drivers/block/DAC960.c +++ b/drivers/block/DAC960.c @@ -7134,7 +7134,7 @@ static struct DAC960_privdata DAC960_P_privdata = { .MemoryWindowSize = DAC960_PD_RegisterWindowSize, }; -static struct pci_device_id DAC960_id_table[] = { +static const struct pci_device_id DAC960_id_table[] = { { .vendor = PCI_VENDOR_ID_MYLEX, .device = PCI_DEVICE_ID_MYLEX_DAC960_GEM, diff --git a/drivers/block/sx8.c b/drivers/block/sx8.c index a7c4184f4a63..7bd7b2f83116 100644 --- a/drivers/block/sx8.c +++ b/drivers/block/sx8.c @@ -409,7 +409,7 @@ static int carm_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) static void carm_remove_one (struct pci_dev *pdev); static int carm_bdev_getgeo(struct block_device *bdev, struct hd_geometry *geo); -static struct pci_device_id carm_pci_tbl[] = { +static const struct pci_device_id carm_pci_tbl[] = { { PCI_VENDOR_ID_PROMISE, 0x8000, PCI_ANY_ID, PCI_ANY_ID, 0, 0, }, { PCI_VENDOR_ID_PROMISE, 0x8002, PCI_ANY_ID, PCI_ANY_ID, 0, 0, }, { } /* terminate list */ -- cgit v1.2.2 From 577cdf0cf5afa5f350fbaddf77bbacdb9f76d2f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1rton=20N=C3=A9meth?= Date: Sun, 10 Jan 2010 13:39:39 +0100 Subject: block: make USB device id 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 is worth to make ub_usb_ids also constant. The semantic match that finds this kind of pattern is as follows: (http://coccinelle.lip6.fr/) // @r@ disable decl_init,const_decl_init; identifier I1, I2, x; @@ struct I1 { ... const struct I2 *x; ... }; @s@ identifier r.I1, y; identifier r.x, E; @@ struct I1 y = { .x = E, }; @c@ identifier r.I2; identifier s.E; @@ const struct I2 E[] = ... ; @depends on !c@ identifier r.I2; identifier s.E; @@ + const struct I2 E[] = ...; // Signed-off-by: Márton Németh Cc: Julia Lawall Cc: cocci@diku.dk Signed-off-by: Jens Axboe --- drivers/block/ub.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/block/ub.c b/drivers/block/ub.c index c739b203fe91..d86d1357ccef 100644 --- a/drivers/block/ub.c +++ b/drivers/block/ub.c @@ -393,7 +393,7 @@ static int ub_probe_lun(struct ub_dev *sc, int lnum); #define ub_usb_ids usb_storage_usb_ids #else -static struct usb_device_id ub_usb_ids[] = { +static const struct usb_device_id ub_usb_ids[] = { { USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_SCSI, US_PR_BULK) }, { } }; -- cgit v1.2.2 From 5cccfd9b3a9ca06b6245ea2c4af052b7db0105a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1rton=20N=C3=A9meth?= Date: Sun, 10 Jan 2010 13:39:46 +0100 Subject: block: make Open Firmware device id 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 is worth to make ace_of_match also constant. The semantic match that finds this kind of pattern is as follows: (http://coccinelle.lip6.fr/) // @r@ disable decl_init,const_decl_init; identifier I1, I2, x; @@ struct I1 { ... const struct I2 *x; ... }; @s@ identifier r.I1, y; identifier r.x, E; @@ struct I1 y = { .x = E, }; @c@ identifier r.I2; identifier s.E; @@ const struct I2 E[] = ... ; @depends on !c@ identifier r.I2; identifier s.E; @@ + const struct I2 E[] = ...; // Signed-off-by: Márton Németh Cc: Julia Lawall Cc: cocci@diku.dk Signed-off-by: Jens Axboe --- drivers/block/xsysace.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/block/xsysace.c b/drivers/block/xsysace.c index e5c5415eb45e..e1c95e208a66 100644 --- a/drivers/block/xsysace.c +++ b/drivers/block/xsysace.c @@ -1227,7 +1227,7 @@ static int __devexit ace_of_remove(struct of_device *op) } /* Match table for of_platform binding */ -static struct of_device_id ace_of_match[] __devinitdata = { +static const struct of_device_id ace_of_match[] __devinitconst = { { .compatible = "xlnx,opb-sysace-1.00.b", }, { .compatible = "xlnx,opb-sysace-1.00.c", }, { .compatible = "xlnx,xps-sysace-1.00.a", }, -- cgit v1.2.2 From ec9c42ec793d428e99fdd219867b31932034b138 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1rton=20N=C3=A9meth?= Date: Sun, 10 Jan 2010 13:39:52 +0100 Subject: block: make xenbus device id 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 is worth to make blkfront_ids also constant. The semantic match that finds this kind of pattern is as follows: (http://coccinelle.lip6.fr/) // @r@ disable decl_init,const_decl_init; identifier I1, I2, x; @@ struct I1 { ... const struct I2 *x; ... }; @s@ identifier r.I1, y; identifier r.x, E; @@ struct I1 y = { .x = E, }; @c@ identifier r.I2; identifier s.E; @@ const struct I2 E[] = ... ; @depends on !c@ identifier r.I2; identifier s.E; @@ + const struct I2 E[] = ...; // Signed-off-by: Márton Németh Cc: Julia Lawall Cc: cocci@diku.dk Signed-off-by: Jens Axboe --- drivers/block/xen-blkfront.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/block/xen-blkfront.c b/drivers/block/xen-blkfront.c index 05a31e55d278..a84702d1a35e 100644 --- a/drivers/block/xen-blkfront.c +++ b/drivers/block/xen-blkfront.c @@ -1050,7 +1050,7 @@ static const struct block_device_operations xlvbd_block_fops = }; -static struct xenbus_device_id blkfront_ids[] = { +static const struct xenbus_device_id blkfront_ids[] = { { "vbd" }, { "" } }; -- cgit v1.2.2 From 47483e25205f1f8d79784f0f7c733941bc080ec0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1rton=20N=C3=A9meth?= Date: Sun, 10 Jan 2010 13:40:02 +0100 Subject: block: make virtio device id constant MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The id_table field of the struct virtio_driver is constant in so it is worth to make id_table also constant. The semantic match that finds this kind of pattern is as follows: (http://coccinelle.lip6.fr/) // @r@ disable decl_init,const_decl_init; identifier I1, I2, x; @@ struct I1 { ... const struct I2 *x; ... }; @s@ identifier r.I1, y; identifier r.x, E; @@ struct I1 y = { .x = E, }; @c@ identifier r.I2; identifier s.E; @@ const struct I2 E[] = ... ; @depends on !c@ identifier r.I2; identifier s.E; @@ + const struct I2 E[] = ...; // Signed-off-by: Márton Németh Cc: Julia Lawall Cc: cocci@diku.dk Signed-off-by: Jens Axboe --- drivers/block/virtio_blk.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c index 51042f0ba7e1..c17e622f85ee 100644 --- a/drivers/block/virtio_blk.c +++ b/drivers/block/virtio_blk.c @@ -404,7 +404,7 @@ static void __devexit virtblk_remove(struct virtio_device *vdev) kfree(vblk); } -static struct virtio_device_id id_table[] = { +static const struct virtio_device_id id_table[] = { { VIRTIO_ID_BLOCK, VIRTIO_DEV_ANY_ID }, { 0 }, }; -- cgit v1.2.2 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 --- drivers/input/keyboard/ep93xx_keypad.c | 40 +++++++++++++--------------------- 1 file changed, 15 insertions(+), 25 deletions(-) (limited to 'drivers') 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.2 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') 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.2 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 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') 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; -- cgit v1.2.2 From 2147d3f00f85c9e993786863d8138694672da01b Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Thu, 21 Jan 2010 09:08:31 +0800 Subject: ACPICA: Update for new gcc-4 warning options Added several new options for the gcc-4 generation, and updated the source accordingly. This includes some code restructuring to eliminate unreachable code, elimination of some gotos, elimination of unused return values, and some additional casting. Signed-off-by: Bob Moore Signed-off-by: Lin Ming Signed-off-by: Len Brown --- drivers/acpi/acpica/exconfig.c | 13 +++++-------- drivers/acpi/acpica/hwgpe.c | 6 ++---- drivers/acpi/acpica/nspredef.c | 24 +++++++++++------------- drivers/acpi/acpica/nsrepair2.c | 24 +++++++++--------------- drivers/acpi/acpica/utmutex.c | 16 +++------------- 5 files changed, 30 insertions(+), 53 deletions(-) (limited to 'drivers') diff --git a/drivers/acpi/acpica/exconfig.c b/drivers/acpi/acpica/exconfig.c index 46adfa541cbc..2ea8daccba1c 100644 --- a/drivers/acpi/acpica/exconfig.c +++ b/drivers/acpi/acpica/exconfig.c @@ -490,7 +490,11 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc, status = acpi_tb_add_table(&table_desc, &table_index); if (ACPI_FAILURE(status)) { - goto cleanup; + + /* Delete allocated table buffer */ + + acpi_tb_delete_table(&table_desc); + return_ACPI_STATUS(status); } /* @@ -533,13 +537,6 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc, acpi_gbl_table_handler_context); } - cleanup: - if (ACPI_FAILURE(status)) { - - /* Delete allocated table buffer */ - - acpi_tb_delete_table(&table_desc); - } return_ACPI_STATUS(status); } diff --git a/drivers/acpi/acpica/hwgpe.c b/drivers/acpi/acpica/hwgpe.c index c28c41b3180b..55c4507957bb 100644 --- a/drivers/acpi/acpica/hwgpe.c +++ b/drivers/acpi/acpica/hwgpe.c @@ -224,7 +224,7 @@ acpi_hw_get_gpe_status(struct acpi_gpe_event_info * gpe_event_info, status = acpi_hw_read(&in_byte, &gpe_register_info->status_address); if (ACPI_FAILURE(status)) { - goto unlock_and_exit; + return (status); } if (register_bit & in_byte) { @@ -234,9 +234,7 @@ acpi_hw_get_gpe_status(struct acpi_gpe_event_info * gpe_event_info, /* Set return value */ (*event_status) = local_event_status; - - unlock_and_exit: - return (status); + return (AE_OK); } /****************************************************************************** diff --git a/drivers/acpi/acpica/nspredef.c b/drivers/acpi/acpica/nspredef.c index d34fa59548f7..309586f5809c 100644 --- a/drivers/acpi/acpica/nspredef.c +++ b/drivers/acpi/acpica/nspredef.c @@ -1000,27 +1000,25 @@ acpi_ns_check_object_type(struct acpi_predefined_data *data, /* Is the object one of the expected types? */ - if (!(return_btype & expected_btypes)) { + if (return_btype & expected_btypes) { - /* Type mismatch -- attempt repair of the returned object */ + /* For reference objects, check that the reference type is correct */ - status = acpi_ns_repair_object(data, expected_btypes, - package_index, - return_object_ptr); - if (ACPI_SUCCESS(status)) { - return (AE_OK); /* Repair was successful */ + if (return_object->common.type == ACPI_TYPE_LOCAL_REFERENCE) { + status = acpi_ns_check_reference(data, return_object); } - goto type_error_exit; + + return (status); } - /* For reference objects, check that the reference type is correct */ + /* Type mismatch -- attempt repair of the returned object */ - if (return_object->common.type == ACPI_TYPE_LOCAL_REFERENCE) { - status = acpi_ns_check_reference(data, return_object); + status = acpi_ns_repair_object(data, expected_btypes, + package_index, return_object_ptr); + if (ACPI_SUCCESS(status)) { + return (AE_OK); /* Repair was successful */ } - return (status); - type_error_exit: /* Create a string with all expected types for this predefined object */ diff --git a/drivers/acpi/acpica/nsrepair2.c b/drivers/acpi/acpica/nsrepair2.c index f13691c1cca5..6d6926466a08 100644 --- a/drivers/acpi/acpica/nsrepair2.c +++ b/drivers/acpi/acpica/nsrepair2.c @@ -93,7 +93,7 @@ acpi_ns_check_sorted_list(struct acpi_predefined_data *data, u32 sort_index, u8 sort_direction, char *sort_key_name); -static acpi_status +static void acpi_ns_sort_list(union acpi_operand_object **elements, u32 count, u32 index, u8 sort_direction); @@ -443,7 +443,6 @@ acpi_ns_check_sorted_list(struct acpi_predefined_data *data, union acpi_operand_object *obj_desc; u32 i; u32 previous_value; - acpi_status status; ACPI_FUNCTION_NAME(ns_check_sorted_list); @@ -494,19 +493,15 @@ acpi_ns_check_sorted_list(struct acpi_predefined_data *data, /* * The list must be sorted in the specified order. If we detect a - * discrepancy, issue a warning and sort the entire list + * discrepancy, sort the entire list. */ if (((sort_direction == ACPI_SORT_ASCENDING) && (obj_desc->integer.value < previous_value)) || ((sort_direction == ACPI_SORT_DESCENDING) && (obj_desc->integer.value > previous_value))) { - status = - acpi_ns_sort_list(return_object->package.elements, - outer_element_count, sort_index, - sort_direction); - if (ACPI_FAILURE(status)) { - return (status); - } + acpi_ns_sort_list(return_object->package.elements, + outer_element_count, sort_index, + sort_direction); data->flags |= ACPI_OBJECT_REPAIRED; @@ -615,15 +610,16 @@ acpi_ns_remove_null_elements(struct acpi_predefined_data *data, * Index - Sort by which package element * sort_direction - Ascending or Descending sort * - * RETURN: Status + * RETURN: None * * DESCRIPTION: Sort the objects that are in a package element list. * - * NOTE: Assumes that all NULL elements have been removed from the package. + * NOTE: Assumes that all NULL elements have been removed from the package, + * and that all elements have been verified to be of type Integer. * *****************************************************************************/ -static acpi_status +static void acpi_ns_sort_list(union acpi_operand_object **elements, u32 count, u32 index, u8 sort_direction) { @@ -652,6 +648,4 @@ acpi_ns_sort_list(union acpi_operand_object **elements, } } } - - return (AE_OK); } diff --git a/drivers/acpi/acpica/utmutex.c b/drivers/acpi/acpica/utmutex.c index 80bb65154117..1f58a8824146 100644 --- a/drivers/acpi/acpica/utmutex.c +++ b/drivers/acpi/acpica/utmutex.c @@ -50,7 +50,7 @@ ACPI_MODULE_NAME("utmutex") /* Local prototypes */ static acpi_status acpi_ut_create_mutex(acpi_mutex_handle mutex_id); -static acpi_status acpi_ut_delete_mutex(acpi_mutex_handle mutex_id); +static void acpi_ut_delete_mutex(acpi_mutex_handle mutex_id); /******************************************************************************* * @@ -114,7 +114,7 @@ void acpi_ut_mutex_terminate(void) /* Delete each predefined mutex object */ for (i = 0; i < ACPI_NUM_MUTEX; i++) { - (void)acpi_ut_delete_mutex(i); + acpi_ut_delete_mutex(i); } /* Delete the spinlocks */ @@ -146,10 +146,6 @@ static acpi_status acpi_ut_create_mutex(acpi_mutex_handle mutex_id) ACPI_FUNCTION_TRACE_U32(ut_create_mutex, mutex_id); - if (mutex_id > ACPI_MAX_MUTEX) { - return_ACPI_STATUS(AE_BAD_PARAMETER); - } - if (!acpi_gbl_mutex_info[mutex_id].mutex) { status = acpi_os_create_mutex(&acpi_gbl_mutex_info[mutex_id].mutex); @@ -173,21 +169,15 @@ static acpi_status acpi_ut_create_mutex(acpi_mutex_handle mutex_id) * ******************************************************************************/ -static acpi_status acpi_ut_delete_mutex(acpi_mutex_handle mutex_id) +static void acpi_ut_delete_mutex(acpi_mutex_handle mutex_id) { ACPI_FUNCTION_TRACE_U32(ut_delete_mutex, mutex_id); - if (mutex_id > ACPI_MAX_MUTEX) { - return_ACPI_STATUS(AE_BAD_PARAMETER); - } - acpi_os_delete_mutex(acpi_gbl_mutex_info[mutex_id].mutex); acpi_gbl_mutex_info[mutex_id].mutex = NULL; acpi_gbl_mutex_info[mutex_id].thread_id = ACPI_MUTEX_NOT_ACQUIRED; - - return_ACPI_STATUS(AE_OK); } /******************************************************************************* -- cgit v1.2.2 From a8357b0c95484b46944728712f8810d3b37bf588 Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Fri, 22 Jan 2010 19:07:36 +0800 Subject: ACPICA: Update all ACPICA copyrights and signons to 2010 Add 2010 copyright to all module headers and signons, including the Linux header. This affects virtually every file in the ACPICA core subsystem, iASL compiler, and all utilities. Signed-off-by: Bob Moore Signed-off-by: Lin Ming Signed-off-by: Len Brown --- drivers/acpi/acpica/accommon.h | 2 +- drivers/acpi/acpica/acconfig.h | 2 +- drivers/acpi/acpica/acdebug.h | 2 +- drivers/acpi/acpica/acdispat.h | 2 +- drivers/acpi/acpica/acevents.h | 2 +- drivers/acpi/acpica/acglobal.h | 2 +- drivers/acpi/acpica/achware.h | 2 +- drivers/acpi/acpica/acinterp.h | 2 +- drivers/acpi/acpica/aclocal.h | 2 +- drivers/acpi/acpica/acmacros.h | 2 +- drivers/acpi/acpica/acnamesp.h | 2 +- drivers/acpi/acpica/acobject.h | 2 +- drivers/acpi/acpica/acopcode.h | 2 +- drivers/acpi/acpica/acparser.h | 2 +- drivers/acpi/acpica/acpredef.h | 2 +- drivers/acpi/acpica/acresrc.h | 2 +- drivers/acpi/acpica/acstruct.h | 2 +- drivers/acpi/acpica/actables.h | 2 +- drivers/acpi/acpica/acutils.h | 2 +- drivers/acpi/acpica/amlcode.h | 2 +- drivers/acpi/acpica/amlresrc.h | 2 +- drivers/acpi/acpica/dsfield.c | 2 +- drivers/acpi/acpica/dsinit.c | 2 +- drivers/acpi/acpica/dsmethod.c | 2 +- drivers/acpi/acpica/dsmthdat.c | 2 +- drivers/acpi/acpica/dsobject.c | 2 +- drivers/acpi/acpica/dsopcode.c | 2 +- drivers/acpi/acpica/dsutils.c | 2 +- drivers/acpi/acpica/dswexec.c | 2 +- drivers/acpi/acpica/dswload.c | 2 +- drivers/acpi/acpica/dswscope.c | 2 +- drivers/acpi/acpica/dswstate.c | 2 +- drivers/acpi/acpica/evevent.c | 2 +- drivers/acpi/acpica/evgpe.c | 2 +- drivers/acpi/acpica/evgpeblk.c | 2 +- drivers/acpi/acpica/evmisc.c | 2 +- drivers/acpi/acpica/evregion.c | 2 +- drivers/acpi/acpica/evrgnini.c | 2 +- drivers/acpi/acpica/evsci.c | 2 +- drivers/acpi/acpica/evxface.c | 2 +- drivers/acpi/acpica/evxfevnt.c | 2 +- drivers/acpi/acpica/evxfregn.c | 2 +- drivers/acpi/acpica/exconfig.c | 2 +- drivers/acpi/acpica/exconvrt.c | 2 +- drivers/acpi/acpica/excreate.c | 2 +- drivers/acpi/acpica/exdump.c | 2 +- drivers/acpi/acpica/exfield.c | 2 +- drivers/acpi/acpica/exfldio.c | 2 +- drivers/acpi/acpica/exmisc.c | 2 +- drivers/acpi/acpica/exmutex.c | 2 +- drivers/acpi/acpica/exnames.c | 2 +- drivers/acpi/acpica/exoparg1.c | 2 +- drivers/acpi/acpica/exoparg2.c | 2 +- drivers/acpi/acpica/exoparg3.c | 2 +- drivers/acpi/acpica/exoparg6.c | 2 +- drivers/acpi/acpica/exprep.c | 2 +- drivers/acpi/acpica/exregion.c | 2 +- drivers/acpi/acpica/exresnte.c | 2 +- drivers/acpi/acpica/exresolv.c | 2 +- drivers/acpi/acpica/exresop.c | 2 +- drivers/acpi/acpica/exstore.c | 2 +- drivers/acpi/acpica/exstoren.c | 2 +- drivers/acpi/acpica/exstorob.c | 2 +- drivers/acpi/acpica/exsystem.c | 2 +- drivers/acpi/acpica/exutils.c | 2 +- drivers/acpi/acpica/hwacpi.c | 2 +- drivers/acpi/acpica/hwgpe.c | 2 +- drivers/acpi/acpica/hwregs.c | 2 +- drivers/acpi/acpica/hwsleep.c | 2 +- drivers/acpi/acpica/hwtimer.c | 2 +- drivers/acpi/acpica/hwvalid.c | 2 +- drivers/acpi/acpica/hwxface.c | 2 +- drivers/acpi/acpica/nsaccess.c | 2 +- drivers/acpi/acpica/nsalloc.c | 2 +- drivers/acpi/acpica/nsdump.c | 2 +- drivers/acpi/acpica/nsdumpdv.c | 2 +- drivers/acpi/acpica/nseval.c | 2 +- drivers/acpi/acpica/nsinit.c | 2 +- drivers/acpi/acpica/nsload.c | 2 +- drivers/acpi/acpica/nsnames.c | 2 +- drivers/acpi/acpica/nsobject.c | 2 +- drivers/acpi/acpica/nsparse.c | 2 +- drivers/acpi/acpica/nspredef.c | 2 +- drivers/acpi/acpica/nsrepair.c | 2 +- drivers/acpi/acpica/nsrepair2.c | 2 +- drivers/acpi/acpica/nssearch.c | 2 +- drivers/acpi/acpica/nsutils.c | 2 +- drivers/acpi/acpica/nswalk.c | 2 +- drivers/acpi/acpica/nsxfeval.c | 2 +- drivers/acpi/acpica/nsxfname.c | 2 +- drivers/acpi/acpica/nsxfobj.c | 2 +- drivers/acpi/acpica/psargs.c | 2 +- drivers/acpi/acpica/psloop.c | 2 +- drivers/acpi/acpica/psopcode.c | 2 +- drivers/acpi/acpica/psparse.c | 2 +- drivers/acpi/acpica/psscope.c | 2 +- drivers/acpi/acpica/pstree.c | 2 +- drivers/acpi/acpica/psutils.c | 2 +- drivers/acpi/acpica/pswalk.c | 2 +- drivers/acpi/acpica/psxface.c | 2 +- drivers/acpi/acpica/rsaddr.c | 2 +- drivers/acpi/acpica/rscalc.c | 2 +- drivers/acpi/acpica/rscreate.c | 2 +- drivers/acpi/acpica/rsdump.c | 2 +- drivers/acpi/acpica/rsinfo.c | 2 +- drivers/acpi/acpica/rsio.c | 2 +- drivers/acpi/acpica/rsirq.c | 2 +- drivers/acpi/acpica/rslist.c | 2 +- drivers/acpi/acpica/rsmemory.c | 2 +- drivers/acpi/acpica/rsmisc.c | 2 +- drivers/acpi/acpica/rsutils.c | 2 +- drivers/acpi/acpica/rsxface.c | 2 +- drivers/acpi/acpica/tbfadt.c | 2 +- drivers/acpi/acpica/tbfind.c | 2 +- drivers/acpi/acpica/tbinstal.c | 2 +- drivers/acpi/acpica/tbutils.c | 2 +- drivers/acpi/acpica/tbxface.c | 2 +- drivers/acpi/acpica/tbxfroot.c | 2 +- drivers/acpi/acpica/utalloc.c | 2 +- drivers/acpi/acpica/utcopy.c | 2 +- drivers/acpi/acpica/utdebug.c | 2 +- drivers/acpi/acpica/utdelete.c | 2 +- drivers/acpi/acpica/uteval.c | 2 +- drivers/acpi/acpica/utglobal.c | 2 +- drivers/acpi/acpica/utids.c | 2 +- drivers/acpi/acpica/utinit.c | 2 +- drivers/acpi/acpica/utlock.c | 2 +- drivers/acpi/acpica/utmath.c | 2 +- drivers/acpi/acpica/utmisc.c | 2 +- drivers/acpi/acpica/utmutex.c | 2 +- drivers/acpi/acpica/utobject.c | 2 +- drivers/acpi/acpica/utresrc.c | 2 +- drivers/acpi/acpica/utstate.c | 2 +- drivers/acpi/acpica/utxface.c | 2 +- 134 files changed, 134 insertions(+), 134 deletions(-) (limited to 'drivers') diff --git a/drivers/acpi/acpica/accommon.h b/drivers/acpi/acpica/accommon.h index 3b20786cbb0d..3e50c74ed4a1 100644 --- a/drivers/acpi/acpica/accommon.h +++ b/drivers/acpi/acpica/accommon.h @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/acconfig.h b/drivers/acpi/acpica/acconfig.h index a4471e3d3853..33181ad350d5 100644 --- a/drivers/acpi/acpica/acconfig.h +++ b/drivers/acpi/acpica/acconfig.h @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/acdebug.h b/drivers/acpi/acpica/acdebug.h index a4fb001d96f1..48faf3eba9fb 100644 --- a/drivers/acpi/acpica/acdebug.h +++ b/drivers/acpi/acpica/acdebug.h @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/acdispat.h b/drivers/acpi/acpica/acdispat.h index 6291904be01e..894a0ff2a946 100644 --- a/drivers/acpi/acpica/acdispat.h +++ b/drivers/acpi/acpica/acdispat.h @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/acevents.h b/drivers/acpi/acpica/acevents.h index 0bba148a2c61..13d2b0bc2144 100644 --- a/drivers/acpi/acpica/acevents.h +++ b/drivers/acpi/acpica/acevents.h @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/acglobal.h b/drivers/acpi/acpica/acglobal.h index 29ba66d5a790..f8dd8f250ac4 100644 --- a/drivers/acpi/acpica/acglobal.h +++ b/drivers/acpi/acpica/acglobal.h @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/achware.h b/drivers/acpi/acpica/achware.h index 36192f142fbb..5900f135dc6d 100644 --- a/drivers/acpi/acpica/achware.h +++ b/drivers/acpi/acpica/achware.h @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/acinterp.h b/drivers/acpi/acpica/acinterp.h index 5db9f2916f7c..c9d7802f9118 100644 --- a/drivers/acpi/acpica/acinterp.h +++ b/drivers/acpi/acpica/acinterp.h @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/aclocal.h b/drivers/acpi/acpica/aclocal.h index 81e64f478679..2caf141076fc 100644 --- a/drivers/acpi/acpica/aclocal.h +++ b/drivers/acpi/acpica/aclocal.h @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/acmacros.h b/drivers/acpi/acpica/acmacros.h index 7d9ba6e57554..a4a9519a1288 100644 --- a/drivers/acpi/acpica/acmacros.h +++ b/drivers/acpi/acpica/acmacros.h @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/acnamesp.h b/drivers/acpi/acpica/acnamesp.h index 61edb156e8d0..73f9b0c88dd8 100644 --- a/drivers/acpi/acpica/acnamesp.h +++ b/drivers/acpi/acpica/acnamesp.h @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/acobject.h b/drivers/acpi/acpica/acobject.h index 64062b1be3ee..6d0b4de68cf6 100644 --- a/drivers/acpi/acpica/acobject.h +++ b/drivers/acpi/acpica/acobject.h @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/acopcode.h b/drivers/acpi/acpica/acopcode.h index dfdf63327885..8c15ff43f42b 100644 --- a/drivers/acpi/acpica/acopcode.h +++ b/drivers/acpi/acpica/acopcode.h @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/acparser.h b/drivers/acpi/acpica/acparser.h index 22881e8ce229..d0bb0fd3e57a 100644 --- a/drivers/acpi/acpica/acparser.h +++ b/drivers/acpi/acpica/acparser.h @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/acpredef.h b/drivers/acpi/acpica/acpredef.h index 57bdaf6ffab1..97116082cb6c 100644 --- a/drivers/acpi/acpica/acpredef.h +++ b/drivers/acpi/acpica/acpredef.h @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/acresrc.h b/drivers/acpi/acpica/acresrc.h index eef5bd7a59fa..528bcbaf4ce7 100644 --- a/drivers/acpi/acpica/acresrc.h +++ b/drivers/acpi/acpica/acresrc.h @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/acstruct.h b/drivers/acpi/acpica/acstruct.h index 7980a26bad35..161bc0e3d70a 100644 --- a/drivers/acpi/acpica/acstruct.h +++ b/drivers/acpi/acpica/acstruct.h @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/actables.h b/drivers/acpi/acpica/actables.h index 01c76b8ea7ba..8ff3b741df28 100644 --- a/drivers/acpi/acpica/actables.h +++ b/drivers/acpi/acpica/actables.h @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/acutils.h b/drivers/acpi/acpica/acutils.h index 3a451a21a3f9..d3ae626cf715 100644 --- a/drivers/acpi/acpica/acutils.h +++ b/drivers/acpi/acpica/acutils.h @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/amlcode.h b/drivers/acpi/acpica/amlcode.h index 4940249f2524..1f484ba228fc 100644 --- a/drivers/acpi/acpica/amlcode.h +++ b/drivers/acpi/acpica/amlcode.h @@ -7,7 +7,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/amlresrc.h b/drivers/acpi/acpica/amlresrc.h index 7b070e42b7c5..0e5798fcbb19 100644 --- a/drivers/acpi/acpica/amlresrc.h +++ b/drivers/acpi/acpica/amlresrc.h @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/dsfield.c b/drivers/acpi/acpica/dsfield.c index 54a225e56a64..effbf1550b03 100644 --- a/drivers/acpi/acpica/dsfield.c +++ b/drivers/acpi/acpica/dsfield.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/dsinit.c b/drivers/acpi/acpica/dsinit.c index f23fa0be6fc2..abe140318a74 100644 --- a/drivers/acpi/acpica/dsinit.c +++ b/drivers/acpi/acpica/dsinit.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/dsmethod.c b/drivers/acpi/acpica/dsmethod.c index e786f9fd767f..721039233aa7 100644 --- a/drivers/acpi/acpica/dsmethod.c +++ b/drivers/acpi/acpica/dsmethod.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/dsmthdat.c b/drivers/acpi/acpica/dsmthdat.c index 0ba19f84ad82..cc343b959540 100644 --- a/drivers/acpi/acpica/dsmthdat.c +++ b/drivers/acpi/acpica/dsmthdat.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/dsobject.c b/drivers/acpi/acpica/dsobject.c index 9bc1ba076347..edd7aa238cf1 100644 --- a/drivers/acpi/acpica/dsobject.c +++ b/drivers/acpi/acpica/dsobject.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/dsopcode.c b/drivers/acpi/acpica/dsopcode.c index b79978f7bc71..bf980cadb1e8 100644 --- a/drivers/acpi/acpica/dsopcode.c +++ b/drivers/acpi/acpica/dsopcode.c @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/dsutils.c b/drivers/acpi/acpica/dsutils.c index dfa104102926..306c62ab2e88 100644 --- a/drivers/acpi/acpica/dsutils.c +++ b/drivers/acpi/acpica/dsutils.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/dswexec.c b/drivers/acpi/acpica/dswexec.c index f0280856dc0e..6b76c486d784 100644 --- a/drivers/acpi/acpica/dswexec.c +++ b/drivers/acpi/acpica/dswexec.c @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/dswload.c b/drivers/acpi/acpica/dswload.c index b40513dd6a6a..140a9d002959 100644 --- a/drivers/acpi/acpica/dswload.c +++ b/drivers/acpi/acpica/dswload.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/dswscope.c b/drivers/acpi/acpica/dswscope.c index 908645e72f03..d1e701709dac 100644 --- a/drivers/acpi/acpica/dswscope.c +++ b/drivers/acpi/acpica/dswscope.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/dswstate.c b/drivers/acpi/acpica/dswstate.c index e46c821cf572..050df8164165 100644 --- a/drivers/acpi/acpica/dswstate.c +++ b/drivers/acpi/acpica/dswstate.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/evevent.c b/drivers/acpi/acpica/evevent.c index cd55c774e882..c1e6f472d435 100644 --- a/drivers/acpi/acpica/evevent.c +++ b/drivers/acpi/acpica/evevent.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/evgpe.c b/drivers/acpi/acpica/evgpe.c index afacf4416c73..1685ce37dd12 100644 --- a/drivers/acpi/acpica/evgpe.c +++ b/drivers/acpi/acpica/evgpe.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/evgpeblk.c b/drivers/acpi/acpica/evgpeblk.c index 247920900187..77670e04812d 100644 --- a/drivers/acpi/acpica/evgpeblk.c +++ b/drivers/acpi/acpica/evgpeblk.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/evmisc.c b/drivers/acpi/acpica/evmisc.c index ce224e1eaa89..e77374d92816 100644 --- a/drivers/acpi/acpica/evmisc.c +++ b/drivers/acpi/acpica/evmisc.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/evregion.c b/drivers/acpi/acpica/evregion.c index 5336d911fbf0..654b2833598c 100644 --- a/drivers/acpi/acpica/evregion.c +++ b/drivers/acpi/acpica/evregion.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/evrgnini.c b/drivers/acpi/acpica/evrgnini.c index ff168052a332..86bd5a7f40d0 100644 --- a/drivers/acpi/acpica/evrgnini.c +++ b/drivers/acpi/acpica/evrgnini.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/evsci.c b/drivers/acpi/acpica/evsci.c index 567b356c85af..8dfbaa96e422 100644 --- a/drivers/acpi/acpica/evsci.c +++ b/drivers/acpi/acpica/evsci.c @@ -6,7 +6,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/evxface.c b/drivers/acpi/acpica/evxface.c index 2fe0809d4eb2..292c36375de8 100644 --- a/drivers/acpi/acpica/evxface.c +++ b/drivers/acpi/acpica/evxface.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/evxfevnt.c b/drivers/acpi/acpica/evxfevnt.c index eed7a38d25f2..8bbde6244908 100644 --- a/drivers/acpi/acpica/evxfevnt.c +++ b/drivers/acpi/acpica/evxfevnt.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/evxfregn.c b/drivers/acpi/acpica/evxfregn.c index c98aa7c2d67c..541cbc1544d5 100644 --- a/drivers/acpi/acpica/evxfregn.c +++ b/drivers/acpi/acpica/evxfregn.c @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/exconfig.c b/drivers/acpi/acpica/exconfig.c index 2ea8daccba1c..cee2bceb2169 100644 --- a/drivers/acpi/acpica/exconfig.c +++ b/drivers/acpi/acpica/exconfig.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/exconvrt.c b/drivers/acpi/acpica/exconvrt.c index 51d5f224f9fa..adcaf3b89587 100644 --- a/drivers/acpi/acpica/exconvrt.c +++ b/drivers/acpi/acpica/exconvrt.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/excreate.c b/drivers/acpi/acpica/excreate.c index 02b25d233d99..0aa57d938698 100644 --- a/drivers/acpi/acpica/excreate.c +++ b/drivers/acpi/acpica/excreate.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/exdump.c b/drivers/acpi/acpica/exdump.c index de3446372ddc..d39d438ba1e3 100644 --- a/drivers/acpi/acpica/exdump.c +++ b/drivers/acpi/acpica/exdump.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/exfield.c b/drivers/acpi/acpica/exfield.c index 1588a2d660e7..c9190c784194 100644 --- a/drivers/acpi/acpica/exfield.c +++ b/drivers/acpi/acpica/exfield.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/exfldio.c b/drivers/acpi/acpica/exfldio.c index d7b3b418fb45..dc2f9e8bee6e 100644 --- a/drivers/acpi/acpica/exfldio.c +++ b/drivers/acpi/acpica/exfldio.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/exmisc.c b/drivers/acpi/acpica/exmisc.c index 998eac329937..d29e542bb6df 100644 --- a/drivers/acpi/acpica/exmisc.c +++ b/drivers/acpi/acpica/exmisc.c @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/exmutex.c b/drivers/acpi/acpica/exmutex.c index 3c456bd575d0..cc8a10268f68 100644 --- a/drivers/acpi/acpica/exmutex.c +++ b/drivers/acpi/acpica/exmutex.c @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/exnames.c b/drivers/acpi/acpica/exnames.c index ffdae122d94a..679f308c5a89 100644 --- a/drivers/acpi/acpica/exnames.c +++ b/drivers/acpi/acpica/exnames.c @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/exoparg1.c b/drivers/acpi/acpica/exoparg1.c index 752fe48b2d20..2b2128e52d42 100644 --- a/drivers/acpi/acpica/exoparg1.c +++ b/drivers/acpi/acpica/exoparg1.c @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/exoparg2.c b/drivers/acpi/acpica/exoparg2.c index 85d95c92dfd3..ea115021ee7d 100644 --- a/drivers/acpi/acpica/exoparg2.c +++ b/drivers/acpi/acpica/exoparg2.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/exoparg3.c b/drivers/acpi/acpica/exoparg3.c index 253f9e122584..25d1cd35c3e1 100644 --- a/drivers/acpi/acpica/exoparg3.c +++ b/drivers/acpi/acpica/exoparg3.c @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/exoparg6.c b/drivers/acpi/acpica/exoparg6.c index 295542e6bd51..580abbd924dc 100644 --- a/drivers/acpi/acpica/exoparg6.c +++ b/drivers/acpi/acpica/exoparg6.c @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/exprep.c b/drivers/acpi/acpica/exprep.c index 52fec07064f0..edf62bf5b266 100644 --- a/drivers/acpi/acpica/exprep.c +++ b/drivers/acpi/acpica/exprep.c @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/exregion.c b/drivers/acpi/acpica/exregion.c index 2bd83ac57c3a..0cd88f6c95f7 100644 --- a/drivers/acpi/acpica/exregion.c +++ b/drivers/acpi/acpica/exregion.c @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/exresnte.c b/drivers/acpi/acpica/exresnte.c index 607958ff467c..fdc1b27999ef 100644 --- a/drivers/acpi/acpica/exresnte.c +++ b/drivers/acpi/acpica/exresnte.c @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/exresolv.c b/drivers/acpi/acpica/exresolv.c index c93b54ce7f78..fdd6a7079b97 100644 --- a/drivers/acpi/acpica/exresolv.c +++ b/drivers/acpi/acpica/exresolv.c @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/exresop.c b/drivers/acpi/acpica/exresop.c index 5c729a9e9131..c5ecd615f145 100644 --- a/drivers/acpi/acpica/exresop.c +++ b/drivers/acpi/acpica/exresop.c @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/exstore.c b/drivers/acpi/acpica/exstore.c index 6efd07a4f779..702b9ecfd44b 100644 --- a/drivers/acpi/acpica/exstore.c +++ b/drivers/acpi/acpica/exstore.c @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/exstoren.c b/drivers/acpi/acpica/exstoren.c index 608e838d537e..d4af684620ca 100644 --- a/drivers/acpi/acpica/exstoren.c +++ b/drivers/acpi/acpica/exstoren.c @@ -7,7 +7,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/exstorob.c b/drivers/acpi/acpica/exstorob.c index 257706e7734f..e972b667b09b 100644 --- a/drivers/acpi/acpica/exstorob.c +++ b/drivers/acpi/acpica/exstorob.c @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/exsystem.c b/drivers/acpi/acpica/exsystem.c index 3d00b9357233..c6cb6042603c 100644 --- a/drivers/acpi/acpica/exsystem.c +++ b/drivers/acpi/acpica/exsystem.c @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/exutils.c b/drivers/acpi/acpica/exutils.c index 7d41f99f7052..0f2ce9c52f02 100644 --- a/drivers/acpi/acpica/exutils.c +++ b/drivers/acpi/acpica/exutils.c @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/hwacpi.c b/drivers/acpi/acpica/hwacpi.c index 9af361a191e7..679a112a7d26 100644 --- a/drivers/acpi/acpica/hwacpi.c +++ b/drivers/acpi/acpica/hwacpi.c @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/hwgpe.c b/drivers/acpi/acpica/hwgpe.c index 55c4507957bb..bd72319a38f0 100644 --- a/drivers/acpi/acpica/hwgpe.c +++ b/drivers/acpi/acpica/hwgpe.c @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/hwregs.c b/drivers/acpi/acpica/hwregs.c index 15c9ed2be853..ec7fc227b33f 100644 --- a/drivers/acpi/acpica/hwregs.c +++ b/drivers/acpi/acpica/hwregs.c @@ -7,7 +7,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/hwsleep.c b/drivers/acpi/acpica/hwsleep.c index cc22f9a585b0..5e6d4dbb8024 100644 --- a/drivers/acpi/acpica/hwsleep.c +++ b/drivers/acpi/acpica/hwsleep.c @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/hwtimer.c b/drivers/acpi/acpica/hwtimer.c index 6b282e85d039..ce0cbbc18ad0 100644 --- a/drivers/acpi/acpica/hwtimer.c +++ b/drivers/acpi/acpica/hwtimer.c @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/hwvalid.c b/drivers/acpi/acpica/hwvalid.c index ec33f270c5b7..e26c17d4b716 100644 --- a/drivers/acpi/acpica/hwvalid.c +++ b/drivers/acpi/acpica/hwvalid.c @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2009, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/hwxface.c b/drivers/acpi/acpica/hwxface.c index 647c7b6e6756..50cc3be77724 100644 --- a/drivers/acpi/acpica/hwxface.c +++ b/drivers/acpi/acpica/hwxface.c @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/nsaccess.c b/drivers/acpi/acpica/nsaccess.c index d622ba770000..aa2b80132d0a 100644 --- a/drivers/acpi/acpica/nsaccess.c +++ b/drivers/acpi/acpica/nsaccess.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/nsalloc.c b/drivers/acpi/acpica/nsalloc.c index 8a58a1b85aa0..982269c1fa48 100644 --- a/drivers/acpi/acpica/nsalloc.c +++ b/drivers/acpi/acpica/nsalloc.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/nsdump.c b/drivers/acpi/acpica/nsdump.c index e37836e27e29..0689d36638d9 100644 --- a/drivers/acpi/acpica/nsdump.c +++ b/drivers/acpi/acpica/nsdump.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/nsdumpdv.c b/drivers/acpi/acpica/nsdumpdv.c index 36be7f0e97ec..d2a97921e249 100644 --- a/drivers/acpi/acpica/nsdumpdv.c +++ b/drivers/acpi/acpica/nsdumpdv.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/nseval.c b/drivers/acpi/acpica/nseval.c index af9fe9103734..f52829cc294b 100644 --- a/drivers/acpi/acpica/nseval.c +++ b/drivers/acpi/acpica/nseval.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/nsinit.c b/drivers/acpi/acpica/nsinit.c index 4f8abac231d2..9bd6f050f299 100644 --- a/drivers/acpi/acpica/nsinit.c +++ b/drivers/acpi/acpica/nsinit.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/nsload.c b/drivers/acpi/acpica/nsload.c index a7234e60e985..df18be94fefe 100644 --- a/drivers/acpi/acpica/nsload.c +++ b/drivers/acpi/acpica/nsload.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/nsnames.c b/drivers/acpi/acpica/nsnames.c index 8f9a4875ce26..959372451635 100644 --- a/drivers/acpi/acpica/nsnames.c +++ b/drivers/acpi/acpica/nsnames.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/nsobject.c b/drivers/acpi/acpica/nsobject.c index 60f3af08d28c..41a9213dd5af 100644 --- a/drivers/acpi/acpica/nsobject.c +++ b/drivers/acpi/acpica/nsobject.c @@ -6,7 +6,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/nsparse.c b/drivers/acpi/acpica/nsparse.c index 662a4bd5b621..27cda52c76bc 100644 --- a/drivers/acpi/acpica/nsparse.c +++ b/drivers/acpi/acpica/nsparse.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/nspredef.c b/drivers/acpi/acpica/nspredef.c index 309586f5809c..ba1072fb0daa 100644 --- a/drivers/acpi/acpica/nspredef.c +++ b/drivers/acpi/acpica/nspredef.c @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/nsrepair.c b/drivers/acpi/acpica/nsrepair.c index 4fd1bdb056b2..c82060fd3821 100644 --- a/drivers/acpi/acpica/nsrepair.c +++ b/drivers/acpi/acpica/nsrepair.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2009, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/nsrepair2.c b/drivers/acpi/acpica/nsrepair2.c index 6d6926466a08..29ff5d14e1d5 100644 --- a/drivers/acpi/acpica/nsrepair2.c +++ b/drivers/acpi/acpica/nsrepair2.c @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2009, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/nssearch.c b/drivers/acpi/acpica/nssearch.c index 7e865639a928..08f8b3f5ccaa 100644 --- a/drivers/acpi/acpica/nssearch.c +++ b/drivers/acpi/acpica/nssearch.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/nsutils.c b/drivers/acpi/acpica/nsutils.c index 47d91e668a1b..24d05a87a2a3 100644 --- a/drivers/acpi/acpica/nsutils.c +++ b/drivers/acpi/acpica/nsutils.c @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/nswalk.c b/drivers/acpi/acpica/nswalk.c index d7e6b52b4482..00e79fb26029 100644 --- a/drivers/acpi/acpica/nswalk.c +++ b/drivers/acpi/acpica/nswalk.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/nsxfeval.c b/drivers/acpi/acpica/nsxfeval.c index f0c0892bc7e5..c5a5357c69e6 100644 --- a/drivers/acpi/acpica/nsxfeval.c +++ b/drivers/acpi/acpica/nsxfeval.c @@ -6,7 +6,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/nsxfname.c b/drivers/acpi/acpica/nsxfname.c index e611dd961b20..b01e45a415e3 100644 --- a/drivers/acpi/acpica/nsxfname.c +++ b/drivers/acpi/acpica/nsxfname.c @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/nsxfobj.c b/drivers/acpi/acpica/nsxfobj.c index 0cc6ba01a495..eafef24ea448 100644 --- a/drivers/acpi/acpica/nsxfobj.c +++ b/drivers/acpi/acpica/nsxfobj.c @@ -6,7 +6,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/psargs.c b/drivers/acpi/acpica/psargs.c index b161f3544b51..6aa6a1a4d918 100644 --- a/drivers/acpi/acpica/psargs.c +++ b/drivers/acpi/acpica/psargs.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/psloop.c b/drivers/acpi/acpica/psloop.c index 0988e4a8901d..59aabaeab1d3 100644 --- a/drivers/acpi/acpica/psloop.c +++ b/drivers/acpi/acpica/psloop.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/psopcode.c b/drivers/acpi/acpica/psopcode.c index 3bc3a60194d6..2b0c3be2b1b8 100644 --- a/drivers/acpi/acpica/psopcode.c +++ b/drivers/acpi/acpica/psopcode.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/psparse.c b/drivers/acpi/acpica/psparse.c index 4df8f139026c..8d81542194d4 100644 --- a/drivers/acpi/acpica/psparse.c +++ b/drivers/acpi/acpica/psparse.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/psscope.c b/drivers/acpi/acpica/psscope.c index 2feca5ca9581..40e2b279ea12 100644 --- a/drivers/acpi/acpica/psscope.c +++ b/drivers/acpi/acpica/psscope.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/pstree.c b/drivers/acpi/acpica/pstree.c index 4d3389118ec3..d4b970c3630b 100644 --- a/drivers/acpi/acpica/pstree.c +++ b/drivers/acpi/acpica/pstree.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/psutils.c b/drivers/acpi/acpica/psutils.c index e636e078ad3d..fe29eee5adb1 100644 --- a/drivers/acpi/acpica/psutils.c +++ b/drivers/acpi/acpica/psutils.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/pswalk.c b/drivers/acpi/acpica/pswalk.c index 78b8b791f2ae..8abb9629443d 100644 --- a/drivers/acpi/acpica/pswalk.c +++ b/drivers/acpi/acpica/pswalk.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/psxface.c b/drivers/acpi/acpica/psxface.c index d0c1b91eb8ca..6064dd4e94c2 100644 --- a/drivers/acpi/acpica/psxface.c +++ b/drivers/acpi/acpica/psxface.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/rsaddr.c b/drivers/acpi/acpica/rsaddr.c index 1e437bfd8db5..226c806ae986 100644 --- a/drivers/acpi/acpica/rsaddr.c +++ b/drivers/acpi/acpica/rsaddr.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/rscalc.c b/drivers/acpi/acpica/rscalc.c index 3c4dcc3d1069..d6ebf7ec622d 100644 --- a/drivers/acpi/acpica/rscalc.c +++ b/drivers/acpi/acpica/rscalc.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/rscreate.c b/drivers/acpi/acpica/rscreate.c index a3c23d686d5f..61a038dbfe23 100644 --- a/drivers/acpi/acpica/rscreate.c +++ b/drivers/acpi/acpica/rscreate.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/rsdump.c b/drivers/acpi/acpica/rsdump.c index 3f0ca5a12d34..f859b0386fe4 100644 --- a/drivers/acpi/acpica/rsdump.c +++ b/drivers/acpi/acpica/rsdump.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/rsinfo.c b/drivers/acpi/acpica/rsinfo.c index 77b25fdb459c..1fd868b964fd 100644 --- a/drivers/acpi/acpica/rsinfo.c +++ b/drivers/acpi/acpica/rsinfo.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/rsio.c b/drivers/acpi/acpica/rsio.c index 35a49aa95609..33bff17c0bbc 100644 --- a/drivers/acpi/acpica/rsio.c +++ b/drivers/acpi/acpica/rsio.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/rsirq.c b/drivers/acpi/acpica/rsirq.c index 2e0256983aa6..545da40d7fa7 100644 --- a/drivers/acpi/acpica/rsirq.c +++ b/drivers/acpi/acpica/rsirq.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/rslist.c b/drivers/acpi/acpica/rslist.c index 1b1dbc69f087..fd057c72d252 100644 --- a/drivers/acpi/acpica/rslist.c +++ b/drivers/acpi/acpica/rslist.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/rsmemory.c b/drivers/acpi/acpica/rsmemory.c index ddc76cebdc92..887b8ba8c432 100644 --- a/drivers/acpi/acpica/rsmemory.c +++ b/drivers/acpi/acpica/rsmemory.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/rsmisc.c b/drivers/acpi/acpica/rsmisc.c index 5bc49a553284..07de352fa443 100644 --- a/drivers/acpi/acpica/rsmisc.c +++ b/drivers/acpi/acpica/rsmisc.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/rsutils.c b/drivers/acpi/acpica/rsutils.c index bc03d5966829..22cfcfbd9fff 100644 --- a/drivers/acpi/acpica/rsutils.c +++ b/drivers/acpi/acpica/rsutils.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/rsxface.c b/drivers/acpi/acpica/rsxface.c index f27feb4772f6..9f6a6e7e1c8e 100644 --- a/drivers/acpi/acpica/rsxface.c +++ b/drivers/acpi/acpica/rsxface.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/tbfadt.c b/drivers/acpi/acpica/tbfadt.c index c016335fb759..f43fbe0fc3fc 100644 --- a/drivers/acpi/acpica/tbfadt.c +++ b/drivers/acpi/acpica/tbfadt.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/tbfind.c b/drivers/acpi/acpica/tbfind.c index 1054dfd49207..e252180ce61c 100644 --- a/drivers/acpi/acpica/tbfind.c +++ b/drivers/acpi/acpica/tbfind.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/tbinstal.c b/drivers/acpi/acpica/tbinstal.c index 63e82329a9e8..7ec02b0f69e0 100644 --- a/drivers/acpi/acpica/tbinstal.c +++ b/drivers/acpi/acpica/tbinstal.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/tbutils.c b/drivers/acpi/acpica/tbutils.c index 1f15497f00d1..02723a9fb10c 100644 --- a/drivers/acpi/acpica/tbutils.c +++ b/drivers/acpi/acpica/tbutils.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/tbxface.c b/drivers/acpi/acpica/tbxface.c index a88f02bd6c94..5217a6159a31 100644 --- a/drivers/acpi/acpica/tbxface.c +++ b/drivers/acpi/acpica/tbxface.c @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/tbxfroot.c b/drivers/acpi/acpica/tbxfroot.c index 85ea834199e2..dda6e8c497d3 100644 --- a/drivers/acpi/acpica/tbxfroot.c +++ b/drivers/acpi/acpica/tbxfroot.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/utalloc.c b/drivers/acpi/acpica/utalloc.c index 7580f6b3069e..3d706b8fd449 100644 --- a/drivers/acpi/acpica/utalloc.c +++ b/drivers/acpi/acpica/utalloc.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/utcopy.c b/drivers/acpi/acpica/utcopy.c index f857c5efb79f..97ec3621e71d 100644 --- a/drivers/acpi/acpica/utcopy.c +++ b/drivers/acpi/acpica/utcopy.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/utdebug.c b/drivers/acpi/acpica/utdebug.c index 527d729f6815..e156915fa0e8 100644 --- a/drivers/acpi/acpica/utdebug.c +++ b/drivers/acpi/acpica/utdebug.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/utdelete.c b/drivers/acpi/acpica/utdelete.c index 96e26e70c63d..16b51c69606a 100644 --- a/drivers/acpi/acpica/utdelete.c +++ b/drivers/acpi/acpica/utdelete.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/uteval.c b/drivers/acpi/acpica/uteval.c index 5d54e36ab453..f4c5ee8109bc 100644 --- a/drivers/acpi/acpica/uteval.c +++ b/drivers/acpi/acpica/uteval.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/utglobal.c b/drivers/acpi/acpica/utglobal.c index 3f2c68f4e959..49286a39b09e 100644 --- a/drivers/acpi/acpica/utglobal.c +++ b/drivers/acpi/acpica/utglobal.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/utids.c b/drivers/acpi/acpica/utids.c index 52eaae404554..1397fadd0d4b 100644 --- a/drivers/acpi/acpica/utids.c +++ b/drivers/acpi/acpica/utids.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2009, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/utinit.c b/drivers/acpi/acpica/utinit.c index 9d0919ebf7b0..a39c93dac719 100644 --- a/drivers/acpi/acpica/utinit.c +++ b/drivers/acpi/acpica/utinit.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/utlock.c b/drivers/acpi/acpica/utlock.c index 25e03120686d..b081cd46a15f 100644 --- a/drivers/acpi/acpica/utlock.c +++ b/drivers/acpi/acpica/utlock.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2009, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/utmath.c b/drivers/acpi/acpica/utmath.c index c9f682d640ef..7cfa1d8164d0 100644 --- a/drivers/acpi/acpica/utmath.c +++ b/drivers/acpi/acpica/utmath.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/utmisc.c b/drivers/acpi/acpica/utmisc.c index 6c6a5137b728..fb55924e6e0f 100644 --- a/drivers/acpi/acpica/utmisc.c +++ b/drivers/acpi/acpica/utmisc.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/utmutex.c b/drivers/acpi/acpica/utmutex.c index 1f58a8824146..55d014ed6d55 100644 --- a/drivers/acpi/acpica/utmutex.c +++ b/drivers/acpi/acpica/utmutex.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/utobject.c b/drivers/acpi/acpica/utobject.c index 42e658b543f1..3356f0cb0745 100644 --- a/drivers/acpi/acpica/utobject.c +++ b/drivers/acpi/acpica/utobject.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/utresrc.c b/drivers/acpi/acpica/utresrc.c index 91b7c00236f4..7965919000b1 100644 --- a/drivers/acpi/acpica/utresrc.c +++ b/drivers/acpi/acpica/utresrc.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/utstate.c b/drivers/acpi/acpica/utstate.c index 0440c958f5a4..d35d109b8da2 100644 --- a/drivers/acpi/acpica/utstate.c +++ b/drivers/acpi/acpica/utstate.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/utxface.c b/drivers/acpi/acpica/utxface.c index b1f5f680bc78..db9d8ca57987 100644 --- a/drivers/acpi/acpica/utxface.c +++ b/drivers/acpi/acpica/utxface.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2010, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without -- cgit v1.2.2 From 5f8902acf87aa206ee4b3f633104456d82747ca6 Mon Sep 17 00:00:00 2001 From: Lin Ming Date: Thu, 21 Jan 2010 09:15:20 +0800 Subject: ACPICA: AcpiGetDevices: Eliminate unnecessary _STA calls In the case where a specific _HID is requested, do not run _STA until a _HID match is found. This eliminates potentially dozens of _STA calls during a search for a particular device/HID. Signed-off-by: Lin Ming Signed-off-by: Bob Moore Signed-off-by: Len Brown --- drivers/acpi/acpica/nsxfeval.c | 52 +++++++++++++++++++++++++++--------------- 1 file changed, 33 insertions(+), 19 deletions(-) (limited to 'drivers') diff --git a/drivers/acpi/acpica/nsxfeval.c b/drivers/acpi/acpica/nsxfeval.c index c5a5357c69e6..ebef8a7fd707 100644 --- a/drivers/acpi/acpica/nsxfeval.c +++ b/drivers/acpi/acpica/nsxfeval.c @@ -562,25 +562,20 @@ acpi_ns_get_device_callback(acpi_handle obj_handle, return (AE_BAD_PARAMETER); } - /* Run _STA to determine if device is present */ - - status = acpi_ut_execute_STA(node, &flags); - if (ACPI_FAILURE(status)) { - return (AE_CTRL_DEPTH); - } - - if (!(flags & ACPI_STA_DEVICE_PRESENT) && - !(flags & ACPI_STA_DEVICE_FUNCTIONING)) { - /* - * Don't examine the children of the device only when the - * device is neither present nor functional. See ACPI spec, - * description of _STA for more information. - */ - return (AE_CTRL_DEPTH); - } - - /* Filter based on device HID & CID */ - + /* + * First, filter based on the device HID and CID. + * + * 01/2010: For this case where a specific HID is requested, we don't + * want to run _STA until we have an actual HID match. Thus, we will + * not unnecessarily execute _STA on devices for which the caller + * doesn't care about. Previously, _STA was executed unconditionally + * on all devices found here. + * + * A side-effect of this change is that now we will continue to search + * for a matching HID even under device trees where the parent device + * would have returned a _STA that indicates it is not present or + * not functioning (thus aborting the search on that branch). + */ if (info->hid != NULL) { status = acpi_ut_execute_HID(node, &hid); if (status == AE_NOT_FOUND) { @@ -620,6 +615,25 @@ acpi_ns_get_device_callback(acpi_handle obj_handle, } } + /* Run _STA to determine if device is present */ + + status = acpi_ut_execute_STA(node, &flags); + if (ACPI_FAILURE(status)) { + return (AE_CTRL_DEPTH); + } + + if (!(flags & ACPI_STA_DEVICE_PRESENT) && + !(flags & ACPI_STA_DEVICE_FUNCTIONING)) { + /* + * Don't examine the children of the device only when the + * device is neither present nor functional. See ACPI spec, + * description of _STA for more information. + */ + return (AE_CTRL_DEPTH); + } + + /* We have a valid device, invoke the user function */ + status = info->user_function(obj_handle, nesting_level, info->context, return_value); return (status); -- cgit v1.2.2 From 091f4d718620a79698e1c8ca3e9acbf78eb62da3 Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Thu, 21 Jan 2010 09:28:32 +0800 Subject: ACPICA: Predefined name repair: fix NULL package elements For the predefined methods that return fixed-length packages (or subpackages), attempt repair for a NULL element. Create an Integer of value 0, a NULL String, or a zero-length buffer as appropriate. http://www.acpica.org/bugzilla/show_bug.cgi?id=818 Signed-off-by: Bob Moore Signed-off-by: Lin Ming Signed-off-by: Len Brown --- drivers/acpi/acpica/aclocal.h | 1 + drivers/acpi/acpica/acnamesp.h | 16 ++-- drivers/acpi/acpica/nspredef.c | 27 ++++++- drivers/acpi/acpica/nsrepair.c | 173 ++++++++++++++++++++++++++++++++++++++++ drivers/acpi/acpica/nsrepair2.c | 84 ------------------- 5 files changed, 209 insertions(+), 92 deletions(-) (limited to 'drivers') diff --git a/drivers/acpi/acpica/aclocal.h b/drivers/acpi/acpica/aclocal.h index 2caf141076fc..681205c75563 100644 --- a/drivers/acpi/acpica/aclocal.h +++ b/drivers/acpi/acpica/aclocal.h @@ -374,6 +374,7 @@ union acpi_predefined_info { struct acpi_predefined_data { char *pathname; const union acpi_predefined_info *predefined; + union acpi_operand_object *parent_package; u32 flags; u8 node_flags; }; diff --git a/drivers/acpi/acpica/acnamesp.h b/drivers/acpi/acpica/acnamesp.h index 73f9b0c88dd8..258159cfcdfa 100644 --- a/drivers/acpi/acpica/acnamesp.h +++ b/drivers/acpi/acpica/acnamesp.h @@ -286,6 +286,17 @@ acpi_status acpi_ns_repair_package_list(struct acpi_predefined_data *data, union acpi_operand_object **obj_desc_ptr); +acpi_status +acpi_ns_repair_null_element(struct acpi_predefined_data *data, + u32 expected_btypes, + u32 package_index, + union acpi_operand_object **return_object_ptr); + +void +acpi_ns_remove_null_elements(struct acpi_predefined_data *data, + u8 package_type, + union acpi_operand_object *obj_desc); + /* * nsrepair2 - Return object repair for specific * predefined methods/objects @@ -296,11 +307,6 @@ acpi_ns_complex_repairs(struct acpi_predefined_data *data, acpi_status validate_status, union acpi_operand_object **return_object_ptr); -void -acpi_ns_remove_null_elements(struct acpi_predefined_data *data, - u8 package_type, - union acpi_operand_object *obj_desc); - /* * nssearch - Namespace searching and entry */ diff --git a/drivers/acpi/acpica/nspredef.c b/drivers/acpi/acpica/nspredef.c index ba1072fb0daa..7096bcda0c72 100644 --- a/drivers/acpi/acpica/nspredef.c +++ b/drivers/acpi/acpica/nspredef.c @@ -231,6 +231,7 @@ acpi_ns_check_predefined_names(struct acpi_namespace_node *node, * Note: Package may have been newly created by call above. */ if ((*return_object_ptr)->common.type == ACPI_TYPE_PACKAGE) { + data->parent_package = *return_object_ptr; status = acpi_ns_check_package(data, return_object_ptr); if (ACPI_FAILURE(status)) { goto exit; @@ -710,6 +711,7 @@ acpi_ns_check_package_list(struct acpi_predefined_data *data, for (i = 0; i < count; i++) { sub_package = *elements; sub_elements = sub_package->package.elements; + data->parent_package = sub_package; /* Each sub-object must be of type Package */ @@ -721,6 +723,7 @@ acpi_ns_check_package_list(struct acpi_predefined_data *data, /* Examine the different types of expected sub-packages */ + data->parent_package = sub_package; switch (package->ret_info.type) { case ACPI_PTYPE2: case ACPI_PTYPE2_PKG_COUNT: @@ -800,7 +803,7 @@ acpi_ns_check_package_list(struct acpi_predefined_data *data, /* * First element is the (Integer) count of elements, including - * the count field. + * the count field (the ACPI name is num_elements) */ status = acpi_ns_check_object_type(data, sub_elements, ACPI_RTYPE_INTEGER, @@ -822,6 +825,16 @@ acpi_ns_check_package_list(struct acpi_predefined_data *data, expected_count = package->ret_info.count1; goto package_too_small; } + if (expected_count == 0) { + /* + * Either the num_entries element was originally zero or it was + * a NULL element and repaired to an Integer of value zero. + * In either case, repair it by setting num_entries to be the + * actual size of the subpackage. + */ + expected_count = sub_package->package.count; + (*sub_elements)->integer.value = expected_count; + } /* Check the type of each sub-package element */ @@ -945,10 +958,18 @@ acpi_ns_check_object_type(struct acpi_predefined_data *data, char type_buffer[48]; /* Room for 5 types */ /* - * If we get a NULL return_object here, it is a NULL package element, - * and this is always an error. + * If we get a NULL return_object here, it is a NULL package element. + * Since all extraneous NULL package elements were removed earlier by a + * call to acpi_ns_remove_null_elements, this is an unexpected NULL element. + * We will attempt to repair it. */ if (!return_object) { + status = acpi_ns_repair_null_element(data, expected_btypes, + package_index, + return_object_ptr); + if (ACPI_SUCCESS(status)) { + return (AE_OK); /* Repair was successful */ + } goto type_error_exit; } diff --git a/drivers/acpi/acpica/nsrepair.c b/drivers/acpi/acpica/nsrepair.c index c82060fd3821..d4be37751be4 100644 --- a/drivers/acpi/acpica/nsrepair.c +++ b/drivers/acpi/acpica/nsrepair.c @@ -45,6 +45,7 @@ #include "accommon.h" #include "acnamesp.h" #include "acinterp.h" +#include "acpredef.h" #define _COMPONENT ACPI_NAMESPACE ACPI_MODULE_NAME("nsrepair") @@ -71,6 +72,12 @@ ACPI_MODULE_NAME("nsrepair") * Buffer -> Package of Integers * Package -> Package of one Package * + * Additional possible repairs: + * + * Optional/unnecessary NULL package elements removed + * Required package elements that are NULL replaced by Integer/String/Buffer + * Incorrect standalone package wrapped with required outer package + * ******************************************************************************/ /* Local prototypes */ static acpi_status @@ -504,6 +511,172 @@ acpi_ns_convert_to_package(union acpi_operand_object *original_object, return (AE_OK); } +/******************************************************************************* + * + * FUNCTION: acpi_ns_repair_null_element + * + * PARAMETERS: Data - Pointer to validation data structure + * expected_btypes - Object types expected + * package_index - Index of object within parent package (if + * applicable - ACPI_NOT_PACKAGE_ELEMENT + * otherwise) + * return_object_ptr - Pointer to the object returned from the + * evaluation of a method or object + * + * RETURN: Status. AE_OK if repair was successful. + * + * DESCRIPTION: Attempt to repair a NULL element of a returned Package object. + * + ******************************************************************************/ + +acpi_status +acpi_ns_repair_null_element(struct acpi_predefined_data *data, + u32 expected_btypes, + u32 package_index, + union acpi_operand_object **return_object_ptr) +{ + union acpi_operand_object *return_object = *return_object_ptr; + union acpi_operand_object *new_object; + + ACPI_FUNCTION_NAME(ns_repair_null_element); + + /* No repair needed if return object is non-NULL */ + + if (return_object) { + return (AE_OK); + } + + /* + * Attempt to repair a NULL element of a Package object. This applies to + * predefined names that return a fixed-length package and each element + * is required. It does not apply to variable-length packages where NULL + * elements are allowed, especially at the end of the package. + */ + if (expected_btypes & ACPI_RTYPE_INTEGER) { + + /* Need an Integer - create a zero-value integer */ + + new_object = acpi_ut_create_integer_object(0); + } else if (expected_btypes & ACPI_RTYPE_STRING) { + + /* Need a String - create a NULL string */ + + new_object = acpi_ut_create_string_object(0); + } else if (expected_btypes & ACPI_RTYPE_BUFFER) { + + /* Need a Buffer - create a zero-length buffer */ + + new_object = acpi_ut_create_buffer_object(0); + } else { + /* Error for all other expected types */ + + return (AE_AML_OPERAND_TYPE); + } + + if (!new_object) { + return (AE_NO_MEMORY); + } + + /* Set the reference count according to the parent Package object */ + + new_object->common.reference_count = + data->parent_package->common.reference_count; + + ACPI_DEBUG_PRINT((ACPI_DB_REPAIR, + "%s: Converted NULL package element to expected %s at index %u\n", + data->pathname, + acpi_ut_get_object_type_name(new_object), + package_index)); + + *return_object_ptr = new_object; + data->flags |= ACPI_OBJECT_REPAIRED; + return (AE_OK); +} + +/****************************************************************************** + * + * FUNCTION: acpi_ns_remove_null_elements + * + * PARAMETERS: Data - Pointer to validation data structure + * package_type - An acpi_return_package_types value + * obj_desc - A Package object + * + * RETURN: None. + * + * DESCRIPTION: Remove all NULL package elements from packages that contain + * a variable number of sub-packages. For these types of + * packages, NULL elements can be safely removed. + * + *****************************************************************************/ + +void +acpi_ns_remove_null_elements(struct acpi_predefined_data *data, + u8 package_type, + union acpi_operand_object *obj_desc) +{ + union acpi_operand_object **source; + union acpi_operand_object **dest; + u32 count; + u32 new_count; + u32 i; + + ACPI_FUNCTION_NAME(ns_remove_null_elements); + + /* + * PTYPE1 packages contain no subpackages. + * PTYPE2 packages contain a variable number of sub-packages. We can + * safely remove all NULL elements from the PTYPE2 packages. + */ + switch (package_type) { + case ACPI_PTYPE1_FIXED: + case ACPI_PTYPE1_VAR: + case ACPI_PTYPE1_OPTION: + return; + + case ACPI_PTYPE2: + case ACPI_PTYPE2_COUNT: + case ACPI_PTYPE2_PKG_COUNT: + case ACPI_PTYPE2_FIXED: + case ACPI_PTYPE2_MIN: + case ACPI_PTYPE2_REV_FIXED: + break; + + default: + return; + } + + count = obj_desc->package.count; + new_count = count; + + source = obj_desc->package.elements; + dest = source; + + /* Examine all elements of the package object, remove nulls */ + + for (i = 0; i < count; i++) { + if (!*source) { + new_count--; + } else { + *dest = *source; + dest++; + } + source++; + } + + /* Update parent package if any null elements were removed */ + + if (new_count < count) { + ACPI_DEBUG_PRINT((ACPI_DB_REPAIR, + "%s: Found and removed %u NULL elements\n", + data->pathname, (count - new_count))); + + /* NULL terminate list and update the package count */ + + *dest = NULL; + obj_desc->package.count = new_count; + } +} + /******************************************************************************* * * FUNCTION: acpi_ns_repair_package_list diff --git a/drivers/acpi/acpica/nsrepair2.c b/drivers/acpi/acpica/nsrepair2.c index 29ff5d14e1d5..61bd0f6755d2 100644 --- a/drivers/acpi/acpica/nsrepair2.c +++ b/drivers/acpi/acpica/nsrepair2.c @@ -45,7 +45,6 @@ #include #include "accommon.h" #include "acnamesp.h" -#include "acpredef.h" #define _COMPONENT ACPI_NAMESPACE ACPI_MODULE_NAME("nsrepair2") @@ -518,89 +517,6 @@ acpi_ns_check_sorted_list(struct acpi_predefined_data *data, return (AE_OK); } -/****************************************************************************** - * - * FUNCTION: acpi_ns_remove_null_elements - * - * PARAMETERS: Data - Pointer to validation data structure - * package_type - An acpi_return_package_types value - * obj_desc - A Package object - * - * RETURN: None. - * - * DESCRIPTION: Remove all NULL package elements from packages that contain - * a variable number of sub-packages. - * - *****************************************************************************/ - -void -acpi_ns_remove_null_elements(struct acpi_predefined_data *data, - u8 package_type, - union acpi_operand_object *obj_desc) -{ - union acpi_operand_object **source; - union acpi_operand_object **dest; - u32 count; - u32 new_count; - u32 i; - - ACPI_FUNCTION_NAME(ns_remove_null_elements); - - /* - * PTYPE1 packages contain no subpackages. - * PTYPE2 packages contain a variable number of sub-packages. We can - * safely remove all NULL elements from the PTYPE2 packages. - */ - switch (package_type) { - case ACPI_PTYPE1_FIXED: - case ACPI_PTYPE1_VAR: - case ACPI_PTYPE1_OPTION: - return; - - case ACPI_PTYPE2: - case ACPI_PTYPE2_COUNT: - case ACPI_PTYPE2_PKG_COUNT: - case ACPI_PTYPE2_FIXED: - case ACPI_PTYPE2_MIN: - case ACPI_PTYPE2_REV_FIXED: - break; - - default: - return; - } - - count = obj_desc->package.count; - new_count = count; - - source = obj_desc->package.elements; - dest = source; - - /* Examine all elements of the package object, remove nulls */ - - for (i = 0; i < count; i++) { - if (!*source) { - new_count--; - } else { - *dest = *source; - dest++; - } - source++; - } - - /* Update parent package if any null elements were removed */ - - if (new_count < count) { - ACPI_DEBUG_PRINT((ACPI_DB_REPAIR, - "%s: Found and removed %u NULL elements\n", - data->pathname, (count - new_count))); - - /* NULL terminate list and update the package count */ - - *dest = NULL; - obj_desc->package.count = new_count; - } -} - /****************************************************************************** * * FUNCTION: acpi_ns_sort_list -- cgit v1.2.2 From 5df7e6cb42da36c7d878239bebc81907b15f3943 Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Thu, 21 Jan 2010 10:06:32 +0800 Subject: ACPICA: Remove obsolete ACPI_INTEGER (acpi_integer) type This type was introduced as the code was migrated from ACPI 1.0 (with 32-bit AML integers) to ACPI 2.0 (with 64-bit integers). It is now obsolete and this change removes it from the ACPICA code base, replaced by u64. The original typedef has been retained for now for compatibility with existing device driver code. Signed-off-by: Bob Moore Signed-off-by: Lin Ming Signed-off-by: Len Brown --- drivers/acpi/acpica/acevents.h | 3 +-- drivers/acpi/acpica/acinterp.h | 42 ++++++++++++++----------------- drivers/acpi/acpica/aclocal.h | 2 +- drivers/acpi/acpica/acmacros.h | 12 ++++----- drivers/acpi/acpica/acobject.h | 2 +- drivers/acpi/acpica/acutils.h | 20 ++++++--------- drivers/acpi/acpica/dsfield.c | 10 ++++---- drivers/acpi/acpica/dsobject.c | 2 +- drivers/acpi/acpica/evregion.c | 5 ++-- drivers/acpi/acpica/evrgnini.c | 2 +- drivers/acpi/acpica/exconfig.c | 2 +- drivers/acpi/acpica/exconvrt.c | 19 ++++++-------- drivers/acpi/acpica/exfield.c | 7 +++--- drivers/acpi/acpica/exfldio.c | 57 +++++++++++++++++++----------------------- drivers/acpi/acpica/exmisc.c | 10 +++----- drivers/acpi/acpica/exoparg1.c | 14 +++++------ drivers/acpi/acpica/exoparg2.c | 4 +-- drivers/acpi/acpica/exoparg3.c | 2 +- drivers/acpi/acpica/exoparg6.c | 8 +++--- drivers/acpi/acpica/exregion.c | 33 +++++++++++------------- drivers/acpi/acpica/exsystem.c | 2 +- drivers/acpi/acpica/exutils.c | 22 ++++++++-------- drivers/acpi/acpica/hwtimer.c | 2 +- drivers/acpi/acpica/psargs.c | 2 +- drivers/acpi/acpica/rscreate.c | 2 +- drivers/acpi/acpica/utdebug.c | 3 +-- drivers/acpi/acpica/uteval.c | 2 +- drivers/acpi/acpica/utglobal.c | 2 +- drivers/acpi/acpica/utmath.c | 25 ++++++++---------- drivers/acpi/acpica/utmisc.c | 14 +++++------ 30 files changed, 150 insertions(+), 182 deletions(-) (limited to 'drivers') diff --git a/drivers/acpi/acpica/acevents.h b/drivers/acpi/acpica/acevents.h index 13d2b0bc2144..31056bc89774 100644 --- a/drivers/acpi/acpica/acevents.h +++ b/drivers/acpi/acpica/acevents.h @@ -139,8 +139,7 @@ acpi_status acpi_ev_initialize_op_regions(void); acpi_status acpi_ev_address_space_dispatch(union acpi_operand_object *region_obj, u32 function, - u32 region_offset, - u32 bit_width, acpi_integer * value); + u32 region_offset, u32 bit_width, u64 *value); acpi_status acpi_ev_attach_region(union acpi_operand_object *handler_obj, diff --git a/drivers/acpi/acpica/acinterp.h b/drivers/acpi/acpica/acinterp.h index c9d7802f9118..6df3f8428168 100644 --- a/drivers/acpi/acpica/acinterp.h +++ b/drivers/acpi/acpica/acinterp.h @@ -129,18 +129,17 @@ acpi_ex_common_buffer_setup(union acpi_operand_object *obj_desc, acpi_status acpi_ex_write_with_update_rule(union acpi_operand_object *obj_desc, - acpi_integer mask, - acpi_integer field_value, - u32 field_datum_byte_offset); + u64 mask, + u64 field_value, u32 field_datum_byte_offset); void -acpi_ex_get_buffer_datum(acpi_integer * datum, +acpi_ex_get_buffer_datum(u64 *datum, void *buffer, u32 buffer_length, u32 byte_granularity, u32 buffer_offset); void -acpi_ex_set_buffer_datum(acpi_integer merged_datum, +acpi_ex_set_buffer_datum(u64 merged_datum, void *buffer, u32 buffer_length, u32 byte_granularity, u32 buffer_offset); @@ -168,8 +167,7 @@ acpi_ex_insert_into_field(union acpi_operand_object *obj_desc, acpi_status acpi_ex_access_region(union acpi_operand_object *obj_desc, - u32 field_datum_byte_offset, - acpi_integer * value, u32 read_write); + u32 field_datum_byte_offset, u64 *value, u32 read_write); /* * exmisc - misc support routines @@ -193,16 +191,14 @@ acpi_ex_do_concatenate(union acpi_operand_object *obj_desc, acpi_status acpi_ex_do_logical_numeric_op(u16 opcode, - acpi_integer integer0, - acpi_integer integer1, u8 * logical_result); + u64 integer0, u64 integer1, u8 *logical_result); acpi_status acpi_ex_do_logical_op(u16 opcode, union acpi_operand_object *operand0, - union acpi_operand_object *operand1, u8 * logical_result); + union acpi_operand_object *operand1, u8 *logical_result); -acpi_integer -acpi_ex_do_math_op(u16 opcode, acpi_integer operand0, acpi_integer operand1); +u64 acpi_ex_do_math_op(u16 opcode, u64 operand0, u64 operand1); acpi_status acpi_ex_create_mutex(struct acpi_walk_state *walk_state); @@ -278,7 +274,7 @@ acpi_status acpi_ex_system_do_notify_op(union acpi_operand_object *value, union acpi_operand_object *obj_desc); -acpi_status acpi_ex_system_do_suspend(acpi_integer time); +acpi_status acpi_ex_system_do_suspend(u64 time); acpi_status acpi_ex_system_do_stall(u32 time); @@ -461,9 +457,9 @@ void acpi_ex_acquire_global_lock(u32 rule); void acpi_ex_release_global_lock(u32 rule); -void acpi_ex_eisa_id_to_string(char *dest, acpi_integer compressed_id); +void acpi_ex_eisa_id_to_string(char *dest, u64 compressed_id); -void acpi_ex_integer_to_string(char *dest, acpi_integer value); +void acpi_ex_integer_to_string(char *dest, u64 value); /* * exregion - default op_region handlers @@ -472,7 +468,7 @@ acpi_status acpi_ex_system_memory_space_handler(u32 function, acpi_physical_address address, u32 bit_width, - acpi_integer * value, + u64 *value, void *handler_context, void *region_context); @@ -480,35 +476,35 @@ acpi_status acpi_ex_system_io_space_handler(u32 function, acpi_physical_address address, u32 bit_width, - acpi_integer * value, + u64 *value, void *handler_context, void *region_context); acpi_status acpi_ex_pci_config_space_handler(u32 function, acpi_physical_address address, u32 bit_width, - acpi_integer * value, + u64 *value, void *handler_context, void *region_context); acpi_status acpi_ex_cmos_space_handler(u32 function, acpi_physical_address address, u32 bit_width, - acpi_integer * value, + u64 *value, void *handler_context, void *region_context); acpi_status acpi_ex_pci_bar_space_handler(u32 function, acpi_physical_address address, u32 bit_width, - acpi_integer * value, + u64 *value, void *handler_context, void *region_context); acpi_status acpi_ex_embedded_controller_space_handler(u32 function, acpi_physical_address address, u32 bit_width, - acpi_integer * value, + u64 *value, void *handler_context, void *region_context); @@ -516,14 +512,14 @@ acpi_status acpi_ex_sm_bus_space_handler(u32 function, acpi_physical_address address, u32 bit_width, - acpi_integer * value, + u64 *value, void *handler_context, void *region_context); acpi_status acpi_ex_data_table_space_handler(u32 function, acpi_physical_address address, u32 bit_width, - acpi_integer * value, + u64 *value, void *handler_context, void *region_context); #endif /* __INTERP_H__ */ diff --git a/drivers/acpi/acpica/aclocal.h b/drivers/acpi/acpica/aclocal.h index 681205c75563..4894decfdcf5 100644 --- a/drivers/acpi/acpica/aclocal.h +++ b/drivers/acpi/acpica/aclocal.h @@ -650,7 +650,7 @@ struct acpi_opcode_info { }; union acpi_parse_value { - acpi_integer integer; /* Integer constant (Up to 64 bits) */ + u64 integer; /* Integer constant (Up to 64 bits) */ struct uint64_struct integer64; /* Structure overlay for 2 32-bit Dwords */ u32 size; /* bytelist or field size */ char *string; /* NULL terminated string */ diff --git a/drivers/acpi/acpica/acmacros.h b/drivers/acpi/acpica/acmacros.h index a4a9519a1288..9894929a2abb 100644 --- a/drivers/acpi/acpica/acmacros.h +++ b/drivers/acpi/acpica/acmacros.h @@ -272,8 +272,8 @@ * MASK_BITS_ABOVE creates a mask starting AT the position and above * MASK_BITS_BELOW creates a mask starting one bit BELOW the position */ -#define ACPI_MASK_BITS_ABOVE(position) (~((ACPI_INTEGER_MAX) << ((u32) (position)))) -#define ACPI_MASK_BITS_BELOW(position) ((ACPI_INTEGER_MAX) << ((u32) (position))) +#define ACPI_MASK_BITS_ABOVE(position) (~((ACPI_UINT64_MAX) << ((u32) (position)))) +#define ACPI_MASK_BITS_BELOW(position) ((ACPI_UINT64_MAX) << ((u32) (position))) /* Bitfields within ACPI registers */ @@ -414,16 +414,16 @@ acpi_ut_ptr_exit (ACPI_DEBUG_PARAMETERS, (u8 *) _s); \ return (_s); }) #define return_VALUE(s) ACPI_DO_WHILE0 ({ \ - register acpi_integer _s = (s); \ + register u64 _s = (s); \ acpi_ut_value_exit (ACPI_DEBUG_PARAMETERS, _s); \ return (_s); }) #define return_UINT8(s) ACPI_DO_WHILE0 ({ \ register u8 _s = (u8) (s); \ - acpi_ut_value_exit (ACPI_DEBUG_PARAMETERS, (acpi_integer) _s); \ + acpi_ut_value_exit (ACPI_DEBUG_PARAMETERS, (u64) _s); \ return (_s); }) #define return_UINT32(s) ACPI_DO_WHILE0 ({ \ register u32 _s = (u32) (s); \ - acpi_ut_value_exit (ACPI_DEBUG_PARAMETERS, (acpi_integer) _s); \ + acpi_ut_value_exit (ACPI_DEBUG_PARAMETERS, (u64) _s); \ return (_s); }) #else /* Use original less-safe macros */ @@ -434,7 +434,7 @@ acpi_ut_ptr_exit (ACPI_DEBUG_PARAMETERS, (u8 *) (s)); \ return((s)); }) #define return_VALUE(s) ACPI_DO_WHILE0 ({ \ - acpi_ut_value_exit (ACPI_DEBUG_PARAMETERS, (acpi_integer) (s)); \ + acpi_ut_value_exit (ACPI_DEBUG_PARAMETERS, (u64) (s)); \ return((s)); }) #define return_UINT8(s) return_VALUE(s) #define return_UINT32(s) return_VALUE(s) diff --git a/drivers/acpi/acpica/acobject.h b/drivers/acpi/acpica/acobject.h index 6d0b4de68cf6..3b5d8bf51251 100644 --- a/drivers/acpi/acpica/acobject.h +++ b/drivers/acpi/acpica/acobject.h @@ -111,7 +111,7 @@ ACPI_OBJECT_COMMON_HEADER}; struct acpi_object_integer { ACPI_OBJECT_COMMON_HEADER u8 fill[3]; /* Prevent warning on some compilers */ - acpi_integer value; + u64 value; }; /* diff --git a/drivers/acpi/acpica/acutils.h b/drivers/acpi/acpica/acutils.h index d3ae626cf715..35df755251ce 100644 --- a/drivers/acpi/acpica/acutils.h +++ b/drivers/acpi/acpica/acutils.h @@ -134,7 +134,7 @@ char *acpi_ut_get_region_name(u8 space_id); char *acpi_ut_get_event_name(u32 event_id); -char acpi_ut_hex_to_ascii_char(acpi_integer integer, u32 position); +char acpi_ut_hex_to_ascii_char(u64 integer, u32 position); u8 acpi_ut_valid_object_type(acpi_object_type type); @@ -279,8 +279,7 @@ acpi_ut_status_exit(u32 line_number, void acpi_ut_value_exit(u32 line_number, const char *function_name, - const char *module_name, - u32 component_id, acpi_integer value); + const char *module_name, u32 component_id, u64 value); void acpi_ut_ptr_exit(u32 line_number, @@ -324,7 +323,7 @@ acpi_ut_evaluate_object(struct acpi_namespace_node *prefix_node, acpi_status acpi_ut_evaluate_numeric_object(char *object_name, struct acpi_namespace_node *device_node, - acpi_integer *value); + u64 *value); acpi_status acpi_ut_execute_STA(struct acpi_namespace_node *device_node, u32 *status_flags); @@ -437,14 +436,12 @@ void acpi_ut_delete_generic_state(union acpi_generic_state *state); * utmath */ acpi_status -acpi_ut_divide(acpi_integer in_dividend, - acpi_integer in_divisor, - acpi_integer * out_quotient, acpi_integer * out_remainder); +acpi_ut_divide(u64 in_dividend, + u64 in_divisor, u64 *out_quotient, u64 *out_remainder); acpi_status -acpi_ut_short_divide(acpi_integer in_dividend, - u32 divisor, - acpi_integer * out_quotient, u32 * out_remainder); +acpi_ut_short_divide(u64 in_dividend, + u32 divisor, u64 *out_quotient, u32 *out_remainder); /* * utmisc @@ -474,8 +471,7 @@ acpi_name acpi_ut_repair_name(char *name); u8 acpi_ut_valid_acpi_char(char character, u32 position); -acpi_status -acpi_ut_strtoul64(char *string, u32 base, acpi_integer * ret_integer); +acpi_status acpi_ut_strtoul64(char *string, u32 base, u64 * ret_integer); void ACPI_INTERNAL_VAR_XFACE acpi_ut_predefined_warning(const char *module_name, diff --git a/drivers/acpi/acpica/dsfield.c b/drivers/acpi/acpica/dsfield.c index effbf1550b03..bb13817e0c31 100644 --- a/drivers/acpi/acpica/dsfield.c +++ b/drivers/acpi/acpica/dsfield.c @@ -220,7 +220,7 @@ acpi_ds_get_field_names(struct acpi_create_field_info *info, union acpi_parse_object *arg) { acpi_status status; - acpi_integer position; + u64 position; ACPI_FUNCTION_TRACE_PTR(ds_get_field_names, info); @@ -240,8 +240,8 @@ acpi_ds_get_field_names(struct acpi_create_field_info *info, switch (arg->common.aml_opcode) { case AML_INT_RESERVEDFIELD_OP: - position = (acpi_integer) info->field_bit_position - + (acpi_integer) arg->common.value.size; + position = (u64) info->field_bit_position + + (u64) arg->common.value.size; if (position > ACPI_UINT32_MAX) { ACPI_ERROR((AE_INFO, @@ -305,8 +305,8 @@ acpi_ds_get_field_names(struct acpi_create_field_info *info, /* Keep track of bit position for the next field */ - position = (acpi_integer) info->field_bit_position - + (acpi_integer) arg->common.value.size; + position = (u64) info->field_bit_position + + (u64) arg->common.value.size; if (position > ACPI_UINT32_MAX) { ACPI_ERROR((AE_INFO, diff --git a/drivers/acpi/acpica/dsobject.c b/drivers/acpi/acpica/dsobject.c index edd7aa238cf1..891e08bf560b 100644 --- a/drivers/acpi/acpica/dsobject.c +++ b/drivers/acpi/acpica/dsobject.c @@ -684,7 +684,7 @@ acpi_ds_init_object_from_op(struct acpi_walk_state *walk_state, case AML_ONES_OP: - obj_desc->integer.value = ACPI_INTEGER_MAX; + obj_desc->integer.value = ACPI_UINT64_MAX; /* Truncate value if we are executing from a 32-bit ACPI table */ diff --git a/drivers/acpi/acpica/evregion.c b/drivers/acpi/acpica/evregion.c index 654b2833598c..98fd210e87b2 100644 --- a/drivers/acpi/acpica/evregion.c +++ b/drivers/acpi/acpica/evregion.c @@ -329,7 +329,7 @@ acpi_ev_execute_reg_method(union acpi_operand_object *region_obj, u32 function) * region_offset - Where in the region to read or write * bit_width - Field width in bits (8, 16, 32, or 64) * Value - Pointer to in or out value, must be - * full 64-bit acpi_integer + * a full 64-bit integer * * RETURN: Status * @@ -341,8 +341,7 @@ acpi_ev_execute_reg_method(union acpi_operand_object *region_obj, u32 function) acpi_status acpi_ev_address_space_dispatch(union acpi_operand_object *region_obj, u32 function, - u32 region_offset, - u32 bit_width, acpi_integer * value) + u32 region_offset, u32 bit_width, u64 *value) { acpi_status status; acpi_adr_space_handler handler; diff --git a/drivers/acpi/acpica/evrgnini.c b/drivers/acpi/acpica/evrgnini.c index 86bd5a7f40d0..2e3b0334072f 100644 --- a/drivers/acpi/acpica/evrgnini.c +++ b/drivers/acpi/acpica/evrgnini.c @@ -168,7 +168,7 @@ acpi_ev_pci_config_region_setup(acpi_handle handle, void *handler_context, void **region_context) { acpi_status status = AE_OK; - acpi_integer pci_value; + u64 pci_value; struct acpi_pci_id *pci_id = *region_context; union acpi_operand_object *handler_obj; struct acpi_namespace_node *parent_node; diff --git a/drivers/acpi/acpica/exconfig.c b/drivers/acpi/acpica/exconfig.c index cee2bceb2169..7e8b3bedc376 100644 --- a/drivers/acpi/acpica/exconfig.c +++ b/drivers/acpi/acpica/exconfig.c @@ -284,7 +284,7 @@ static acpi_status acpi_ex_region_read(union acpi_operand_object *obj_desc, u32 length, u8 *buffer) { acpi_status status; - acpi_integer value; + u64 value; u32 region_offset = 0; u32 i; diff --git a/drivers/acpi/acpica/exconvrt.c b/drivers/acpi/acpica/exconvrt.c index adcaf3b89587..bda7aed0404b 100644 --- a/drivers/acpi/acpica/exconvrt.c +++ b/drivers/acpi/acpica/exconvrt.c @@ -51,8 +51,7 @@ ACPI_MODULE_NAME("exconvrt") /* Local prototypes */ static u32 -acpi_ex_convert_to_ascii(acpi_integer integer, - u16 base, u8 * string, u8 max_length); +acpi_ex_convert_to_ascii(u64 integer, u16 base, u8 *string, u8 max_length); /******************************************************************************* * @@ -75,7 +74,7 @@ acpi_ex_convert_to_integer(union acpi_operand_object *obj_desc, { union acpi_operand_object *return_desc; u8 *pointer; - acpi_integer result; + u64 result; u32 i; u32 count; acpi_status status; @@ -155,7 +154,7 @@ acpi_ex_convert_to_integer(union acpi_operand_object *obj_desc, * Little endian is used, meaning that the first byte of the buffer * is the LSB of the integer */ - result |= (((acpi_integer) pointer[i]) << (i * 8)); + result |= (((u64) pointer[i]) << (i * 8)); } break; @@ -285,10 +284,9 @@ acpi_ex_convert_to_buffer(union acpi_operand_object *obj_desc, ******************************************************************************/ static u32 -acpi_ex_convert_to_ascii(acpi_integer integer, - u16 base, u8 * string, u8 data_width) +acpi_ex_convert_to_ascii(u64 integer, u16 base, u8 *string, u8 data_width) { - acpi_integer digit; + u64 digit; u32 i; u32 j; u32 k = 0; @@ -531,10 +529,9 @@ acpi_ex_convert_to_string(union acpi_operand_object * obj_desc, * (separated by commas or spaces) */ for (i = 0; i < obj_desc->buffer.length; i++) { - new_buf += acpi_ex_convert_to_ascii((acpi_integer) - obj_desc->buffer. - pointer[i], base, - new_buf, 1); + new_buf += acpi_ex_convert_to_ascii((u64) obj_desc-> + buffer.pointer[i], + base, new_buf, 1); *new_buf++ = separator; /* each separated by a comma or space */ } diff --git a/drivers/acpi/acpica/exfield.c b/drivers/acpi/acpica/exfield.c index c9190c784194..6c79fecbee42 100644 --- a/drivers/acpi/acpica/exfield.c +++ b/drivers/acpi/acpica/exfield.c @@ -130,7 +130,7 @@ acpi_ex_read_data_from_field(struct acpi_walk_state *walk_state, /* Call the region handler for the read */ status = acpi_ex_access_region(obj_desc, 0, - ACPI_CAST_PTR(acpi_integer, + ACPI_CAST_PTR(u64, buffer_desc-> buffer.pointer), function); @@ -141,7 +141,7 @@ acpi_ex_read_data_from_field(struct acpi_walk_state *walk_state, /* * Allocate a buffer for the contents of the field. * - * If the field is larger than the size of an acpi_integer, create + * If the field is larger than the current integer width, create * a BUFFER to hold it. Otherwise, use an INTEGER. This allows * the use of arithmetic operators on the returned value if the * field size is equal or smaller than an Integer. @@ -306,8 +306,7 @@ acpi_ex_write_data_to_field(union acpi_operand_object *source_desc, * same buffer) */ status = acpi_ex_access_region(obj_desc, 0, - (acpi_integer *) buffer, - function); + (u64 *) buffer, function); acpi_ex_release_global_lock(obj_desc->common_field.field_flags); *result_desc = buffer_desc; diff --git a/drivers/acpi/acpica/exfldio.c b/drivers/acpi/acpica/exfldio.c index dc2f9e8bee6e..f68a216168be 100644 --- a/drivers/acpi/acpica/exfldio.c +++ b/drivers/acpi/acpica/exfldio.c @@ -55,11 +55,10 @@ ACPI_MODULE_NAME("exfldio") static acpi_status acpi_ex_field_datum_io(union acpi_operand_object *obj_desc, u32 field_datum_byte_offset, - acpi_integer * value, u32 read_write); + u64 *value, u32 read_write); static u8 -acpi_ex_register_overflow(union acpi_operand_object *obj_desc, - acpi_integer value); +acpi_ex_register_overflow(union acpi_operand_object *obj_desc, u64 value); static acpi_status acpi_ex_setup_region(union acpi_operand_object *obj_desc, @@ -212,7 +211,7 @@ acpi_ex_setup_region(union acpi_operand_object *obj_desc, * field_datum_byte_offset - Byte offset of this datum within the * parent field * Value - Where to store value (must at least - * the size of acpi_integer) + * 64 bits) * Function - Read or Write flag plus other region- * dependent flags * @@ -224,8 +223,7 @@ acpi_ex_setup_region(union acpi_operand_object *obj_desc, acpi_status acpi_ex_access_region(union acpi_operand_object *obj_desc, - u32 field_datum_byte_offset, - acpi_integer * value, u32 function) + u32 field_datum_byte_offset, u64 *value, u32 function) { acpi_status status; union acpi_operand_object *rgn_desc; @@ -317,8 +315,7 @@ acpi_ex_access_region(union acpi_operand_object *obj_desc, ******************************************************************************/ static u8 -acpi_ex_register_overflow(union acpi_operand_object *obj_desc, - acpi_integer value) +acpi_ex_register_overflow(union acpi_operand_object *obj_desc, u64 value) { if (obj_desc->common_field.bit_length >= ACPI_INTEGER_BIT_SIZE) { @@ -329,7 +326,7 @@ acpi_ex_register_overflow(union acpi_operand_object *obj_desc, return (FALSE); } - if (value >= ((acpi_integer) 1 << obj_desc->common_field.bit_length)) { + if (value >= ((u64) 1 << obj_desc->common_field.bit_length)) { /* * The Value is larger than the maximum value that can fit into * the register. @@ -362,11 +359,10 @@ acpi_ex_register_overflow(union acpi_operand_object *obj_desc, static acpi_status acpi_ex_field_datum_io(union acpi_operand_object *obj_desc, - u32 field_datum_byte_offset, - acpi_integer * value, u32 read_write) + u32 field_datum_byte_offset, u64 *value, u32 read_write) { acpi_status status; - acpi_integer local_value; + u64 local_value; ACPI_FUNCTION_TRACE_U32(ex_field_datum_io, field_datum_byte_offset); @@ -439,8 +435,8 @@ acpi_ex_field_datum_io(union acpi_operand_object *obj_desc, * the register */ if (acpi_ex_register_overflow(obj_desc->bank_field.bank_obj, - (acpi_integer) obj_desc-> - bank_field.value)) { + (u64) obj_desc->bank_field. + value)) { return_ACPI_STATUS(AE_AML_REGISTER_LIMIT); } @@ -481,8 +477,8 @@ acpi_ex_field_datum_io(union acpi_operand_object *obj_desc, * the register */ if (acpi_ex_register_overflow(obj_desc->index_field.index_obj, - (acpi_integer) obj_desc-> - index_field.value)) { + (u64) obj_desc->index_field. + value)) { return_ACPI_STATUS(AE_AML_REGISTER_LIMIT); } @@ -512,7 +508,7 @@ acpi_ex_field_datum_io(union acpi_operand_object *obj_desc, status = acpi_ex_extract_from_field(obj_desc->index_field. data_obj, value, - sizeof(acpi_integer)); + sizeof(u64)); } else { /* Write the datum to the data_register */ @@ -523,7 +519,7 @@ acpi_ex_field_datum_io(union acpi_operand_object *obj_desc, status = acpi_ex_insert_into_field(obj_desc->index_field. data_obj, value, - sizeof(acpi_integer)); + sizeof(u64)); } break; @@ -571,13 +567,12 @@ acpi_ex_field_datum_io(union acpi_operand_object *obj_desc, acpi_status acpi_ex_write_with_update_rule(union acpi_operand_object *obj_desc, - acpi_integer mask, - acpi_integer field_value, - u32 field_datum_byte_offset) + u64 mask, + u64 field_value, u32 field_datum_byte_offset) { acpi_status status = AE_OK; - acpi_integer merged_value; - acpi_integer current_value; + u64 merged_value; + u64 current_value; ACPI_FUNCTION_TRACE_U32(ex_write_with_update_rule, mask); @@ -587,7 +582,7 @@ acpi_ex_write_with_update_rule(union acpi_operand_object *obj_desc, /* If the mask is all ones, we don't need to worry about the update rule */ - if (mask != ACPI_INTEGER_MAX) { + if (mask != ACPI_UINT64_MAX) { /* Decode the update rule */ @@ -678,8 +673,8 @@ acpi_ex_extract_from_field(union acpi_operand_object *obj_desc, void *buffer, u32 buffer_length) { acpi_status status; - acpi_integer raw_datum; - acpi_integer merged_datum; + u64 raw_datum; + u64 merged_datum; u32 field_offset = 0; u32 buffer_offset = 0; u32 buffer_tail_bits; @@ -804,10 +799,10 @@ acpi_ex_insert_into_field(union acpi_operand_object *obj_desc, void *buffer, u32 buffer_length) { acpi_status status; - acpi_integer mask; - acpi_integer width_mask; - acpi_integer merged_datum; - acpi_integer raw_datum = 0; + u64 mask; + u64 width_mask; + u64 merged_datum; + u64 raw_datum = 0; u32 field_offset = 0; u32 buffer_offset = 0; u32 buffer_tail_bits; @@ -855,7 +850,7 @@ acpi_ex_insert_into_field(union acpi_operand_object *obj_desc, * shift operator */ if (obj_desc->common_field.access_bit_width == ACPI_INTEGER_BIT_SIZE) { - width_mask = ACPI_INTEGER_MAX; + width_mask = ACPI_UINT64_MAX; } else { width_mask = ACPI_MASK_BITS_ABOVE(obj_desc->common_field. diff --git a/drivers/acpi/acpica/exmisc.c b/drivers/acpi/acpica/exmisc.c index d29e542bb6df..c5bb1eeed2df 100644 --- a/drivers/acpi/acpica/exmisc.c +++ b/drivers/acpi/acpica/exmisc.c @@ -409,8 +409,7 @@ acpi_ex_do_concatenate(union acpi_operand_object *operand0, * ******************************************************************************/ -acpi_integer -acpi_ex_do_math_op(u16 opcode, acpi_integer integer0, acpi_integer integer1) +u64 acpi_ex_do_math_op(u16 opcode, u64 integer0, u64 integer1) { ACPI_FUNCTION_ENTRY(); @@ -498,8 +497,7 @@ acpi_ex_do_math_op(u16 opcode, acpi_integer integer0, acpi_integer integer1) acpi_status acpi_ex_do_logical_numeric_op(u16 opcode, - acpi_integer integer0, - acpi_integer integer1, u8 * logical_result) + u64 integer0, u64 integer1, u8 *logical_result) { acpi_status status = AE_OK; u8 local_result = FALSE; @@ -564,8 +562,8 @@ acpi_ex_do_logical_op(u16 opcode, union acpi_operand_object *operand1, u8 * logical_result) { union acpi_operand_object *local_operand1 = operand1; - acpi_integer integer0; - acpi_integer integer1; + u64 integer0; + u64 integer1; u32 length0; u32 length1; acpi_status status = AE_OK; diff --git a/drivers/acpi/acpica/exoparg1.c b/drivers/acpi/acpica/exoparg1.c index 2b2128e52d42..99adbab5acbf 100644 --- a/drivers/acpi/acpica/exoparg1.c +++ b/drivers/acpi/acpica/exoparg1.c @@ -261,8 +261,8 @@ acpi_status acpi_ex_opcode_1A_1T_1R(struct acpi_walk_state *walk_state) union acpi_operand_object *return_desc2 = NULL; u32 temp32; u32 i; - acpi_integer power_of_ten; - acpi_integer digit; + u64 power_of_ten; + u64 digit; ACPI_FUNCTION_TRACE_STR(ex_opcode_1A_1T_1R, acpi_ps_get_opcode_name(walk_state->opcode)); @@ -362,7 +362,7 @@ acpi_status acpi_ex_opcode_1A_1T_1R(struct acpi_walk_state *walk_state) /* Sum the digit into the result with the current power of 10 */ return_desc->integer.value += - (((acpi_integer) temp32) * power_of_ten); + (((u64) temp32) * power_of_ten); /* Shift to next BCD digit */ @@ -392,7 +392,7 @@ acpi_status acpi_ex_opcode_1A_1T_1R(struct acpi_walk_state *walk_state) * remainder from above */ return_desc->integer.value |= - (((acpi_integer) temp32) << ACPI_MUL_4(i)); + (((u64) temp32) << ACPI_MUL_4(i)); } /* Overflow if there is any data left in Digit */ @@ -439,7 +439,7 @@ acpi_status acpi_ex_opcode_1A_1T_1R(struct acpi_walk_state *walk_state) /* The object exists in the namespace, return TRUE */ - return_desc->integer.value = ACPI_INTEGER_MAX; + return_desc->integer.value = ACPI_UINT64_MAX; goto cleanup; default: @@ -589,7 +589,7 @@ acpi_status acpi_ex_opcode_1A_0T_1R(struct acpi_walk_state *walk_state) union acpi_operand_object *return_desc = NULL; acpi_status status = AE_OK; u32 type; - acpi_integer value; + u64 value; ACPI_FUNCTION_TRACE_STR(ex_opcode_1A_0T_1R, acpi_ps_get_opcode_name(walk_state->opcode)); @@ -610,7 +610,7 @@ acpi_status acpi_ex_opcode_1A_0T_1R(struct acpi_walk_state *walk_state) * return_desc->Integer.Value is initially == 0 (FALSE) from above. */ if (!operand[0]->integer.value) { - return_desc->integer.value = ACPI_INTEGER_MAX; + return_desc->integer.value = ACPI_UINT64_MAX; } break; diff --git a/drivers/acpi/acpica/exoparg2.c b/drivers/acpi/acpica/exoparg2.c index ea115021ee7d..22841bbbe63c 100644 --- a/drivers/acpi/acpica/exoparg2.c +++ b/drivers/acpi/acpica/exoparg2.c @@ -282,7 +282,7 @@ acpi_status acpi_ex_opcode_2A_1T_1R(struct acpi_walk_state *walk_state) { union acpi_operand_object **operand = &walk_state->operands[0]; union acpi_operand_object *return_desc = NULL; - acpi_integer index; + u64 index; acpi_status status = AE_OK; acpi_size length; @@ -584,7 +584,7 @@ acpi_status acpi_ex_opcode_2A_0T_1R(struct acpi_walk_state *walk_state) * Default is FALSE (zero) */ if (logical_result) { - return_desc->integer.value = ACPI_INTEGER_MAX; + return_desc->integer.value = ACPI_UINT64_MAX; } cleanup: diff --git a/drivers/acpi/acpica/exoparg3.c b/drivers/acpi/acpica/exoparg3.c index 25d1cd35c3e1..8bb1012ef44e 100644 --- a/drivers/acpi/acpica/exoparg3.c +++ b/drivers/acpi/acpica/exoparg3.c @@ -148,7 +148,7 @@ acpi_status acpi_ex_opcode_3A_1T_1R(struct acpi_walk_state *walk_state) union acpi_operand_object *return_desc = NULL; char *buffer = NULL; acpi_status status = AE_OK; - acpi_integer index; + u64 index; acpi_size length; ACPI_FUNCTION_TRACE_STR(ex_opcode_3A_1T_1R, diff --git a/drivers/acpi/acpica/exoparg6.c b/drivers/acpi/acpica/exoparg6.c index 580abbd924dc..f256b6a25f2e 100644 --- a/drivers/acpi/acpica/exoparg6.c +++ b/drivers/acpi/acpica/exoparg6.c @@ -218,7 +218,7 @@ acpi_status acpi_ex_opcode_6A_0T_1R(struct acpi_walk_state * walk_state) union acpi_operand_object **operand = &walk_state->operands[0]; union acpi_operand_object *return_desc = NULL; acpi_status status = AE_OK; - acpi_integer index; + u64 index; union acpi_operand_object *this_element; ACPI_FUNCTION_TRACE_STR(ex_opcode_6A_0T_1R, @@ -253,9 +253,9 @@ acpi_status acpi_ex_opcode_6A_0T_1R(struct acpi_walk_state * walk_state) } /* Create an integer for the return value */ - /* Default return value is ACPI_INTEGER_MAX if no match found */ + /* Default return value is ACPI_UINT64_MAX if no match found */ - return_desc = acpi_ut_create_integer_object(ACPI_INTEGER_MAX); + return_desc = acpi_ut_create_integer_object(ACPI_UINT64_MAX); if (!return_desc) { status = AE_NO_MEMORY; goto cleanup; @@ -270,7 +270,7 @@ acpi_status acpi_ex_opcode_6A_0T_1R(struct acpi_walk_state * walk_state) * * Upon finding a match, the loop will terminate via "break" at * the bottom. If it terminates "normally", match_value will be - * ACPI_INTEGER_MAX (Ones) (its initial value) indicating that no + * ACPI_UINT64_MAX (Ones) (its initial value) indicating that no * match was found. */ for (; index < operand[0]->package.count; index++) { diff --git a/drivers/acpi/acpica/exregion.c b/drivers/acpi/acpica/exregion.c index 0cd88f6c95f7..486b2e5661b6 100644 --- a/drivers/acpi/acpica/exregion.c +++ b/drivers/acpi/acpica/exregion.c @@ -70,7 +70,7 @@ acpi_status acpi_ex_system_memory_space_handler(u32 function, acpi_physical_address address, u32 bit_width, - acpi_integer * value, + u64 *value, void *handler_context, void *region_context) { acpi_status status = AE_OK; @@ -115,8 +115,7 @@ acpi_ex_system_memory_space_handler(u32 function, * Hardware does not support non-aligned data transfers, we must verify * the request. */ - (void)acpi_ut_short_divide((acpi_integer) address, length, NULL, - &remainder); + (void)acpi_ut_short_divide((u64) address, length, NULL, &remainder); if (remainder != 0) { return_ACPI_STATUS(AE_AML_ALIGNMENT); } @@ -128,10 +127,9 @@ acpi_ex_system_memory_space_handler(u32 function, * 2) Address beyond the current mapping? */ if ((address < mem_info->mapped_physical_address) || - (((acpi_integer) address + length) > ((acpi_integer) - mem_info-> - mapped_physical_address + - mem_info->mapped_length))) { + (((u64) address + length) > ((u64) + mem_info->mapped_physical_address + + mem_info->mapped_length))) { /* * The request cannot be resolved by the current memory mapping; * Delete the existing mapping and create a new one. @@ -193,8 +191,7 @@ acpi_ex_system_memory_space_handler(u32 function, * access */ logical_addr_ptr = mem_info->mapped_logical_address + - ((acpi_integer) address - - (acpi_integer) mem_info->mapped_physical_address); + ((u64) address - (u64) mem_info->mapped_physical_address); ACPI_DEBUG_PRINT((ACPI_DB_INFO, "System-Memory (width %d) R/W %d Address=%8.8X%8.8X\n", @@ -215,19 +212,19 @@ acpi_ex_system_memory_space_handler(u32 function, *value = 0; switch (bit_width) { case 8: - *value = (acpi_integer) ACPI_GET8(logical_addr_ptr); + *value = (u64) ACPI_GET8(logical_addr_ptr); break; case 16: - *value = (acpi_integer) ACPI_GET16(logical_addr_ptr); + *value = (u64) ACPI_GET16(logical_addr_ptr); break; case 32: - *value = (acpi_integer) ACPI_GET32(logical_addr_ptr); + *value = (u64) ACPI_GET32(logical_addr_ptr); break; case 64: - *value = (acpi_integer) ACPI_GET64(logical_addr_ptr); + *value = (u64) ACPI_GET64(logical_addr_ptr); break; default: @@ -291,7 +288,7 @@ acpi_status acpi_ex_system_io_space_handler(u32 function, acpi_physical_address address, u32 bit_width, - acpi_integer * value, + u64 *value, void *handler_context, void *region_context) { acpi_status status = AE_OK; @@ -350,7 +347,7 @@ acpi_status acpi_ex_pci_config_space_handler(u32 function, acpi_physical_address address, u32 bit_width, - acpi_integer * value, + u64 *value, void *handler_context, void *region_context) { acpi_status status = AE_OK; @@ -425,7 +422,7 @@ acpi_status acpi_ex_cmos_space_handler(u32 function, acpi_physical_address address, u32 bit_width, - acpi_integer * value, + u64 *value, void *handler_context, void *region_context) { acpi_status status = AE_OK; @@ -457,7 +454,7 @@ acpi_status acpi_ex_pci_bar_space_handler(u32 function, acpi_physical_address address, u32 bit_width, - acpi_integer * value, + u64 *value, void *handler_context, void *region_context) { acpi_status status = AE_OK; @@ -489,7 +486,7 @@ acpi_status acpi_ex_data_table_space_handler(u32 function, acpi_physical_address address, u32 bit_width, - acpi_integer * value, + u64 *value, void *handler_context, void *region_context) { ACPI_FUNCTION_TRACE(ex_data_table_space_handler); diff --git a/drivers/acpi/acpica/exsystem.c b/drivers/acpi/acpica/exsystem.c index c6cb6042603c..e11b6cb42a57 100644 --- a/drivers/acpi/acpica/exsystem.c +++ b/drivers/acpi/acpica/exsystem.c @@ -193,7 +193,7 @@ acpi_status acpi_ex_system_do_stall(u32 how_long) * ******************************************************************************/ -acpi_status acpi_ex_system_do_suspend(acpi_integer how_long) +acpi_status acpi_ex_system_do_suspend(u64 how_long) { ACPI_FUNCTION_ENTRY(); diff --git a/drivers/acpi/acpica/exutils.c b/drivers/acpi/acpica/exutils.c index 0f2ce9c52f02..74c24d517f81 100644 --- a/drivers/acpi/acpica/exutils.c +++ b/drivers/acpi/acpica/exutils.c @@ -67,7 +67,7 @@ ACPI_MODULE_NAME("exutils") /* Local prototypes */ -static u32 acpi_ex_digits_needed(acpi_integer value, u32 base); +static u32 acpi_ex_digits_needed(u64 value, u32 base); #ifndef ACPI_NO_METHOD_EXECUTION /******************************************************************************* @@ -230,7 +230,7 @@ void acpi_ex_truncate_for32bit_table(union acpi_operand_object *obj_desc) * We are running a method that exists in a 32-bit ACPI table. * Truncate the value to 32 bits by zeroing out the upper 32-bit field */ - obj_desc->integer.value &= (acpi_integer) ACPI_UINT32_MAX; + obj_desc->integer.value &= (u64) ACPI_UINT32_MAX; } } @@ -327,14 +327,14 @@ void acpi_ex_release_global_lock(u32 field_flags) * ******************************************************************************/ -static u32 acpi_ex_digits_needed(acpi_integer value, u32 base) +static u32 acpi_ex_digits_needed(u64 value, u32 base) { u32 num_digits; - acpi_integer current_value; + u64 current_value; ACPI_FUNCTION_TRACE(ex_digits_needed); - /* acpi_integer is unsigned, so we don't worry about a '-' prefix */ + /* u64 is unsigned, so we don't worry about a '-' prefix */ if (value == 0) { return_UINT32(1); @@ -370,7 +370,7 @@ static u32 acpi_ex_digits_needed(acpi_integer value, u32 base) * ******************************************************************************/ -void acpi_ex_eisa_id_to_string(char *out_string, acpi_integer compressed_id) +void acpi_ex_eisa_id_to_string(char *out_string, u64 compressed_id) { u32 swapped_id; @@ -394,10 +394,10 @@ void acpi_ex_eisa_id_to_string(char *out_string, acpi_integer compressed_id) (char)(0x40 + (((unsigned long)swapped_id >> 26) & 0x1F)); out_string[1] = (char)(0x40 + ((swapped_id >> 21) & 0x1F)); out_string[2] = (char)(0x40 + ((swapped_id >> 16) & 0x1F)); - out_string[3] = acpi_ut_hex_to_ascii_char((acpi_integer)swapped_id, 12); - out_string[4] = acpi_ut_hex_to_ascii_char((acpi_integer)swapped_id, 8); - out_string[5] = acpi_ut_hex_to_ascii_char((acpi_integer)swapped_id, 4); - out_string[6] = acpi_ut_hex_to_ascii_char((acpi_integer)swapped_id, 0); + out_string[3] = acpi_ut_hex_to_ascii_char((u64) swapped_id, 12); + out_string[4] = acpi_ut_hex_to_ascii_char((u64) swapped_id, 8); + out_string[5] = acpi_ut_hex_to_ascii_char((u64) swapped_id, 4); + out_string[6] = acpi_ut_hex_to_ascii_char((u64) swapped_id, 0); out_string[7] = 0; } @@ -418,7 +418,7 @@ void acpi_ex_eisa_id_to_string(char *out_string, acpi_integer compressed_id) * ******************************************************************************/ -void acpi_ex_integer_to_string(char *out_string, acpi_integer value) +void acpi_ex_integer_to_string(char *out_string, u64 value) { u32 count; u32 digits_needed; diff --git a/drivers/acpi/acpica/hwtimer.c b/drivers/acpi/acpica/hwtimer.c index ce0cbbc18ad0..1ef8e0bb250b 100644 --- a/drivers/acpi/acpica/hwtimer.c +++ b/drivers/acpi/acpica/hwtimer.c @@ -140,7 +140,7 @@ acpi_get_timer_duration(u32 start_ticks, u32 end_ticks, u32 * time_elapsed) { acpi_status status; u32 delta_ticks; - acpi_integer quotient; + u64 quotient; ACPI_FUNCTION_TRACE(acpi_get_timer_duration); diff --git a/drivers/acpi/acpica/psargs.c b/drivers/acpi/acpica/psargs.c index 6aa6a1a4d918..00493e108a01 100644 --- a/drivers/acpi/acpica/psargs.c +++ b/drivers/acpi/acpica/psargs.c @@ -403,7 +403,7 @@ acpi_ps_get_next_simple_arg(struct acpi_parse_state *parser_state, /* Get 1 byte from the AML stream */ opcode = AML_BYTE_OP; - arg->common.value.integer = (acpi_integer) * aml; + arg->common.value.integer = (u64) *aml; length = 1; break; diff --git a/drivers/acpi/acpica/rscreate.c b/drivers/acpi/acpica/rscreate.c index 61a038dbfe23..f2ee3b548609 100644 --- a/drivers/acpi/acpica/rscreate.c +++ b/drivers/acpi/acpica/rscreate.c @@ -182,7 +182,7 @@ acpi_rs_create_pci_routing_table(union acpi_operand_object *package_object, /* * Loop through the ACPI_INTERNAL_OBJECTS - Each object should be a - * package that in turn contains an acpi_integer Address, a u8 Pin, + * package that in turn contains an u64 Address, a u8 Pin, * a Name, and a u8 source_index. */ top_object_list = package_object->package.elements; diff --git a/drivers/acpi/acpica/utdebug.c b/drivers/acpi/acpica/utdebug.c index e156915fa0e8..983510640059 100644 --- a/drivers/acpi/acpica/utdebug.c +++ b/drivers/acpi/acpica/utdebug.c @@ -460,8 +460,7 @@ ACPI_EXPORT_SYMBOL(acpi_ut_status_exit) void acpi_ut_value_exit(u32 line_number, const char *function_name, - const char *module_name, - u32 component_id, acpi_integer value) + const char *module_name, u32 component_id, u64 value) { acpi_debug_print(ACPI_LV_FUNCTIONS, diff --git a/drivers/acpi/acpica/uteval.c b/drivers/acpi/acpica/uteval.c index f4c5ee8109bc..7f5e734ce7f7 100644 --- a/drivers/acpi/acpica/uteval.c +++ b/drivers/acpi/acpica/uteval.c @@ -348,7 +348,7 @@ acpi_ut_evaluate_object(struct acpi_namespace_node *prefix_node, acpi_status acpi_ut_evaluate_numeric_object(char *object_name, struct acpi_namespace_node *device_node, - acpi_integer *value) + u64 *value) { union acpi_operand_object *obj_desc; acpi_status status; diff --git a/drivers/acpi/acpica/utglobal.c b/drivers/acpi/acpica/utglobal.c index 49286a39b09e..eda3e656c4af 100644 --- a/drivers/acpi/acpica/utglobal.c +++ b/drivers/acpi/acpica/utglobal.c @@ -234,7 +234,7 @@ static const char acpi_gbl_hex_to_ascii[] = { * ******************************************************************************/ -char acpi_ut_hex_to_ascii_char(acpi_integer integer, u32 position) +char acpi_ut_hex_to_ascii_char(u64 integer, u32 position) { return (acpi_gbl_hex_to_ascii[(integer >> position) & 0xF]); diff --git a/drivers/acpi/acpica/utmath.c b/drivers/acpi/acpica/utmath.c index 7cfa1d8164d0..35059a14eb72 100644 --- a/drivers/acpi/acpica/utmath.c +++ b/drivers/acpi/acpica/utmath.c @@ -70,9 +70,8 @@ ACPI_MODULE_NAME("utmath") * ******************************************************************************/ acpi_status -acpi_ut_short_divide(acpi_integer dividend, - u32 divisor, - acpi_integer * out_quotient, u32 * out_remainder) +acpi_ut_short_divide(u64 dividend, + u32 divisor, u64 *out_quotient, u32 *out_remainder) { union uint64_overlay dividend_ovl; union uint64_overlay quotient; @@ -126,9 +125,8 @@ acpi_ut_short_divide(acpi_integer dividend, ******************************************************************************/ acpi_status -acpi_ut_divide(acpi_integer in_dividend, - acpi_integer in_divisor, - acpi_integer * out_quotient, acpi_integer * out_remainder) +acpi_ut_divide(u64 in_dividend, + u64 in_divisor, u64 *out_quotient, u64 *out_remainder) { union uint64_overlay dividend; union uint64_overlay divisor; @@ -199,9 +197,8 @@ acpi_ut_divide(acpi_integer in_dividend, * The 64-bit remainder must be generated. */ partial1 = quotient.part.lo * divisor.part.hi; - partial2.full = - (acpi_integer) quotient.part.lo * divisor.part.lo; - partial3.full = (acpi_integer) partial2.part.hi + partial1; + partial2.full = (u64) quotient.part.lo * divisor.part.lo; + partial3.full = (u64) partial2.part.hi + partial1; remainder.part.hi = partial3.part.lo; remainder.part.lo = partial2.part.lo; @@ -257,9 +254,8 @@ acpi_ut_divide(acpi_integer in_dividend, * ******************************************************************************/ acpi_status -acpi_ut_short_divide(acpi_integer in_dividend, - u32 divisor, - acpi_integer * out_quotient, u32 * out_remainder) +acpi_ut_short_divide(u64 in_dividend, + u32 divisor, u64 *out_quotient, u32 *out_remainder) { ACPI_FUNCTION_TRACE(ut_short_divide); @@ -284,9 +280,8 @@ acpi_ut_short_divide(acpi_integer in_dividend, } acpi_status -acpi_ut_divide(acpi_integer in_dividend, - acpi_integer in_divisor, - acpi_integer * out_quotient, acpi_integer * out_remainder) +acpi_ut_divide(u64 in_dividend, + u64 in_divisor, u64 *out_quotient, u64 *out_remainder) { ACPI_FUNCTION_TRACE(ut_divide); diff --git a/drivers/acpi/acpica/utmisc.c b/drivers/acpi/acpica/utmisc.c index fb55924e6e0f..32982e2ac384 100644 --- a/drivers/acpi/acpica/utmisc.c +++ b/drivers/acpi/acpica/utmisc.c @@ -724,13 +724,12 @@ acpi_name acpi_ut_repair_name(char *name) * ******************************************************************************/ -acpi_status -acpi_ut_strtoul64(char *string, u32 base, acpi_integer * ret_integer) +acpi_status acpi_ut_strtoul64(char *string, u32 base, u64 * ret_integer) { u32 this_digit = 0; - acpi_integer return_value = 0; - acpi_integer quotient; - acpi_integer dividend; + u64 return_value = 0; + u64 quotient; + u64 dividend; u32 to_integer_op = (base == ACPI_ANY_BASE); u32 mode32 = (acpi_gbl_integer_byte_width == 4); u8 valid_digits = 0; @@ -844,9 +843,8 @@ acpi_ut_strtoul64(char *string, u32 base, acpi_integer * ret_integer) /* Divide the digit into the correct position */ - (void) - acpi_ut_short_divide((dividend - (acpi_integer) this_digit), - base, "ient, NULL); + (void)acpi_ut_short_divide((dividend - (u64) this_digit), + base, "ient, NULL); if (return_value > quotient) { if (to_integer_op) { -- cgit v1.2.2 From 758d49313d0bdea1c41aa1d91ab204ca47177aae Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Thu, 21 Jan 2010 10:08:42 +0800 Subject: ACPICA: Disassembler: Remove obsolete "Integer64" field in parse object This field is no longer needed. The "Integer" field is 64 bit and is sufficient. Signed-off-by: Bob Moore Signed-off-by: Lin Ming Signed-off-by: Len Brown --- drivers/acpi/acpica/aclocal.h | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers') diff --git a/drivers/acpi/acpica/aclocal.h b/drivers/acpi/acpica/aclocal.h index 4894decfdcf5..c6d9f6d33bf7 100644 --- a/drivers/acpi/acpica/aclocal.h +++ b/drivers/acpi/acpica/aclocal.h @@ -651,7 +651,6 @@ struct acpi_opcode_info { union acpi_parse_value { u64 integer; /* Integer constant (Up to 64 bits) */ - struct uint64_struct integer64; /* Structure overlay for 2 32-bit Dwords */ u32 size; /* bytelist or field size */ char *string; /* NULL terminated string */ u8 *buffer; /* buffer or string */ -- cgit v1.2.2 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') 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.2 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') 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.2 From fc05475f867624dddd5ea7089cf8f434f95fbec5 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Fri, 22 Jan 2010 13:53:30 +0100 Subject: ARM: 5893/1: SPI AMBA PL022: Limit TX FIFO fills Added logic to cap TX FIFO fill size based on current free RX FIFO entries instead of TX status flags. This is to prevent an issue with RX FIFO overflows. Signed-off-by: Kevin Wells Signed-off-by: Linus Walleij Signed-off-by: Russell King --- drivers/spi/amba-pl022.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/spi/amba-pl022.c b/drivers/spi/amba-pl022.c index ff5bbb9c43c9..9aeb68113100 100644 --- a/drivers/spi/amba-pl022.c +++ b/drivers/spi/amba-pl022.c @@ -363,6 +363,7 @@ struct pl022 { void *rx_end; enum ssp_reading read; enum ssp_writing write; + u32 exp_fifo_level; }; /** @@ -501,6 +502,9 @@ static int flush(struct pl022 *pl022) while (readw(SSP_SR(pl022->virtbase)) & SSP_SR_MASK_RNE) readw(SSP_DR(pl022->virtbase)); } while ((readw(SSP_SR(pl022->virtbase)) & SSP_SR_MASK_BSY) && limit--); + + pl022->exp_fifo_level = 0; + return limit; } @@ -583,10 +587,9 @@ static void readwriter(struct pl022 *pl022) * errons in 8bit wide transfers on ARM variants (just 8 words * FIFO, means only 8x8 = 64 bits in FIFO) at least. * - * FIXME: currently we have no logic to account for this. - * perhaps there is even something broken in HW regarding - * 8bit transfers (it doesn't fail on 16bit) so this needs - * more investigation... + * To prevent this issue, the TX FIFO is only filled to the + * unused RX FIFO fill length, regardless of what the TX + * FIFO status flag indicates. */ dev_dbg(&pl022->adev->dev, "%s, rx: %p, rxend: %p, tx: %p, txend: %p\n", @@ -613,11 +616,12 @@ static void readwriter(struct pl022 *pl022) break; } pl022->rx += (pl022->cur_chip->n_bytes); + pl022->exp_fifo_level--; } /* - * Write as much as you can, while keeping an eye on the RX FIFO! + * Write as much as possible up to the RX FIFO size */ - while ((readw(SSP_SR(pl022->virtbase)) & SSP_SR_MASK_TNF) + while ((pl022->exp_fifo_level < pl022->vendor->fifodepth) && (pl022->tx < pl022->tx_end)) { switch (pl022->write) { case WRITING_NULL: @@ -634,6 +638,7 @@ static void readwriter(struct pl022 *pl022) break; } pl022->tx += (pl022->cur_chip->n_bytes); + pl022->exp_fifo_level++; /* * This inner reader takes care of things appearing in the RX * FIFO as we're transmitting. This will happen a lot since the @@ -660,6 +665,7 @@ static void readwriter(struct pl022 *pl022) break; } pl022->rx += (pl022->cur_chip->n_bytes); + pl022->exp_fifo_level--; } } /* -- cgit v1.2.2 From f28e8a4d027e4e21c3d0a52706527bb87397bea0 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Mon, 25 Jan 2010 07:14:46 +0100 Subject: ARM: 5896/1: MMCI: work around a hardware bug in U300 In the U300 some hardware bug makes the status flag not come up signalling a successful write (or anything else, like an error, for that matter) on write requests. This little quirk makes the writes work on U300. Signed-off-by: Linus Walleij Signed-off-by: Russell King --- drivers/mmc/host/mmci.c | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'drivers') diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c index 90d168ad03b6..643818a5ac45 100644 --- a/drivers/mmc/host/mmci.c +++ b/drivers/mmc/host/mmci.c @@ -184,6 +184,17 @@ mmci_data_irq(struct mmci_host *host, struct mmc_data *data, { if (status & MCI_DATABLOCKEND) { host->data_xfered += data->blksz; +#ifdef CONFIG_ARCH_U300 + /* + * On the U300 some signal or other is + * badly routed so that a data write does + * not properly terminate with a MCI_DATAEND + * status flag. This quirk will make writes + * work again. + */ + if (data->flags & MMC_DATA_WRITE) + status |= MCI_DATAEND; +#endif } if (status & (MCI_DATACRCFAIL|MCI_DATATIMEOUT|MCI_TXUNDERRUN|MCI_RXOVERRUN)) { if (status & MCI_DATACRCFAIL) -- cgit v1.2.2 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 --- 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 ++-- 15 files changed, 57 insertions(+), 57 deletions(-) (limited to 'drivers') 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); -- cgit v1.2.2 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') 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.2 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') 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.2 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 ++++++++++++++++++++++++++++++++++------- 1 file changed, 34 insertions(+), 7 deletions(-) (limited to 'drivers') 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); /* -- cgit v1.2.2 From 99b089c3c38a83ebaeb1cc4584ddcde841626467 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Sat, 30 Jan 2010 00:53:29 -0800 Subject: Input: Mac button emulation - implement as an input filter Current implementation of Mac mouse button emulation plugs into legacy keyboard driver, converts certain keys into button events on a separate device, and suppresses the real events from reaching tty. This worked well enough until user space started using evdev which was completely unaware of this arrangement and kept sending original key presses to its users. Change the implementation to use newly added input filter framework so that original key presses are not transmitted to any handlers. As a bonus remove SYSCTL dependencies from the code and use Kconfig instead; also do not create the emulated mouse device until user activates emulation. Signed-off-by: Dmitry Torokhov --- drivers/char/keyboard.c | 5 - drivers/macintosh/Kconfig | 1 + drivers/macintosh/mac_hid.c | 257 ++++++++++++++++++++++++++++++++------------ 3 files changed, 188 insertions(+), 75 deletions(-) (limited to 'drivers') diff --git a/drivers/char/keyboard.c b/drivers/char/keyboard.c index f706b1dffdb3..cbf64b985ef4 100644 --- a/drivers/char/keyboard.c +++ b/drivers/char/keyboard.c @@ -1185,11 +1185,6 @@ static void kbd_keycode(unsigned int keycode, int down, int hw_raw) rep = (down == 2); -#ifdef CONFIG_MAC_EMUMOUSEBTN - if (mac_hid_mouse_emulate_buttons(1, keycode, down)) - return; -#endif /* CONFIG_MAC_EMUMOUSEBTN */ - if ((raw_mode = (kbd->kbdmode == VC_RAW)) && !hw_raw) if (emulate_raw(vc, keycode, !down << 7)) if (keycode < BTN_MISC && printk_ratelimit()) diff --git a/drivers/macintosh/Kconfig b/drivers/macintosh/Kconfig index 3d906833948d..aa3c27e5255d 100644 --- a/drivers/macintosh/Kconfig +++ b/drivers/macintosh/Kconfig @@ -172,6 +172,7 @@ config INPUT_ADBHID config MAC_EMUMOUSEBTN bool "Support for mouse button 2+3 emulation" + depends on SYSCTL select INPUT help This provides generic support for emulating the 2nd and 3rd mouse diff --git a/drivers/macintosh/mac_hid.c b/drivers/macintosh/mac_hid.c index 7b4ef5bb556b..0b210a90aef5 100644 --- a/drivers/macintosh/mac_hid.c +++ b/drivers/macintosh/mac_hid.c @@ -13,17 +13,195 @@ #include #include #include -#include - -static struct input_dev *emumousebtn; -static int emumousebtn_input_register(void); static int mouse_emulate_buttons; static int mouse_button2_keycode = KEY_RIGHTCTRL; /* right control key */ static int mouse_button3_keycode = KEY_RIGHTALT; /* right option key */ -static int mouse_last_keycode; -#if defined(CONFIG_SYSCTL) +static struct input_dev *mac_hid_emumouse_dev; + +static int mac_hid_create_emumouse(void) +{ + static struct lock_class_key mac_hid_emumouse_dev_event_class; + static struct lock_class_key mac_hid_emumouse_dev_mutex_class; + int err; + + mac_hid_emumouse_dev = input_allocate_device(); + if (!mac_hid_emumouse_dev) + return -ENOMEM; + + lockdep_set_class(&mac_hid_emumouse_dev->event_lock, + &mac_hid_emumouse_dev_event_class); + lockdep_set_class(&mac_hid_emumouse_dev->mutex, + &mac_hid_emumouse_dev_mutex_class); + + mac_hid_emumouse_dev->name = "Macintosh mouse button emulation"; + mac_hid_emumouse_dev->id.bustype = BUS_ADB; + mac_hid_emumouse_dev->id.vendor = 0x0001; + mac_hid_emumouse_dev->id.product = 0x0001; + mac_hid_emumouse_dev->id.version = 0x0100; + + mac_hid_emumouse_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL); + mac_hid_emumouse_dev->keybit[BIT_WORD(BTN_MOUSE)] = + BIT_MASK(BTN_LEFT) | BIT_MASK(BTN_MIDDLE) | BIT_MASK(BTN_RIGHT); + mac_hid_emumouse_dev->relbit[0] = BIT_MASK(REL_X) | BIT_MASK(REL_Y); + + err = input_register_device(mac_hid_emumouse_dev); + if (err) { + input_free_device(mac_hid_emumouse_dev); + mac_hid_emumouse_dev = NULL; + return err; + } + + return 0; +} + +static void mac_hid_destroy_emumouse(void) +{ + input_unregister_device(mac_hid_emumouse_dev); + mac_hid_emumouse_dev = NULL; +} + +static bool mac_hid_emumouse_filter(struct input_handle *handle, + unsigned int type, unsigned int code, + int value) +{ + unsigned int btn; + + if (type != EV_KEY) + return false; + + if (code == mouse_button2_keycode) + btn = BTN_MIDDLE; + else if (code == mouse_button3_keycode) + btn = BTN_RIGHT; + else + return false; + + input_report_key(mac_hid_emumouse_dev, btn, value); + input_sync(mac_hid_emumouse_dev); + + return true; +} + +static int mac_hid_emumouse_connect(struct input_handler *handler, + struct input_dev *dev, + const struct input_device_id *id) +{ + struct input_handle *handle; + int error; + + /* Don't bind to ourselves */ + if (dev == mac_hid_emumouse_dev) + return -ENODEV; + + handle = kzalloc(sizeof(struct input_handle), GFP_KERNEL); + if (!handle) + return -ENOMEM; + + handle->dev = dev; + handle->handler = handler; + handle->name = "mac-button-emul"; + + error = input_register_handle(handle); + if (error) { + printk(KERN_ERR + "mac_hid: Failed to register button emulation handle, " + "error %d\n", error); + goto err_free; + } + + error = input_open_device(handle); + if (error) { + printk(KERN_ERR + "mac_hid: Failed to open input device, error %d\n", + error); + goto err_unregister; + } + + return 0; + + err_unregister: + input_unregister_handle(handle); + err_free: + kfree(handle); + return error; +} + +static void mac_hid_emumouse_disconnect(struct input_handle *handle) +{ + input_close_device(handle); + input_unregister_handle(handle); + kfree(handle); +} + +static const struct input_device_id mac_hid_emumouse_ids[] = { + { + .flags = INPUT_DEVICE_ID_MATCH_EVBIT, + .evbit = { BIT_MASK(EV_KEY) }, + }, + { }, +}; + +MODULE_DEVICE_TABLE(input, mac_hid_emumouse_ids); + +static struct input_handler mac_hid_emumouse_handler = { + .filter = mac_hid_emumouse_filter, + .connect = mac_hid_emumouse_connect, + .disconnect = mac_hid_emumouse_disconnect, + .name = "mac-button-emul", + .id_table = mac_hid_emumouse_ids, +}; + +static int mac_hid_start_emulation(void) +{ + int err; + + err = mac_hid_create_emumouse(); + if (err) + return err; + + err = input_register_handler(&mac_hid_emumouse_handler); + if (err) { + mac_hid_destroy_emumouse(); + return err; + } + + return 0; +} + +static void mac_hid_stop_emulation(void) +{ + input_unregister_handler(&mac_hid_emumouse_handler); + mac_hid_destroy_emumouse(); +} + +static int mac_hid_toggle_emumouse(ctl_table *table, int write, + void __user *buffer, size_t *lenp, + loff_t *ppos) +{ + int *valp = table->data; + int old_val = *valp; + int rc; + + rc = proc_dointvec(table, write, buffer, lenp, ppos); + + if (rc == 0 && write && *valp != old_val) { + if (*valp == 1) + rc = mac_hid_start_emulation(); + else if (*valp == 0) + mac_hid_stop_emulation(); + else + rc = -EINVAL; + } + + /* Restore the old value in case of error */ + if (rc) + *valp = old_val; + + return rc; +} + /* file(s) in /proc/sys/dev/mac_hid */ static ctl_table mac_hid_files[] = { { @@ -31,7 +209,7 @@ static ctl_table mac_hid_files[] = { .data = &mouse_emulate_buttons, .maxlen = sizeof(int), .mode = 0644, - .proc_handler = proc_dointvec, + .proc_handler = mac_hid_toggle_emumouse, }, { .procname = "mouse_button2_keycode", @@ -74,73 +252,12 @@ static ctl_table mac_hid_root_dir[] = { static struct ctl_table_header *mac_hid_sysctl_header; -#endif /* endif CONFIG_SYSCTL */ - -int mac_hid_mouse_emulate_buttons(int caller, unsigned int keycode, int down) -{ - switch (caller) { - case 1: - /* Called from keyboard.c */ - if (mouse_emulate_buttons - && (keycode == mouse_button2_keycode - || keycode == mouse_button3_keycode)) { - if (mouse_emulate_buttons == 1) { - input_report_key(emumousebtn, - keycode == mouse_button2_keycode ? BTN_MIDDLE : BTN_RIGHT, - down); - input_sync(emumousebtn); - return 1; - } - mouse_last_keycode = down ? keycode : 0; - } - break; - } - return 0; -} - -static struct lock_class_key emumousebtn_event_class; -static struct lock_class_key emumousebtn_mutex_class; - -static int emumousebtn_input_register(void) -{ - int ret; - - emumousebtn = input_allocate_device(); - if (!emumousebtn) - return -ENOMEM; - - lockdep_set_class(&emumousebtn->event_lock, &emumousebtn_event_class); - lockdep_set_class(&emumousebtn->mutex, &emumousebtn_mutex_class); - - emumousebtn->name = "Macintosh mouse button emulation"; - emumousebtn->id.bustype = BUS_ADB; - emumousebtn->id.vendor = 0x0001; - emumousebtn->id.product = 0x0001; - emumousebtn->id.version = 0x0100; - - emumousebtn->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL); - emumousebtn->keybit[BIT_WORD(BTN_MOUSE)] = BIT_MASK(BTN_LEFT) | - BIT_MASK(BTN_MIDDLE) | BIT_MASK(BTN_RIGHT); - emumousebtn->relbit[0] = BIT_MASK(REL_X) | BIT_MASK(REL_Y); - - ret = input_register_device(emumousebtn); - if (ret) - input_free_device(emumousebtn); - - return ret; -} static int __init mac_hid_init(void) { - int err; - - err = emumousebtn_input_register(); - if (err) - return err; - -#if defined(CONFIG_SYSCTL) mac_hid_sysctl_header = register_sysctl_table(mac_hid_root_dir); -#endif /* CONFIG_SYSCTL */ + if (!mac_hid_sysctl_header) + return -ENOMEM; return 0; } -- cgit v1.2.2 From 429722e19dff319aa87ee552beadee71d41a3655 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Sat, 30 Jan 2010 01:44:20 -0800 Subject: Input: Mac button emulation - allow compiling as a module Not all systems require Mac-style button emulation, however distributions enable it by default so it is readily available. Allow compiling it as a module so it can be loaded only on systems that actually require it. Signed-off-by: Dmitry Torokhov --- drivers/macintosh/Kconfig | 8 +++++--- drivers/macintosh/mac_hid.c | 13 +++++++++++-- 2 files changed, 16 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/macintosh/Kconfig b/drivers/macintosh/Kconfig index aa3c27e5255d..fd85bde283a0 100644 --- a/drivers/macintosh/Kconfig +++ b/drivers/macintosh/Kconfig @@ -171,9 +171,8 @@ config INPUT_ADBHID If unsure, say Y. config MAC_EMUMOUSEBTN - bool "Support for mouse button 2+3 emulation" - depends on SYSCTL - select INPUT + tristate "Support for mouse button 2+3 emulation" + depends on SYSCTL && INPUT help This provides generic support for emulating the 2nd and 3rd mouse button with keypresses. If you say Y here, the emulation is still @@ -185,6 +184,9 @@ config MAC_EMUMOUSEBTN If you have an Apple machine with a 1-button mouse, say Y here. + To compile this driver as a module, choose M here: the + module will be called mac_hid. + config THERM_WINDTUNNEL tristate "Support for thermal management on Windtunnel G4s" depends on I2C && I2C_POWERMAC && PPC_PMAC && !PPC_PMAC64 diff --git a/drivers/macintosh/mac_hid.c b/drivers/macintosh/mac_hid.c index 0b210a90aef5..e943d2a29253 100644 --- a/drivers/macintosh/mac_hid.c +++ b/drivers/macintosh/mac_hid.c @@ -14,6 +14,8 @@ #include #include +MODULE_LICENSE("GPL"); + static int mouse_emulate_buttons; static int mouse_button2_keycode = KEY_RIGHTCTRL; /* right control key */ static int mouse_button3_keycode = KEY_RIGHTALT; /* right option key */ @@ -252,7 +254,6 @@ static ctl_table mac_hid_root_dir[] = { static struct ctl_table_header *mac_hid_sysctl_header; - static int __init mac_hid_init(void) { mac_hid_sysctl_header = register_sysctl_table(mac_hid_root_dir); @@ -261,5 +262,13 @@ static int __init mac_hid_init(void) return 0; } +module_init(mac_hid_init); -device_initcall(mac_hid_init); +static void __exit mac_hid_exit(void) +{ + unregister_sysctl_table(mac_hid_sysctl_header); + + if (mouse_emulate_buttons) + mac_hid_stop_emulation(); +} +module_exit(mac_hid_exit); -- cgit v1.2.2 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') 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.2 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') 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.2 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') 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.2 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') 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.2 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') 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.2 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 +++++++++++++++----------------- 3 files changed, 37 insertions(+), 32 deletions(-) (limited to 'drivers') 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) -- cgit v1.2.2 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') 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.2 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') 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.2 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 +++++++++++++++++++++++++++++++++++-- 1 file changed, 307 insertions(+), 11 deletions(-) (limited to 'drivers') 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++) { -- cgit v1.2.2 From c72881e8377ca713427486add16fc63256f0231b Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Thu, 4 Feb 2010 12:50:13 +0100 Subject: ARM: 5914/1: Modify PL031 for Nomadik and U8500 v2 This extends the existing PrimeCell PL031 driver with support for the ST Microelectronics and ST-Ericsson derivatives, in a first and second version as used on the Nomadik and U8500 platforms. It also rids the old ioctl() alarm on/off functions in favor of the new .alarm_irq_enable field of the RTC class ops. Signed-off-by: Linus Walleij Signed-off-by: Russell King --- drivers/rtc/rtc-pl031.c | 365 +++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 327 insertions(+), 38 deletions(-) (limited to 'drivers') diff --git a/drivers/rtc/rtc-pl031.c b/drivers/rtc/rtc-pl031.c index 0264b117893b..c256aacfa954 100644 --- a/drivers/rtc/rtc-pl031.c +++ b/drivers/rtc/rtc-pl031.c @@ -7,6 +7,9 @@ * * Copyright 2006 (c) MontaVista Software, Inc. * + * Author: Mian Yousaf Kaukab + * Copyright 2010 (c) ST-Ericsson AB + * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version @@ -18,6 +21,9 @@ #include #include #include +#include +#include +#include /* * Register definitions @@ -30,35 +36,207 @@ #define RTC_RIS 0x14 /* Raw interrupt status register */ #define RTC_MIS 0x18 /* Masked interrupt status register */ #define RTC_ICR 0x1c /* Interrupt clear register */ +/* ST variants have additional timer functionality */ +#define RTC_TDR 0x20 /* Timer data read register */ +#define RTC_TLR 0x24 /* Timer data load register */ +#define RTC_TCR 0x28 /* Timer control register */ +#define RTC_YDR 0x30 /* Year data read register */ +#define RTC_YMR 0x34 /* Year match register */ +#define RTC_YLR 0x38 /* Year data load register */ + +#define RTC_CR_CWEN (1 << 26) /* Clockwatch enable bit */ + +#define RTC_TCR_EN (1 << 1) /* Periodic timer enable bit */ + +/* Common bit definitions for Interrupt status and control registers */ +#define RTC_BIT_AI (1 << 0) /* Alarm interrupt bit */ +#define RTC_BIT_PI (1 << 1) /* Periodic interrupt bit. ST variants only. */ + +/* Common bit definations for ST v2 for reading/writing time */ +#define RTC_SEC_SHIFT 0 +#define RTC_SEC_MASK (0x3F << RTC_SEC_SHIFT) /* Second [0-59] */ +#define RTC_MIN_SHIFT 6 +#define RTC_MIN_MASK (0x3F << RTC_MIN_SHIFT) /* Minute [0-59] */ +#define RTC_HOUR_SHIFT 12 +#define RTC_HOUR_MASK (0x1F << RTC_HOUR_SHIFT) /* Hour [0-23] */ +#define RTC_WDAY_SHIFT 17 +#define RTC_WDAY_MASK (0x7 << RTC_WDAY_SHIFT) /* Day of Week [1-7] 1=Sunday */ +#define RTC_MDAY_SHIFT 20 +#define RTC_MDAY_MASK (0x1F << RTC_MDAY_SHIFT) /* Day of Month [1-31] */ +#define RTC_MON_SHIFT 25 +#define RTC_MON_MASK (0xF << RTC_MON_SHIFT) /* Month [1-12] 1=January */ + +#define RTC_TIMER_FREQ 32768 struct pl031_local { struct rtc_device *rtc; void __iomem *base; + u8 hw_designer; + u8 hw_revision:4; }; -static irqreturn_t pl031_interrupt(int irq, void *dev_id) +static int pl031_alarm_irq_enable(struct device *dev, + unsigned int enabled) +{ + struct pl031_local *ldata = dev_get_drvdata(dev); + unsigned long imsc; + + /* Clear any pending alarm interrupts. */ + writel(RTC_BIT_AI, ldata->base + RTC_ICR); + + imsc = readl(ldata->base + RTC_IMSC); + + if (enabled == 1) + writel(imsc | RTC_BIT_AI, ldata->base + RTC_IMSC); + else + writel(imsc & ~RTC_BIT_AI, ldata->base + RTC_IMSC); + + return 0; +} + +/* + * Convert Gregorian date to ST v2 RTC format. + */ +static int pl031_stv2_tm_to_time(struct device *dev, + struct rtc_time *tm, unsigned long *st_time, + unsigned long *bcd_year) +{ + int year = tm->tm_year + 1900; + int wday = tm->tm_wday; + + /* wday masking is not working in hardware so wday must be valid */ + if (wday < -1 || wday > 6) { + dev_err(dev, "invalid wday value %d\n", tm->tm_wday); + return -EINVAL; + } else if (wday == -1) { + /* wday is not provided, calculate it here */ + unsigned long time; + struct rtc_time calc_tm; + + rtc_tm_to_time(tm, &time); + rtc_time_to_tm(time, &calc_tm); + wday = calc_tm.tm_wday; + } + + *bcd_year = (bin2bcd(year % 100) | bin2bcd(year / 100) << 8); + + *st_time = ((tm->tm_mon + 1) << RTC_MON_SHIFT) + | (tm->tm_mday << RTC_MDAY_SHIFT) + | ((wday + 1) << RTC_WDAY_SHIFT) + | (tm->tm_hour << RTC_HOUR_SHIFT) + | (tm->tm_min << RTC_MIN_SHIFT) + | (tm->tm_sec << RTC_SEC_SHIFT); + + return 0; +} + +/* + * Convert ST v2 RTC format to Gregorian date. + */ +static int pl031_stv2_time_to_tm(unsigned long st_time, unsigned long bcd_year, + struct rtc_time *tm) +{ + tm->tm_year = bcd2bin(bcd_year) + (bcd2bin(bcd_year >> 8) * 100); + tm->tm_mon = ((st_time & RTC_MON_MASK) >> RTC_MON_SHIFT) - 1; + tm->tm_mday = ((st_time & RTC_MDAY_MASK) >> RTC_MDAY_SHIFT); + tm->tm_wday = ((st_time & RTC_WDAY_MASK) >> RTC_WDAY_SHIFT) - 1; + tm->tm_hour = ((st_time & RTC_HOUR_MASK) >> RTC_HOUR_SHIFT); + tm->tm_min = ((st_time & RTC_MIN_MASK) >> RTC_MIN_SHIFT); + tm->tm_sec = ((st_time & RTC_SEC_MASK) >> RTC_SEC_SHIFT); + + tm->tm_yday = rtc_year_days(tm->tm_mday, tm->tm_mon, tm->tm_year); + tm->tm_year -= 1900; + + return 0; +} + +static int pl031_stv2_read_time(struct device *dev, struct rtc_time *tm) +{ + struct pl031_local *ldata = dev_get_drvdata(dev); + + pl031_stv2_time_to_tm(readl(ldata->base + RTC_DR), + readl(ldata->base + RTC_YDR), tm); + + return 0; +} + +static int pl031_stv2_set_time(struct device *dev, struct rtc_time *tm) +{ + unsigned long time; + unsigned long bcd_year; + struct pl031_local *ldata = dev_get_drvdata(dev); + int ret; + + ret = pl031_stv2_tm_to_time(dev, tm, &time, &bcd_year); + if (ret == 0) { + writel(bcd_year, ldata->base + RTC_YLR); + writel(time, ldata->base + RTC_LR); + } + + return ret; +} + +static int pl031_stv2_read_alarm(struct device *dev, struct rtc_wkalrm *alarm) { - struct rtc_device *rtc = dev_id; + struct pl031_local *ldata = dev_get_drvdata(dev); + int ret; - rtc_update_irq(rtc, 1, RTC_AF); + ret = pl031_stv2_time_to_tm(readl(ldata->base + RTC_MR), + readl(ldata->base + RTC_YMR), &alarm->time); - return IRQ_HANDLED; + alarm->pending = readl(ldata->base + RTC_RIS) & RTC_BIT_AI; + alarm->enabled = readl(ldata->base + RTC_IMSC) & RTC_BIT_AI; + + return ret; } -static int pl031_ioctl(struct device *dev, unsigned int cmd, unsigned long arg) +static int pl031_stv2_set_alarm(struct device *dev, struct rtc_wkalrm *alarm) { struct pl031_local *ldata = dev_get_drvdata(dev); + unsigned long time; + unsigned long bcd_year; + int ret; + + /* At the moment, we can only deal with non-wildcarded alarm times. */ + ret = rtc_valid_tm(&alarm->time); + if (ret == 0) { + ret = pl031_stv2_tm_to_time(dev, &alarm->time, + &time, &bcd_year); + if (ret == 0) { + writel(bcd_year, ldata->base + RTC_YMR); + writel(time, ldata->base + RTC_MR); + + pl031_alarm_irq_enable(dev, alarm->enabled); + } + } + + return ret; +} + +static irqreturn_t pl031_interrupt(int irq, void *dev_id) +{ + struct pl031_local *ldata = dev_id; + unsigned long rtcmis; + unsigned long events = 0; + + rtcmis = readl(ldata->base + RTC_MIS); + if (rtcmis) { + writel(rtcmis, ldata->base + RTC_ICR); + + if (rtcmis & RTC_BIT_AI) + events |= (RTC_AF | RTC_IRQF); + + /* Timer interrupt is only available in ST variants */ + if ((rtcmis & RTC_BIT_PI) && + (ldata->hw_designer == AMBA_VENDOR_ST)) + events |= (RTC_PF | RTC_IRQF); + + rtc_update_irq(ldata->rtc, 1, events); - switch (cmd) { - case RTC_AIE_OFF: - writel(1, ldata->base + RTC_MIS); - return 0; - case RTC_AIE_ON: - writel(0, ldata->base + RTC_MIS); - return 0; + return IRQ_HANDLED; } - return -ENOIOCTLCMD; + return IRQ_NONE; } static int pl031_read_time(struct device *dev, struct rtc_time *tm) @@ -74,11 +252,14 @@ static int pl031_set_time(struct device *dev, struct rtc_time *tm) { unsigned long time; struct pl031_local *ldata = dev_get_drvdata(dev); + int ret; - rtc_tm_to_time(tm, &time); - writel(time, ldata->base + RTC_LR); + ret = rtc_tm_to_time(tm, &time); - return 0; + if (ret == 0) + writel(time, ldata->base + RTC_LR); + + return ret; } static int pl031_read_alarm(struct device *dev, struct rtc_wkalrm *alarm) @@ -86,8 +267,9 @@ static int pl031_read_alarm(struct device *dev, struct rtc_wkalrm *alarm) struct pl031_local *ldata = dev_get_drvdata(dev); rtc_time_to_tm(readl(ldata->base + RTC_MR), &alarm->time); - alarm->pending = readl(ldata->base + RTC_RIS); - alarm->enabled = readl(ldata->base + RTC_IMSC); + + alarm->pending = readl(ldata->base + RTC_RIS) & RTC_BIT_AI; + alarm->enabled = readl(ldata->base + RTC_IMSC) & RTC_BIT_AI; return 0; } @@ -96,22 +278,71 @@ static int pl031_set_alarm(struct device *dev, struct rtc_wkalrm *alarm) { struct pl031_local *ldata = dev_get_drvdata(dev); unsigned long time; + int ret; + + /* At the moment, we can only deal with non-wildcarded alarm times. */ + ret = rtc_valid_tm(&alarm->time); + if (ret == 0) { + ret = rtc_tm_to_time(&alarm->time, &time); + if (ret == 0) { + writel(time, ldata->base + RTC_MR); + pl031_alarm_irq_enable(dev, alarm->enabled); + } + } + + return ret; +} + +/* Periodic interrupt is only available in ST variants. */ +static int pl031_irq_set_state(struct device *dev, int enabled) +{ + struct pl031_local *ldata = dev_get_drvdata(dev); + + if (enabled == 1) { + /* Clear any pending timer interrupt. */ + writel(RTC_BIT_PI, ldata->base + RTC_ICR); + + writel(readl(ldata->base + RTC_IMSC) | RTC_BIT_PI, + ldata->base + RTC_IMSC); - rtc_tm_to_time(&alarm->time, &time); + /* Now start the timer */ + writel(readl(ldata->base + RTC_TCR) | RTC_TCR_EN, + ldata->base + RTC_TCR); - writel(time, ldata->base + RTC_MR); - writel(!alarm->enabled, ldata->base + RTC_MIS); + } else { + writel(readl(ldata->base + RTC_IMSC) & (~RTC_BIT_PI), + ldata->base + RTC_IMSC); + + /* Also stop the timer */ + writel(readl(ldata->base + RTC_TCR) & (~RTC_TCR_EN), + ldata->base + RTC_TCR); + } + /* Wait at least 1 RTC32 clock cycle to ensure next access + * to RTC_TCR will succeed. + */ + udelay(40); return 0; } -static const struct rtc_class_ops pl031_ops = { - .ioctl = pl031_ioctl, - .read_time = pl031_read_time, - .set_time = pl031_set_time, - .read_alarm = pl031_read_alarm, - .set_alarm = pl031_set_alarm, -}; +static int pl031_irq_set_freq(struct device *dev, int freq) +{ + struct pl031_local *ldata = dev_get_drvdata(dev); + + /* Cant set timer if it is already enabled */ + if (readl(ldata->base + RTC_TCR) & RTC_TCR_EN) { + dev_err(dev, "can't change frequency while timer enabled\n"); + return -EINVAL; + } + + /* If self start bit in RTC_TCR is set timer will start here, + * but we never set that bit. Instead we start the timer when + * set_state is called with enabled == 1. + */ + writel(RTC_TIMER_FREQ / freq, ldata->base + RTC_TLR); + + return 0; +} static int pl031_remove(struct amba_device *adev) { @@ -131,18 +362,20 @@ static int pl031_probe(struct amba_device *adev, struct amba_id *id) { int ret; struct pl031_local *ldata; + struct rtc_class_ops *ops = id->data; ret = amba_request_regions(adev, NULL); if (ret) goto err_req; - ldata = kmalloc(sizeof(struct pl031_local), GFP_KERNEL); + ldata = kzalloc(sizeof(struct pl031_local), GFP_KERNEL); if (!ldata) { ret = -ENOMEM; goto out; } ldata->base = ioremap(adev->res.start, resource_size(&adev->res)); + if (!ldata->base) { ret = -ENOMEM; goto out_no_remap; @@ -150,24 +383,36 @@ static int pl031_probe(struct amba_device *adev, struct amba_id *id) amba_set_drvdata(adev, ldata); - if (request_irq(adev->irq[0], pl031_interrupt, IRQF_DISABLED, - "rtc-pl031", ldata->rtc)) { - ret = -EIO; - goto out_no_irq; - } + ldata->hw_designer = amba_manf(adev); + ldata->hw_revision = amba_rev(adev); + + dev_dbg(&adev->dev, "designer ID = 0x%02x\n", ldata->hw_designer); + dev_dbg(&adev->dev, "revision = 0x%01x\n", ldata->hw_revision); - ldata->rtc = rtc_device_register("pl031", &adev->dev, &pl031_ops, - THIS_MODULE); + /* Enable the clockwatch on ST Variants */ + if ((ldata->hw_designer == AMBA_VENDOR_ST) && + (ldata->hw_revision > 1)) + writel(readl(ldata->base + RTC_CR) | RTC_CR_CWEN, + ldata->base + RTC_CR); + + ldata->rtc = rtc_device_register("pl031", &adev->dev, ops, + THIS_MODULE); if (IS_ERR(ldata->rtc)) { ret = PTR_ERR(ldata->rtc); goto out_no_rtc; } + if (request_irq(adev->irq[0], pl031_interrupt, + IRQF_DISABLED | IRQF_SHARED, "rtc-pl031", ldata)) { + ret = -EIO; + goto out_no_irq; + } + return 0; -out_no_rtc: - free_irq(adev->irq[0], ldata->rtc); out_no_irq: + rtc_device_unregister(ldata->rtc); +out_no_rtc: iounmap(ldata->base); amba_set_drvdata(adev, NULL); out_no_remap: @@ -175,13 +420,57 @@ out_no_remap: out: amba_release_regions(adev); err_req: + return ret; } +/* Operations for the original ARM version */ +static struct rtc_class_ops arm_pl031_ops = { + .read_time = pl031_read_time, + .set_time = pl031_set_time, + .read_alarm = pl031_read_alarm, + .set_alarm = pl031_set_alarm, + .alarm_irq_enable = pl031_alarm_irq_enable, +}; + +/* The First ST derivative */ +static struct rtc_class_ops stv1_pl031_ops = { + .read_time = pl031_read_time, + .set_time = pl031_set_time, + .read_alarm = pl031_read_alarm, + .set_alarm = pl031_set_alarm, + .alarm_irq_enable = pl031_alarm_irq_enable, + .irq_set_state = pl031_irq_set_state, + .irq_set_freq = pl031_irq_set_freq, +}; + +/* And the second ST derivative */ +static struct rtc_class_ops stv2_pl031_ops = { + .read_time = pl031_stv2_read_time, + .set_time = pl031_stv2_set_time, + .read_alarm = pl031_stv2_read_alarm, + .set_alarm = pl031_stv2_set_alarm, + .alarm_irq_enable = pl031_alarm_irq_enable, + .irq_set_state = pl031_irq_set_state, + .irq_set_freq = pl031_irq_set_freq, +}; + static struct amba_id pl031_ids[] __initdata = { { .id = 0x00041031, .mask = 0x000fffff, + .data = &arm_pl031_ops, + }, + /* ST Micro variants */ + { + .id = 0x00180031, + .mask = 0x00ffffff, + .data = &stv1_pl031_ops, + }, + { + .id = 0x00280031, + .mask = 0x00ffffff, + .data = &stv2_pl031_ops, }, {0, 0}, }; -- cgit v1.2.2 From 8ee2bf9ab792d0c02b13ca3acbd036debb7745d9 Mon Sep 17 00:00:00 2001 From: Sriramakrishnan Date: Thu, 19 Nov 2009 15:58:25 +0530 Subject: TI Davinci EMAC : Re-use driver for other platforms. The davinci EMAC peripheral is also available on other TI platforms -notably TI AM3517 SoC. This patch modifies the config option and the platform structure header files so that the driver can be reused on non-davinci platforms as well. Signed-off-by: Sriramakrishnan Acked-by: Chaithrika U S Acked-by: David S. Miller Signed-off-by: Kevin Hilman --- drivers/net/Kconfig | 2 +- drivers/net/davinci_emac.c | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index dd9a09c72dff..18300625b05b 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -920,7 +920,7 @@ config NET_NETX config TI_DAVINCI_EMAC tristate "TI DaVinci EMAC Support" - depends on ARM && ARCH_DAVINCI + depends on ARM && ( ARCH_DAVINCI || ARCH_OMAP3 ) select PHYLIB help This driver supports TI's DaVinci Ethernet . diff --git a/drivers/net/davinci_emac.c b/drivers/net/davinci_emac.c index 33c4fe26178c..9ebac35d3af0 100644 --- a/drivers/net/davinci_emac.c +++ b/drivers/net/davinci_emac.c @@ -62,12 +62,11 @@ #include #include #include +#include #include #include -#include - static int debug_level; module_param(debug_level, int, 0); MODULE_PARM_DESC(debug_level, "DaVinci EMAC debug level (NETIF_MSG bits)"); -- cgit v1.2.2 From 01a9af36cd9d25fc71e28192974732d8053bd1c0 Mon Sep 17 00:00:00 2001 From: Sriramakrishnan Date: Thu, 19 Nov 2009 15:58:26 +0530 Subject: TI Davinci EMAC : add platform specific interrupt enable/disable logic. On certain SOCs, the EMAC controller is interfaced with a wrapper logic for handling interrupts. This patch implements a platform specific hook to cater to platforms that require custom interrupt handling logic Signed-off-by: Sriramakrishnan Acked-by: Chaithrika U S Acked-by: David S. Miller Signed-off-by: Kevin Hilman --- drivers/net/davinci_emac.c | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'drivers') diff --git a/drivers/net/davinci_emac.c b/drivers/net/davinci_emac.c index 9ebac35d3af0..c735b62baa03 100644 --- a/drivers/net/davinci_emac.c +++ b/drivers/net/davinci_emac.c @@ -487,6 +487,9 @@ struct emac_priv { struct mii_bus *mii_bus; struct phy_device *phydev; spinlock_t lock; + /*platform specific members*/ + void (*int_enable) (void); + void (*int_disable) (void); }; /* clock frequency for EMAC */ @@ -1001,6 +1004,8 @@ static void emac_int_disable(struct emac_priv *priv) emac_ctrl_write(EMAC_DM646X_CMRXINTEN, 0x0); emac_ctrl_write(EMAC_DM646X_CMTXINTEN, 0x0); /* NOTE: Rx Threshold and Misc interrupts are not disabled */ + if (priv->int_disable) + priv->int_disable(); local_irq_restore(flags); @@ -1020,6 +1025,9 @@ static void emac_int_disable(struct emac_priv *priv) static void emac_int_enable(struct emac_priv *priv) { if (priv->version == EMAC_VERSION_2) { + if (priv->int_enable) + priv->int_enable(); + emac_ctrl_write(EMAC_DM646X_CMRXINTEN, 0xff); emac_ctrl_write(EMAC_DM646X_CMTXINTEN, 0xff); @@ -2659,6 +2667,9 @@ static int __devinit davinci_emac_probe(struct platform_device *pdev) priv->phy_mask = pdata->phy_mask; priv->rmii_en = pdata->rmii_en; priv->version = pdata->version; + priv->int_enable = pdata->interrupt_enable; + priv->int_disable = pdata->interrupt_disable; + emac_dev = &ndev->dev; /* Get EMAC platform data */ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -- cgit v1.2.2 From ad021ae8862209864dc8ebd3b7d3a55ce84b9ea2 Mon Sep 17 00:00:00 2001 From: Sriramakrishnan Date: Thu, 19 Nov 2009 15:58:27 +0530 Subject: TI Davinci EMAC : Abstract Buffer address translation logic. When programming the DMA engine, the next pointers must be programmed with physical address as seen from the DMA master address space. This address may be different from physical address of the buffer RAM area. This patch abstracts the buffer address translation logic. Signed-off-by: Sriramakrishnan Acked-by: Chaithrika U S Acked-by: David S. Miller Signed-off-by: Kevin Hilman --- drivers/net/davinci_emac.c | 41 ++++++++++++++++++++++++----------------- 1 file changed, 24 insertions(+), 17 deletions(-) (limited to 'drivers') diff --git a/drivers/net/davinci_emac.c b/drivers/net/davinci_emac.c index c735b62baa03..1605bc225b0c 100644 --- a/drivers/net/davinci_emac.c +++ b/drivers/net/davinci_emac.c @@ -464,6 +464,7 @@ struct emac_priv { void __iomem *ctrl_base; void __iomem *emac_ctrl_ram; u32 ctrl_ram_size; + u32 hw_ram_addr; struct emac_txch *txch[EMAC_DEF_MAX_TX_CH]; struct emac_rxch *rxch[EMAC_DEF_MAX_RX_CH]; u32 link; /* 1=link on, 0=link off */ @@ -497,11 +498,9 @@ static struct clk *emac_clk; static unsigned long emac_bus_frequency; static unsigned long mdio_max_freq; -/* EMAC internal utility function */ -static inline u32 emac_virt_to_phys(void __iomem *addr) -{ - return (u32 __force) io_v2p(addr); -} +#define emac_virt_to_phys(addr, priv) \ + (((u32 __force)(addr) - (u32 __force)(priv->emac_ctrl_ram)) \ + + priv->hw_ram_addr) /* Cache macros - Packet buffers would be from skb pool which is cached */ #define EMAC_VIRT_NOCACHE(addr) (addr) @@ -1309,7 +1308,7 @@ static int emac_tx_bdproc(struct emac_priv *priv, u32 ch, u32 budget) curr_bd = txch->active_queue_head; if (NULL == curr_bd) { emac_write(EMAC_TXCP(ch), - emac_virt_to_phys(txch->last_hw_bdprocessed)); + emac_virt_to_phys(txch->last_hw_bdprocessed, priv)); txch->no_active_pkts++; spin_unlock_irqrestore(&priv->tx_lock, flags); return 0; @@ -1319,7 +1318,7 @@ static int emac_tx_bdproc(struct emac_priv *priv, u32 ch, u32 budget) while ((curr_bd) && ((frame_status & EMAC_CPPI_OWNERSHIP_BIT) == 0) && (pkts_processed < budget)) { - emac_write(EMAC_TXCP(ch), emac_virt_to_phys(curr_bd)); + emac_write(EMAC_TXCP(ch), emac_virt_to_phys(curr_bd, priv)); txch->active_queue_head = curr_bd->next; if (frame_status & EMAC_CPPI_EOQ_BIT) { if (curr_bd->next) { /* misqueued packet */ @@ -1406,7 +1405,7 @@ static int emac_send(struct emac_priv *priv, struct emac_netpktobj *pkt, u32 ch) txch->active_queue_tail = curr_bd; if (1 != txch->queue_active) { emac_write(EMAC_TXHDP(ch), - emac_virt_to_phys(curr_bd)); + emac_virt_to_phys(curr_bd, priv)); txch->queue_active = 1; } ++txch->queue_reinit; @@ -1418,10 +1417,11 @@ static int emac_send(struct emac_priv *priv, struct emac_netpktobj *pkt, u32 ch) tail_bd->next = curr_bd; txch->active_queue_tail = curr_bd; tail_bd = EMAC_VIRT_NOCACHE(tail_bd); - tail_bd->h_next = (int)emac_virt_to_phys(curr_bd); + tail_bd->h_next = (int)emac_virt_to_phys(curr_bd, priv); frame_status = tail_bd->mode; if (frame_status & EMAC_CPPI_EOQ_BIT) { - emac_write(EMAC_TXHDP(ch), emac_virt_to_phys(curr_bd)); + emac_write(EMAC_TXHDP(ch), + emac_virt_to_phys(curr_bd, priv)); frame_status &= ~(EMAC_CPPI_EOQ_BIT); tail_bd->mode = frame_status; ++txch->end_of_queue_add; @@ -1611,7 +1611,8 @@ static int emac_init_rxch(struct emac_priv *priv, u32 ch, char *param) } /* populate the hardware descriptor */ - curr_bd->h_next = emac_virt_to_phys(rxch->active_queue_head); + curr_bd->h_next = emac_virt_to_phys(rxch->active_queue_head, + priv); /* FIXME buff_ptr = dma_map_single(... data_ptr ...) */ curr_bd->buff_ptr = virt_to_phys(curr_bd->data_ptr); curr_bd->off_b_len = rxch->buf_size; @@ -1886,7 +1887,7 @@ static void emac_addbd_to_rx_queue(struct emac_priv *priv, u32 ch, rxch->active_queue_tail = curr_bd; if (0 != rxch->queue_active) { emac_write(EMAC_RXHDP(ch), - emac_virt_to_phys(rxch->active_queue_head)); + emac_virt_to_phys(rxch->active_queue_head, priv)); rxch->queue_active = 1; } } else { @@ -1897,11 +1898,11 @@ static void emac_addbd_to_rx_queue(struct emac_priv *priv, u32 ch, rxch->active_queue_tail = curr_bd; tail_bd->next = curr_bd; tail_bd = EMAC_VIRT_NOCACHE(tail_bd); - tail_bd->h_next = emac_virt_to_phys(curr_bd); + tail_bd->h_next = emac_virt_to_phys(curr_bd, priv); frame_status = tail_bd->mode; if (frame_status & EMAC_CPPI_EOQ_BIT) { emac_write(EMAC_RXHDP(ch), - emac_virt_to_phys(curr_bd)); + emac_virt_to_phys(curr_bd, priv)); frame_status &= ~(EMAC_CPPI_EOQ_BIT); tail_bd->mode = frame_status; ++rxch->end_of_queue_add; @@ -1994,7 +1995,7 @@ static int emac_rx_bdproc(struct emac_priv *priv, u32 ch, u32 budget) curr_pkt->num_bufs = 1; curr_pkt->pkt_length = (frame_status & EMAC_RX_BD_PKT_LENGTH_MASK); - emac_write(EMAC_RXCP(ch), emac_virt_to_phys(curr_bd)); + emac_write(EMAC_RXCP(ch), emac_virt_to_phys(curr_bd, priv)); ++rxch->processed_bd; last_bd = curr_bd; curr_bd = last_bd->next; @@ -2005,7 +2006,7 @@ static int emac_rx_bdproc(struct emac_priv *priv, u32 ch, u32 budget) if (curr_bd) { ++rxch->mis_queued_packets; emac_write(EMAC_RXHDP(ch), - emac_virt_to_phys(curr_bd)); + emac_virt_to_phys(curr_bd, priv)); } else { ++rxch->end_of_queue; rxch->queue_active = 0; @@ -2106,7 +2107,7 @@ static int emac_hw_enable(struct emac_priv *priv) emac_write(EMAC_RXINTMASKSET, BIT(ch)); rxch->queue_active = 1; emac_write(EMAC_RXHDP(ch), - emac_virt_to_phys(rxch->active_queue_head)); + emac_virt_to_phys(rxch->active_queue_head, priv)); } /* Enable MII */ @@ -2702,6 +2703,12 @@ static int __devinit davinci_emac_probe(struct platform_device *pdev) priv->ctrl_ram_size = pdata->ctrl_ram_size; priv->emac_ctrl_ram = priv->remap_addr + pdata->ctrl_ram_offset; + if (pdata->hw_ram_addr) + priv->hw_ram_addr = pdata->hw_ram_addr; + else + priv->hw_ram_addr = (u32 __force)res->start + + pdata->ctrl_ram_offset; + res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); if (!res) { dev_err(emac_dev, "DaVinci EMAC: Error getting irq res\n"); -- cgit v1.2.2 From c81628848af8a01f103acc8166299c698898a8f4 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Tue, 2 Feb 2010 14:41:40 -0800 Subject: clocksource: start CMT at clocksource resume Add code to start the CMT timer on clocksource resume. While at it handle the suspend case as well. Remove the platform device specific suspend calls. This makes sure the timer is started during sysdev_resume(). Without this patch the clocksource may be read as suspended, this after sysdev resume but before platform device resume. Signed-off-by: Magnus Damm Cc: john stultz Cc: Paul Mundt Signed-off-by: Andrew Morton Signed-off-by: Thomas Gleixner --- drivers/clocksource/sh_cmt.c | 35 +++++++---------------------------- 1 file changed, 7 insertions(+), 28 deletions(-) (limited to 'drivers') diff --git a/drivers/clocksource/sh_cmt.c b/drivers/clocksource/sh_cmt.c index 6b3e0c2f33e2..27efe08becbb 100644 --- a/drivers/clocksource/sh_cmt.c +++ b/drivers/clocksource/sh_cmt.c @@ -40,7 +40,6 @@ struct sh_cmt_priv { struct platform_device *pdev; unsigned long flags; - unsigned long flags_suspend; unsigned long match_value; unsigned long next_match_value; unsigned long max_match_value; @@ -432,6 +431,11 @@ static void sh_cmt_clocksource_disable(struct clocksource *cs) sh_cmt_stop(cs_to_sh_cmt(cs), FLAG_CLOCKSOURCE); } +static void sh_cmt_clocksource_resume(struct clocksource *cs) +{ + sh_cmt_start(cs_to_sh_cmt(cs), FLAG_CLOCKSOURCE); +} + static int sh_cmt_register_clocksource(struct sh_cmt_priv *p, char *name, unsigned long rating) { @@ -442,6 +446,8 @@ static int sh_cmt_register_clocksource(struct sh_cmt_priv *p, cs->read = sh_cmt_clocksource_read; cs->enable = sh_cmt_clocksource_enable; cs->disable = sh_cmt_clocksource_disable; + cs->suspend = sh_cmt_clocksource_disable; + cs->resume = sh_cmt_clocksource_resume; cs->mask = CLOCKSOURCE_MASK(sizeof(unsigned long) * 8); cs->flags = CLOCK_SOURCE_IS_CONTINUOUS; pr_info("sh_cmt: %s used as clock source\n", cs->name); @@ -668,38 +674,11 @@ static int __devexit sh_cmt_remove(struct platform_device *pdev) return -EBUSY; /* cannot unregister clockevent and clocksource */ } -static int sh_cmt_suspend(struct device *dev) -{ - struct platform_device *pdev = to_platform_device(dev); - struct sh_cmt_priv *p = platform_get_drvdata(pdev); - - /* save flag state and stop CMT channel */ - p->flags_suspend = p->flags; - sh_cmt_stop(p, p->flags); - return 0; -} - -static int sh_cmt_resume(struct device *dev) -{ - struct platform_device *pdev = to_platform_device(dev); - struct sh_cmt_priv *p = platform_get_drvdata(pdev); - - /* start CMT channel from saved state */ - sh_cmt_start(p, p->flags_suspend); - return 0; -} - -static struct dev_pm_ops sh_cmt_dev_pm_ops = { - .suspend = sh_cmt_suspend, - .resume = sh_cmt_resume, -}; - static struct platform_driver sh_cmt_device_driver = { .probe = sh_cmt_probe, .remove = __devexit_p(sh_cmt_remove), .driver = { .name = "sh_cmt", - .pm = &sh_cmt_dev_pm_ops, } }; -- cgit v1.2.2 From 1c64606968538396ffe87eb6da4121a5bffe5e34 Mon Sep 17 00:00:00 2001 From: Vaibhav Hiremath Date: Mon, 4 Jan 2010 15:34:15 +0100 Subject: OMAP: DSS2: Add Sharp LQ043T1DG01 panel driver Signed-off-by: Vaibhav Hiremath Signed-off-by: Tomi Valkeinen --- drivers/video/omap2/displays/Kconfig | 6 ++ drivers/video/omap2/displays/Makefile | 1 + .../video/omap2/displays/panel-sharp-lq043t1dg01.c | 120 +++++++++++++++++++++ 3 files changed, 127 insertions(+) create mode 100644 drivers/video/omap2/displays/panel-sharp-lq043t1dg01.c (limited to 'drivers') diff --git a/drivers/video/omap2/displays/Kconfig b/drivers/video/omap2/displays/Kconfig index b12a59c9c50a..4ce47ddffd3c 100644 --- a/drivers/video/omap2/displays/Kconfig +++ b/drivers/video/omap2/displays/Kconfig @@ -13,6 +13,12 @@ config PANEL_SHARP_LS037V7DW01 help LCD Panel used in TI's SDP3430 and EVM boards +config PANEL_SHARP_LQ043T1DG01 + tristate "Sharp LQ043T1DG01 LCD Panel" + depends on OMAP2_DSS + help + LCD Panel used in TI's OMAP3517 EVM boards + config PANEL_TAAL tristate "Taal DSI Panel" depends on OMAP2_DSS_DSI diff --git a/drivers/video/omap2/displays/Makefile b/drivers/video/omap2/displays/Makefile index 955646440b3a..8f3d0adc7612 100644 --- a/drivers/video/omap2/displays/Makefile +++ b/drivers/video/omap2/displays/Makefile @@ -1,4 +1,5 @@ obj-$(CONFIG_PANEL_GENERIC) += panel-generic.o obj-$(CONFIG_PANEL_SHARP_LS037V7DW01) += panel-sharp-ls037v7dw01.o +obj-$(CONFIG_PANEL_SHARP_LQ043T1DG01) += panel-sharp-lq043t1dg01.o obj-$(CONFIG_PANEL_TAAL) += panel-taal.o diff --git a/drivers/video/omap2/displays/panel-sharp-lq043t1dg01.c b/drivers/video/omap2/displays/panel-sharp-lq043t1dg01.c new file mode 100644 index 000000000000..e75798edbb59 --- /dev/null +++ b/drivers/video/omap2/displays/panel-sharp-lq043t1dg01.c @@ -0,0 +1,120 @@ +/* + * LCD panel driver for Sharp LQ043T1DG01 + * + * Copyright (C) 2009 Texas Instruments Inc + * Author: Vaibhav Hiremath + * + * 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, see . + */ + +#include +#include +#include +#include + +#include + +static struct omap_video_timings sharp_lq_timings = { + .x_res = 480, + .y_res = 272, + + .pixel_clock = 9000, + + .hsw = 42, + .hfp = 3, + .hbp = 2, + + .vsw = 11, + .vfp = 3, + .vbp = 2, +}; + +static int sharp_lq_panel_probe(struct omap_dss_device *dssdev) +{ + + dssdev->panel.config = OMAP_DSS_LCD_TFT | OMAP_DSS_LCD_IVS | + OMAP_DSS_LCD_IHS | OMAP_DSS_LCD_IEO; + dssdev->panel.acb = 0x0; + dssdev->panel.timings = sharp_lq_timings; + + return 0; +} + +static void sharp_lq_panel_remove(struct omap_dss_device *dssdev) +{ +} + +static int sharp_lq_panel_enable(struct omap_dss_device *dssdev) +{ + int r = 0; + + + /* wait couple of vsyncs until enabling the LCD */ + msleep(50); + + if (dssdev->platform_enable) + r = dssdev->platform_enable(dssdev); + + return r; +} + +static void sharp_lq_panel_disable(struct omap_dss_device *dssdev) +{ + + if (dssdev->platform_disable) + dssdev->platform_disable(dssdev); + + /* wait at least 5 vsyncs after disabling the LCD */ + + msleep(100); +} + +static int sharp_lq_panel_suspend(struct omap_dss_device *dssdev) +{ + sharp_lq_panel_disable(dssdev); + return 0; +} + +static int sharp_lq_panel_resume(struct omap_dss_device *dssdev) +{ + return sharp_lq_panel_enable(dssdev); +} + +static struct omap_dss_driver sharp_lq_driver = { + .probe = sharp_lq_panel_probe, + .remove = sharp_lq_panel_remove, + + .enable = sharp_lq_panel_enable, + .disable = sharp_lq_panel_disable, + .suspend = sharp_lq_panel_suspend, + .resume = sharp_lq_panel_resume, + + .driver = { + .name = "sharp_lq_panel", + .owner = THIS_MODULE, + }, +}; + +static int __init sharp_lq_panel_drv_init(void) +{ + return omap_dss_register_driver(&sharp_lq_driver); +} + +static void __exit sharp_lq_panel_drv_exit(void) +{ + omap_dss_unregister_driver(&sharp_lq_driver); +} + +module_init(sharp_lq_panel_drv_init); +module_exit(sharp_lq_panel_drv_exit); +MODULE_LICENSE("GPL"); -- cgit v1.2.2 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 --- drivers/input/input-compat.h | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers') 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.2 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 --- drivers/input/keyboard/Kconfig | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) (limited to 'drivers') 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.2 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 --- drivers/input/touchscreen/Kconfig | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers') 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.2 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') 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.2 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') 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.2 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 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') 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); -- cgit v1.2.2 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') 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.2 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') 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.2 From 751ef159c5600e7ee53e64c3d04f3e2d78908ce5 Mon Sep 17 00:00:00 2001 From: Mike Rapoport Date: Mon, 14 Dec 2009 09:01:07 +0100 Subject: OMAP: DSS2: add Toppoly TDO35S panel Signed-off-by: Mike Rapoport Signed-off-by: Tomi Valkeinen --- drivers/video/omap2/displays/Kconfig | 6 ++ drivers/video/omap2/displays/Makefile | 1 + .../video/omap2/displays/panel-toppoly-tdo35s.c | 112 +++++++++++++++++++++ 3 files changed, 119 insertions(+) create mode 100644 drivers/video/omap2/displays/panel-toppoly-tdo35s.c (limited to 'drivers') diff --git a/drivers/video/omap2/displays/Kconfig b/drivers/video/omap2/displays/Kconfig index 4ce47ddffd3c..4d95ed52886c 100644 --- a/drivers/video/omap2/displays/Kconfig +++ b/drivers/video/omap2/displays/Kconfig @@ -25,4 +25,10 @@ config PANEL_TAAL help Taal DSI command mode panel from TPO. +config PANEL_TOPPOLY_TDO35S + tristate "Toppoly TDO35S LCD Panel support" + depends on OMAP2_DSS + help + LCD Panel used in CM-T35 + endmenu diff --git a/drivers/video/omap2/displays/Makefile b/drivers/video/omap2/displays/Makefile index 8f3d0adc7612..e75cc70415ff 100644 --- a/drivers/video/omap2/displays/Makefile +++ b/drivers/video/omap2/displays/Makefile @@ -3,3 +3,4 @@ obj-$(CONFIG_PANEL_SHARP_LS037V7DW01) += panel-sharp-ls037v7dw01.o obj-$(CONFIG_PANEL_SHARP_LQ043T1DG01) += panel-sharp-lq043t1dg01.o obj-$(CONFIG_PANEL_TAAL) += panel-taal.o +obj-$(CONFIG_PANEL_TOPPOLY_TDO35S) += panel-toppoly-tdo35s.o \ No newline at end of file diff --git a/drivers/video/omap2/displays/panel-toppoly-tdo35s.c b/drivers/video/omap2/displays/panel-toppoly-tdo35s.c new file mode 100644 index 000000000000..e744b8c83817 --- /dev/null +++ b/drivers/video/omap2/displays/panel-toppoly-tdo35s.c @@ -0,0 +1,112 @@ +/* + * LCD panel driver for Toppoly TDO35S + * + * Copyright (C) 2009 CompuLab, Ltd. + * Author: Mike Rapoport + * + * Based on generic panel support + * Copyright (C) 2008 Nokia Corporation + * Author: Tomi Valkeinen + * + * 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, see . + */ + +#include +#include + +#include + +static struct omap_video_timings toppoly_tdo_panel_timings = { + /* 640 x 480 @ 60 Hz Reduced blanking VESA CVT 0.31M3-R */ + .x_res = 480, + .y_res = 640, + + .pixel_clock = 26000, + + .hfp = 104, + .hsw = 8, + .hbp = 8, + + .vfp = 4, + .vsw = 2, + .vbp = 2, +}; + +static int toppoly_tdo_panel_probe(struct omap_dss_device *dssdev) +{ + dssdev->panel.config = OMAP_DSS_LCD_TFT | OMAP_DSS_LCD_IVS | + OMAP_DSS_LCD_IHS; + dssdev->panel.timings = toppoly_tdo_panel_timings; + + return 0; +} + +static void toppoly_tdo_panel_remove(struct omap_dss_device *dssdev) +{ +} + +static int toppoly_tdo_panel_enable(struct omap_dss_device *dssdev) +{ + int r = 0; + + if (dssdev->platform_enable) + r = dssdev->platform_enable(dssdev); + + return r; +} + +static void toppoly_tdo_panel_disable(struct omap_dss_device *dssdev) +{ + if (dssdev->platform_disable) + dssdev->platform_disable(dssdev); +} + +static int toppoly_tdo_panel_suspend(struct omap_dss_device *dssdev) +{ + toppoly_tdo_panel_disable(dssdev); + return 0; +} + +static int toppoly_tdo_panel_resume(struct omap_dss_device *dssdev) +{ + return toppoly_tdo_panel_enable(dssdev); +} + +static struct omap_dss_driver generic_driver = { + .probe = toppoly_tdo_panel_probe, + .remove = toppoly_tdo_panel_remove, + + .enable = toppoly_tdo_panel_enable, + .disable = toppoly_tdo_panel_disable, + .suspend = toppoly_tdo_panel_suspend, + .resume = toppoly_tdo_panel_resume, + + .driver = { + .name = "toppoly_tdo35s_panel", + .owner = THIS_MODULE, + }, +}; + +static int __init toppoly_tdo_panel_drv_init(void) +{ + return omap_dss_register_driver(&generic_driver); +} + +static void __exit toppoly_tdo_panel_drv_exit(void) +{ + omap_dss_unregister_driver(&generic_driver); +} + +module_init(toppoly_tdo_panel_drv_init); +module_exit(toppoly_tdo_panel_drv_exit); +MODULE_LICENSE("GPL"); -- cgit v1.2.2 From 9ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59 Mon Sep 17 00:00:00 2001 From: Grazvydas Ignotas Date: Fri, 11 Dec 2009 21:30:14 +0200 Subject: OMAP: DSS: add TPO TD043MTEA1 panel Add support of TPO TD043MTEA1 TFT LCD panel to DSS2 driver. This panel is used by OMAP3 Pandora device. Signed-off-by: Grazvydas Ignotas Signed-off-by: Tomi Valkeinen --- drivers/video/omap2/displays/Kconfig | 6 + drivers/video/omap2/displays/Makefile | 3 +- .../video/omap2/displays/panel-tpo-td043mtea1.c | 489 +++++++++++++++++++++ 3 files changed, 497 insertions(+), 1 deletion(-) create mode 100644 drivers/video/omap2/displays/panel-tpo-td043mtea1.c (limited to 'drivers') diff --git a/drivers/video/omap2/displays/Kconfig b/drivers/video/omap2/displays/Kconfig index 4d95ed52886c..dfb57ee50861 100644 --- a/drivers/video/omap2/displays/Kconfig +++ b/drivers/video/omap2/displays/Kconfig @@ -31,4 +31,10 @@ config PANEL_TOPPOLY_TDO35S help LCD Panel used in CM-T35 +config PANEL_TPO_TD043MTEA1 + tristate "TPO TD043MTEA1 LCD Panel" + depends on OMAP2_DSS && I2C + help + LCD Panel used in OMAP3 Pandora + endmenu diff --git a/drivers/video/omap2/displays/Makefile b/drivers/video/omap2/displays/Makefile index e75cc70415ff..e2bb32168dee 100644 --- a/drivers/video/omap2/displays/Makefile +++ b/drivers/video/omap2/displays/Makefile @@ -3,4 +3,5 @@ obj-$(CONFIG_PANEL_SHARP_LS037V7DW01) += panel-sharp-ls037v7dw01.o obj-$(CONFIG_PANEL_SHARP_LQ043T1DG01) += panel-sharp-lq043t1dg01.o obj-$(CONFIG_PANEL_TAAL) += panel-taal.o -obj-$(CONFIG_PANEL_TOPPOLY_TDO35S) += panel-toppoly-tdo35s.o \ No newline at end of file +obj-$(CONFIG_PANEL_TOPPOLY_TDO35S) += panel-toppoly-tdo35s.o +obj-$(CONFIG_PANEL_TPO_TD043MTEA1) += panel-tpo-td043mtea1.o diff --git a/drivers/video/omap2/displays/panel-tpo-td043mtea1.c b/drivers/video/omap2/displays/panel-tpo-td043mtea1.c new file mode 100644 index 000000000000..f297a46f2b1a --- /dev/null +++ b/drivers/video/omap2/displays/panel-tpo-td043mtea1.c @@ -0,0 +1,489 @@ +/* + * LCD panel driver for TPO TD043MTEA1 + * + * Author: Gražvydas Ignotas + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#include +#include +#include +#include +#include +#include + +#include + +#define TPO_R02_MODE(x) ((x) & 7) +#define TPO_R02_MODE_800x480 7 +#define TPO_R02_NCLK_RISING BIT(3) +#define TPO_R02_HSYNC_HIGH BIT(4) +#define TPO_R02_VSYNC_HIGH BIT(5) + +#define TPO_R03_NSTANDBY BIT(0) +#define TPO_R03_EN_CP_CLK BIT(1) +#define TPO_R03_EN_VGL_PUMP BIT(2) +#define TPO_R03_EN_PWM BIT(3) +#define TPO_R03_DRIVING_CAP_100 BIT(4) +#define TPO_R03_EN_PRE_CHARGE BIT(6) +#define TPO_R03_SOFTWARE_CTL BIT(7) + +#define TPO_R04_NFLIP_H BIT(0) +#define TPO_R04_NFLIP_V BIT(1) +#define TPO_R04_CP_CLK_FREQ_1H BIT(2) +#define TPO_R04_VGL_FREQ_1H BIT(4) + +#define TPO_R03_VAL_NORMAL (TPO_R03_NSTANDBY | TPO_R03_EN_CP_CLK | \ + TPO_R03_EN_VGL_PUMP | TPO_R03_EN_PWM | \ + TPO_R03_DRIVING_CAP_100 | TPO_R03_EN_PRE_CHARGE | \ + TPO_R03_SOFTWARE_CTL) + +#define TPO_R03_VAL_STANDBY (TPO_R03_DRIVING_CAP_100 | \ + TPO_R03_EN_PRE_CHARGE | TPO_R03_SOFTWARE_CTL) + +static const u16 tpo_td043_def_gamma[12] = { + 106, 200, 289, 375, 460, 543, 625, 705, 785, 864, 942, 1020 +}; + +struct tpo_td043_device { + struct spi_device *spi; + struct regulator *vcc_reg; + u16 gamma[12]; + u32 mode; + u32 hmirror:1; + u32 vmirror:1; +}; + +static int tpo_td043_write(struct spi_device *spi, u8 addr, u8 data) +{ + struct spi_message m; + struct spi_transfer xfer; + u16 w; + int r; + + spi_message_init(&m); + + memset(&xfer, 0, sizeof(xfer)); + + w = ((u16)addr << 10) | (1 << 8) | data; + xfer.tx_buf = &w; + xfer.bits_per_word = 16; + xfer.len = 2; + spi_message_add_tail(&xfer, &m); + + r = spi_sync(spi, &m); + if (r < 0) + dev_warn(&spi->dev, "failed to write to LCD reg (%d)\n", r); + return r; +} + +static void tpo_td043_write_gamma(struct spi_device *spi, u16 gamma[12]) +{ + u8 i, val; + + /* gamma bits [9:8] */ + for (val = i = 0; i < 4; i++) + val |= (gamma[i] & 0x300) >> ((i + 1) * 2); + tpo_td043_write(spi, 0x11, val); + + for (val = i = 0; i < 4; i++) + val |= (gamma[i+4] & 0x300) >> ((i + 1) * 2); + tpo_td043_write(spi, 0x12, val); + + for (val = i = 0; i < 4; i++) + val |= (gamma[i+8] & 0x300) >> ((i + 1) * 2); + tpo_td043_write(spi, 0x13, val); + + /* gamma bits [7:0] */ + for (val = i = 0; i < 12; i++) + tpo_td043_write(spi, 0x14 + i, gamma[i] & 0xff); +} + +static int tpo_td043_write_mirror(struct spi_device *spi, bool h, bool v) +{ + u8 reg4 = TPO_R04_NFLIP_H | TPO_R04_NFLIP_V | \ + TPO_R04_CP_CLK_FREQ_1H | TPO_R04_VGL_FREQ_1H; + if (h) + reg4 &= ~TPO_R04_NFLIP_H; + if (v) + reg4 &= ~TPO_R04_NFLIP_V; + + return tpo_td043_write(spi, 4, reg4); +} + +static int tpo_td043_set_hmirror(struct omap_dss_device *dssdev, bool enable) +{ + struct tpo_td043_device *tpo_td043 = dev_get_drvdata(&dssdev->dev); + + tpo_td043->hmirror = enable; + return tpo_td043_write_mirror(tpo_td043->spi, tpo_td043->hmirror, + tpo_td043->vmirror); +} + +static bool tpo_td043_get_hmirror(struct omap_dss_device *dssdev) +{ + struct tpo_td043_device *tpo_td043 = dev_get_drvdata(&dssdev->dev); + + return tpo_td043->hmirror; +} + +static ssize_t tpo_td043_vmirror_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct tpo_td043_device *tpo_td043 = dev_get_drvdata(dev); + + return snprintf(buf, PAGE_SIZE, "%d\n", tpo_td043->vmirror); +} + +static ssize_t tpo_td043_vmirror_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + struct tpo_td043_device *tpo_td043 = dev_get_drvdata(dev); + long val; + int ret; + + ret = strict_strtol(buf, 0, &val); + if (ret < 0) + return ret; + + ret = tpo_td043_write_mirror(tpo_td043->spi, tpo_td043->hmirror, val); + if (ret < 0) + return ret; + + tpo_td043->vmirror = val; + + return count; +} + +static ssize_t tpo_td043_mode_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct tpo_td043_device *tpo_td043 = dev_get_drvdata(dev); + + return snprintf(buf, PAGE_SIZE, "%d\n", tpo_td043->mode); +} + +static ssize_t tpo_td043_mode_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + struct tpo_td043_device *tpo_td043 = dev_get_drvdata(dev); + long val; + int ret; + + ret = strict_strtol(buf, 0, &val); + if (ret != 0 || val & ~7) + return -EINVAL; + + tpo_td043->mode = val; + + val |= TPO_R02_NCLK_RISING; + tpo_td043_write(tpo_td043->spi, 2, val); + + return count; +} + +static ssize_t tpo_td043_gamma_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct tpo_td043_device *tpo_td043 = dev_get_drvdata(dev); + ssize_t len = 0; + int ret; + int i; + + for (i = 0; i < ARRAY_SIZE(tpo_td043->gamma); i++) { + ret = snprintf(buf + len, PAGE_SIZE - len, "%u ", + tpo_td043->gamma[i]); + if (ret < 0) + return ret; + len += ret; + } + buf[len - 1] = '\n'; + + return len; +} + +static ssize_t tpo_td043_gamma_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + struct tpo_td043_device *tpo_td043 = dev_get_drvdata(dev); + unsigned int g[12]; + int ret; + int i; + + ret = sscanf(buf, "%u %u %u %u %u %u %u %u %u %u %u %u", + &g[0], &g[1], &g[2], &g[3], &g[4], &g[5], + &g[6], &g[7], &g[8], &g[9], &g[10], &g[11]); + + if (ret != 12) + return -EINVAL; + + for (i = 0; i < 12; i++) + tpo_td043->gamma[i] = g[i]; + + tpo_td043_write_gamma(tpo_td043->spi, tpo_td043->gamma); + + return count; +} + +static DEVICE_ATTR(vmirror, S_IRUGO | S_IWUSR, + tpo_td043_vmirror_show, tpo_td043_vmirror_store); +static DEVICE_ATTR(mode, S_IRUGO | S_IWUSR, + tpo_td043_mode_show, tpo_td043_mode_store); +static DEVICE_ATTR(gamma, S_IRUGO | S_IWUSR, + tpo_td043_gamma_show, tpo_td043_gamma_store); + +static struct attribute *tpo_td043_attrs[] = { + &dev_attr_vmirror.attr, + &dev_attr_mode.attr, + &dev_attr_gamma.attr, + NULL, +}; + +static struct attribute_group tpo_td043_attr_group = { + .attrs = tpo_td043_attrs, +}; + +static const struct omap_video_timings tpo_td043_timings = { + .x_res = 800, + .y_res = 480, + + .pixel_clock = 36000, + + .hsw = 1, + .hfp = 68, + .hbp = 214, + + .vsw = 1, + .vfp = 39, + .vbp = 34, +}; + +static int tpo_td043_enable(struct omap_dss_device *dssdev) +{ + struct tpo_td043_device *tpo_td043 = dev_get_drvdata(&dssdev->dev); + int nreset_gpio = dssdev->reset_gpio; + int ret; + + dev_dbg(&dssdev->dev, "enable\n"); + + if (dssdev->platform_enable) { + ret = dssdev->platform_enable(dssdev); + if (ret) + return ret; + } + + regulator_enable(tpo_td043->vcc_reg); + + /* wait for power up */ + msleep(160); + + if (gpio_is_valid(nreset_gpio)) + gpio_set_value(nreset_gpio, 1); + + tpo_td043_write(tpo_td043->spi, 2, + TPO_R02_MODE(tpo_td043->mode) | TPO_R02_NCLK_RISING); + tpo_td043_write(tpo_td043->spi, 3, TPO_R03_VAL_NORMAL); + tpo_td043_write(tpo_td043->spi, 0x20, 0xf0); + tpo_td043_write(tpo_td043->spi, 0x21, 0xf0); + tpo_td043_write_mirror(tpo_td043->spi, tpo_td043->hmirror, + tpo_td043->vmirror); + tpo_td043_write_gamma(tpo_td043->spi, tpo_td043->gamma); + + return 0; +} + +static void tpo_td043_disable(struct omap_dss_device *dssdev) +{ + struct tpo_td043_device *tpo_td043 = dev_get_drvdata(&dssdev->dev); + int nreset_gpio = dssdev->reset_gpio; + + dev_dbg(&dssdev->dev, "disable\n"); + + tpo_td043_write(tpo_td043->spi, 3, + TPO_R03_VAL_STANDBY | TPO_R03_EN_PWM); + + if (gpio_is_valid(nreset_gpio)) + gpio_set_value(nreset_gpio, 0); + + /* wait for at least 2 vsyncs before cutting off power */ + msleep(50); + + tpo_td043_write(tpo_td043->spi, 3, TPO_R03_VAL_STANDBY); + + regulator_disable(tpo_td043->vcc_reg); + + if (dssdev->platform_disable) + dssdev->platform_disable(dssdev); +} + +static int tpo_td043_suspend(struct omap_dss_device *dssdev) +{ + tpo_td043_disable(dssdev); + return 0; +} + +static int tpo_td043_resume(struct omap_dss_device *dssdev) +{ + return tpo_td043_enable(dssdev); +} + +static int tpo_td043_probe(struct omap_dss_device *dssdev) +{ + struct tpo_td043_device *tpo_td043 = dev_get_drvdata(&dssdev->dev); + int nreset_gpio = dssdev->reset_gpio; + int ret = 0; + + dev_dbg(&dssdev->dev, "probe\n"); + + if (tpo_td043 == NULL) { + dev_err(&dssdev->dev, "missing tpo_td043_device\n"); + return -ENODEV; + } + + dssdev->panel.config = OMAP_DSS_LCD_TFT | OMAP_DSS_LCD_IHS | + OMAP_DSS_LCD_IVS | OMAP_DSS_LCD_IPC; + dssdev->panel.timings = tpo_td043_timings; + dssdev->ctrl.pixel_size = 24; + + tpo_td043->mode = TPO_R02_MODE_800x480; + memcpy(tpo_td043->gamma, tpo_td043_def_gamma, sizeof(tpo_td043->gamma)); + + tpo_td043->vcc_reg = regulator_get(&dssdev->dev, "vcc"); + if (IS_ERR(tpo_td043->vcc_reg)) { + dev_err(&dssdev->dev, "failed to get LCD VCC regulator\n"); + ret = PTR_ERR(tpo_td043->vcc_reg); + goto fail_regulator; + } + + if (gpio_is_valid(nreset_gpio)) { + ret = gpio_request(nreset_gpio, "lcd reset"); + if (ret < 0) { + dev_err(&dssdev->dev, "couldn't request reset GPIO\n"); + goto fail_gpio_req; + } + + ret = gpio_direction_output(nreset_gpio, 0); + if (ret < 0) { + dev_err(&dssdev->dev, "couldn't set GPIO direction\n"); + goto fail_gpio_direction; + } + } + + ret = sysfs_create_group(&dssdev->dev.kobj, &tpo_td043_attr_group); + if (ret) + dev_warn(&dssdev->dev, "failed to create sysfs files\n"); + + return 0; + +fail_gpio_direction: + gpio_free(nreset_gpio); +fail_gpio_req: + regulator_put(tpo_td043->vcc_reg); +fail_regulator: + kfree(tpo_td043); + return ret; +} + +static void tpo_td043_remove(struct omap_dss_device *dssdev) +{ + struct tpo_td043_device *tpo_td043 = dev_get_drvdata(&dssdev->dev); + int nreset_gpio = dssdev->reset_gpio; + + dev_dbg(&dssdev->dev, "remove\n"); + + sysfs_remove_group(&dssdev->dev.kobj, &tpo_td043_attr_group); + regulator_put(tpo_td043->vcc_reg); + if (gpio_is_valid(nreset_gpio)) + gpio_free(nreset_gpio); +} + +static struct omap_dss_driver tpo_td043_driver = { + .probe = tpo_td043_probe, + .remove = tpo_td043_remove, + + .enable = tpo_td043_enable, + .disable = tpo_td043_disable, + .suspend = tpo_td043_suspend, + .resume = tpo_td043_resume, + .set_mirror = tpo_td043_set_hmirror, + .get_mirror = tpo_td043_get_hmirror, + + .driver = { + .name = "tpo_td043mtea1_panel", + .owner = THIS_MODULE, + }, +}; + +static int tpo_td043_spi_probe(struct spi_device *spi) +{ + struct omap_dss_device *dssdev = spi->dev.platform_data; + struct tpo_td043_device *tpo_td043; + int ret; + + if (dssdev == NULL) { + dev_err(&spi->dev, "missing dssdev\n"); + return -ENODEV; + } + + spi->bits_per_word = 16; + spi->mode = SPI_MODE_0; + + ret = spi_setup(spi); + if (ret < 0) { + dev_err(&spi->dev, "spi_setup failed: %d\n", ret); + return ret; + } + + tpo_td043 = kzalloc(sizeof(*tpo_td043), GFP_KERNEL); + if (tpo_td043 == NULL) + return -ENOMEM; + + tpo_td043->spi = spi; + dev_set_drvdata(&spi->dev, tpo_td043); + dev_set_drvdata(&dssdev->dev, tpo_td043); + + omap_dss_register_driver(&tpo_td043_driver); + + return 0; +} + +static int __devexit tpo_td043_spi_remove(struct spi_device *spi) +{ + struct tpo_td043_device *tpo_td043 = dev_get_drvdata(&spi->dev); + + omap_dss_unregister_driver(&tpo_td043_driver); + kfree(tpo_td043); + + return 0; +} + +static struct spi_driver tpo_td043_spi_driver = { + .driver = { + .name = "tpo_td043mtea1_panel_spi", + .bus = &spi_bus_type, + .owner = THIS_MODULE, + }, + .probe = tpo_td043_spi_probe, + .remove = __devexit_p(tpo_td043_spi_remove), +}; + +static int __init tpo_td043_init(void) +{ + return spi_register_driver(&tpo_td043_spi_driver); +} + +static void __exit tpo_td043_exit(void) +{ + spi_unregister_driver(&tpo_td043_spi_driver); +} + +module_init(tpo_td043_init); +module_exit(tpo_td043_exit); + +MODULE_AUTHOR("Gražvydas Ignotas "); +MODULE_DESCRIPTION("TPO TD043MTEA1 LCD Driver"); +MODULE_LICENSE("GPL"); -- cgit v1.2.2 From 60596045ac3d73ab6aac85d1eca617ba4c97b020 Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Thu, 14 Jan 2010 15:12:47 +0200 Subject: OMAP: DSS2: Improve Kconfig help texts Signed-off-by: Tomi Valkeinen --- drivers/video/omap2/dss/Kconfig | 26 ++++++++++++++++++++++---- drivers/video/omap2/omapfb/Kconfig | 2 +- 2 files changed, 23 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/video/omap2/dss/Kconfig b/drivers/video/omap2/dss/Kconfig index c63ce767b277..87afb81b2c44 100644 --- a/drivers/video/omap2/dss/Kconfig +++ b/drivers/video/omap2/dss/Kconfig @@ -30,19 +30,29 @@ config OMAP2_DSS_COLLECT_IRQ_STATS depends on OMAP2_DSS_DEBUG_SUPPORT default n help - Collect DSS IRQ statistics, printable via debugfs + Collect DSS IRQ statistics, printable via debugfs. + + The statistics can be found from + /omapdss/dispc_irq for DISPC interrupts, and + /omapdss/dsi_irq for DSI interrupts. config OMAP2_DSS_RFBI bool "RFBI support" default n help - MIPI DBI, or RFBI (Remote Framebuffer Interface), support. + MIPI DBI support (RFBI, Remote Framebuffer Interface, in Texas + Instrument's terminology). + + DBI is a bus between the host processor and a peripheral, + such as a display or a framebuffer chip. + + See http://www.mipi.org/ for DBI spesifications. config OMAP2_DSS_VENC bool "VENC support" default y help - OMAP Video Encoder support. + OMAP Video Encoder support for S-Video and composite TV-out. config OMAP2_DSS_SDI bool "SDI support" @@ -51,12 +61,20 @@ config OMAP2_DSS_SDI help SDI (Serial Display Interface) support. + SDI is a high speed one-way display serial bus between the host + processor and a display. + config OMAP2_DSS_DSI bool "DSI support" depends on ARCH_OMAP3 default n help - MIPI DSI support. + MIPI DSI (Display Serial Interface) support. + + DSI is a high speed half-duplex serial interface between the host + processor and a peripheral, such as a display or a framebuffer chip. + + See http://www.mipi.org/ for DSI spesifications. config OMAP2_DSS_USE_DSI_PLL bool "Use DSI PLL for PCLK (EXPERIMENTAL)" diff --git a/drivers/video/omap2/omapfb/Kconfig b/drivers/video/omap2/omapfb/Kconfig index bb694cc52a50..5effa1d4d0e6 100644 --- a/drivers/video/omap2/omapfb/Kconfig +++ b/drivers/video/omap2/omapfb/Kconfig @@ -16,7 +16,7 @@ config FB_OMAP2_DEBUG_SUPPORT depends on FB_OMAP2 help Support for debug output. You have to enable the actual printing - with debug module parameter. + with 'debug' module parameter. config FB_OMAP2_FORCE_AUTO_UPDATE bool "Force main display to automatic update mode" -- cgit v1.2.2 From 3e9ff04408483b7972240cf433c7fb4b6b88cf0a Mon Sep 17 00:00:00 2001 From: Janusz Krzysztofik Date: Thu, 14 Jan 2010 21:25:43 +0100 Subject: omapfb: Fix 12-bit display (RGB444 color mode) handling Support for RGB444 (12-bit) pixel format has been introduced into omapfb/lcdc by Mark Underwood on 2006-05-26 (commit f74edb6668aad9fc8e81585861b18f996c78a574) in preparation for Amstrad Delta (E3) videophone LCD display support. Before the Amstrad Delta LCD patch by Jonathan McDowell was applied (on 2006-08-04, commit 8d22fb2ea004cdb6379b54c1a8fd1546cfe40ed7), omapfb and lcdc code was changed substantially (commit e563dc81aa01bd8bbb01bc53975a15c398715f62 dated 2006-06-26) in a way that broke Mark's 12-bit display support. Than, a patch by Jonathan, that supposed to correct the problem, was introduced immediatelly (on 2006-08-04, commit e10a75b49e7a57ae17c28b705153c70eba15a8ef). As a result, the Amstrad Delta display was working correctly at boot time, with fbset reporting: geometry 480 320 480 320 16 ... rgba 4/8,4/4,4/0,0/0 However, after first framebuffer reinitialization, colors were no longer being displayed correctly and fbset was reporting: rgba 5/11,6/5,5/0,0/0 The patch tries to correct the issue by setting plane->color_mode depending on panel->bpp, not var->bits_per_pixel. Created and tested on Amstrad Delta against linux-2.6.33-rc3. Signed-off-by: Janusz Krzysztofik Signed-off-by: Tomi Valkeinen --- drivers/video/omap/omapfb_main.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/video/omap/omapfb_main.c b/drivers/video/omap/omapfb_main.c index 2c4f470fa086..8ce60e1b220a 100644 --- a/drivers/video/omap/omapfb_main.c +++ b/drivers/video/omap/omapfb_main.c @@ -486,10 +486,11 @@ static int set_color_mode(struct omapfb_plane_struct *plane, return 0; case 12: var->bits_per_pixel = 16; - plane->color_mode = OMAPFB_COLOR_RGB444; - return 0; case 16: - plane->color_mode = OMAPFB_COLOR_RGB565; + if (plane->fbdev->panel->bpp == 12) + plane->color_mode = OMAPFB_COLOR_RGB444; + else + plane->color_mode = OMAPFB_COLOR_RGB565; return 0; default: return -EINVAL; -- cgit v1.2.2 From e721032785b72afbc3da14c5525ca570bc2ed108 Mon Sep 17 00:00:00 2001 From: Janusz Krzysztofik Date: Fri, 11 Dec 2009 13:21:46 +0000 Subject: omapfb: lcd_ams_delta: add support for contrast control The patch extends the Amstrad Delta LCD panel driver with optional support for changing contrast using standard LCD class device API instead of setting it silently to a default value at panel enable. It also allows for lowering power consumption by turning off OMAP_PWL_CLK_ENABLE via lcd_ops.set_power callback. Created and tested against linux-omap for-next, commit 155a75d9725e66e5ec8a383822957dee52427057. Signed-off-by: Janusz Krzysztofik Signed-off-by: Tomi Valkeinen --- drivers/video/omap/lcd_ams_delta.c | 93 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 89 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/video/omap/lcd_ams_delta.c b/drivers/video/omap/lcd_ams_delta.c index 567db6ac32c8..6978ae4ef83a 100644 --- a/drivers/video/omap/lcd_ams_delta.c +++ b/drivers/video/omap/lcd_ams_delta.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include @@ -32,6 +33,71 @@ #define AMS_DELTA_DEFAULT_CONTRAST 112 +#define AMS_DELTA_MAX_CONTRAST 0x00FF +#define AMS_DELTA_LCD_POWER 0x0100 + + +/* LCD class device section */ + +static int ams_delta_lcd; + +static int ams_delta_lcd_set_power(struct lcd_device *dev, int power) +{ + if (power == FB_BLANK_UNBLANK) { + if (!(ams_delta_lcd & AMS_DELTA_LCD_POWER)) { + omap_writeb(ams_delta_lcd & AMS_DELTA_MAX_CONTRAST, + OMAP_PWL_ENABLE); + omap_writeb(1, OMAP_PWL_CLK_ENABLE); + ams_delta_lcd |= AMS_DELTA_LCD_POWER; + } + } else { + if (ams_delta_lcd & AMS_DELTA_LCD_POWER) { + omap_writeb(0, OMAP_PWL_ENABLE); + omap_writeb(0, OMAP_PWL_CLK_ENABLE); + ams_delta_lcd &= ~AMS_DELTA_LCD_POWER; + } + } + return 0; +} + +static int ams_delta_lcd_set_contrast(struct lcd_device *dev, int value) +{ + if ((value >= 0) && (value <= AMS_DELTA_MAX_CONTRAST)) { + omap_writeb(value, OMAP_PWL_ENABLE); + ams_delta_lcd &= ~AMS_DELTA_MAX_CONTRAST; + ams_delta_lcd |= value; + } + return 0; +} + +#ifdef CONFIG_LCD_CLASS_DEVICE +static int ams_delta_lcd_get_power(struct lcd_device *dev) +{ + if (ams_delta_lcd & AMS_DELTA_LCD_POWER) + return FB_BLANK_UNBLANK; + else + return FB_BLANK_POWERDOWN; +} + +static int ams_delta_lcd_get_contrast(struct lcd_device *dev) +{ + if (!(ams_delta_lcd & AMS_DELTA_LCD_POWER)) + return 0; + + return ams_delta_lcd & AMS_DELTA_MAX_CONTRAST; +} + +static struct lcd_ops ams_delta_lcd_ops = { + .get_power = ams_delta_lcd_get_power, + .set_power = ams_delta_lcd_set_power, + .get_contrast = ams_delta_lcd_get_contrast, + .set_contrast = ams_delta_lcd_set_contrast, +}; +#endif + + +/* omapfb panel section */ + static int ams_delta_panel_init(struct lcd_panel *panel, struct omapfb_device *fbdev) { @@ -48,10 +114,6 @@ static int ams_delta_panel_enable(struct lcd_panel *panel) AMS_DELTA_LATCH2_LCD_NDISP); ams_delta_latch2_write(AMS_DELTA_LATCH2_LCD_VBLEN, AMS_DELTA_LATCH2_LCD_VBLEN); - - omap_writeb(1, OMAP_PWL_CLK_ENABLE); - omap_writeb(AMS_DELTA_DEFAULT_CONTRAST, OMAP_PWL_ENABLE); - return 0; } @@ -91,8 +153,31 @@ static struct lcd_panel ams_delta_panel = { .get_caps = ams_delta_panel_get_caps, }; + +/* platform driver section */ + static int ams_delta_panel_probe(struct platform_device *pdev) { + struct lcd_device *lcd_device = NULL; +#ifdef CONFIG_LCD_CLASS_DEVICE + int ret; + + lcd_device = lcd_device_register("omapfb", &pdev->dev, NULL, + &ams_delta_lcd_ops); + + if (IS_ERR(lcd_device)) { + ret = PTR_ERR(lcd_device); + dev_err(&pdev->dev, "failed to register device\n"); + return ret; + } + + platform_set_drvdata(pdev, lcd_device); + lcd_device->props.max_contrast = AMS_DELTA_MAX_CONTRAST; +#endif + + ams_delta_lcd_set_contrast(lcd_device, AMS_DELTA_DEFAULT_CONTRAST); + ams_delta_lcd_set_power(lcd_device, FB_BLANK_UNBLANK); + omapfb_register_panel(&ams_delta_panel); return 0; } -- cgit v1.2.2 From 8a2cfea8ccb6292dc43c37968fe08475ae7c2576 Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Thu, 4 Feb 2010 17:03:41 +0200 Subject: OMAP: DSS2: enable VDDS_DSI when using DPI It looks like on OMAP3 some DSS pins need VDDS_DSI to function properly. This has not been confirmed from TI, but looking at figure 15-1 "Display subsystem highlight" from the TRM, some data pins come near the DSI and SDI blocks. This is not very hard evidence, but the fact remains that with the power on, pixels are ok, and with the power off, pixels are not ok. It may also be that VDDS_SDI is needed to power some pins, but as normally both VDDS_SDI and VDDS_DSI come from the same power source, this hasn't been shown. It seems that a single driver can only get a regulator once. This patch solves it by getting all the required regulators in one place, and from which the submodules then get the regulators they need. Signed-off-by: Tomi Valkeinen --- drivers/video/omap2/dss/core.c | 66 +++++++++++++++++++++++++++++++++++++++++- drivers/video/omap2/dss/dpi.c | 55 +++++++++++++++++++++++++++++------ drivers/video/omap2/dss/dsi.c | 4 +-- drivers/video/omap2/dss/dss.h | 5 +++- drivers/video/omap2/dss/venc.c | 4 +-- 5 files changed, 117 insertions(+), 17 deletions(-) (limited to 'drivers') diff --git a/drivers/video/omap2/dss/core.c b/drivers/video/omap2/dss/core.c index 82918eec6d2e..791e1cb7c0bc 100644 --- a/drivers/video/omap2/dss/core.c +++ b/drivers/video/omap2/dss/core.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include @@ -47,6 +48,10 @@ static struct { struct clk *dss_54m_fck; struct clk *dss_96m_fck; unsigned num_clks_enabled; + + struct regulator *vdds_dsi_reg; + struct regulator *vdds_sdi_reg; + struct regulator *vdda_dac_reg; } core; static void dss_clk_enable_all_no_ctx(void); @@ -352,6 +357,50 @@ static void dss_clk_disable_all(void) dss_clk_disable(clks); } +/* REGULATORS */ + +struct regulator *dss_get_vdds_dsi(void) +{ + struct regulator *reg; + + if (core.vdds_dsi_reg != NULL) + return core.vdds_dsi_reg; + + reg = regulator_get(&core.pdev->dev, "vdds_dsi"); + if (!IS_ERR(reg)) + core.vdds_dsi_reg = reg; + + return reg; +} + +struct regulator *dss_get_vdds_sdi(void) +{ + struct regulator *reg; + + if (core.vdds_sdi_reg != NULL) + return core.vdds_sdi_reg; + + reg = regulator_get(&core.pdev->dev, "vdds_sdi"); + if (!IS_ERR(reg)) + core.vdds_sdi_reg = reg; + + return reg; +} + +struct regulator *dss_get_vdda_dac(void) +{ + struct regulator *reg; + + if (core.vdda_dac_reg != NULL) + return core.vdda_dac_reg; + + reg = regulator_get(&core.pdev->dev, "vdda_dac"); + if (!IS_ERR(reg)) + core.vdda_dac_reg = reg; + + return reg; +} + /* DEBUGFS */ #if defined(CONFIG_DEBUG_FS) && defined(CONFIG_OMAP2_DSS_DEBUG_SUPPORT) static void dss_debug_dump_clocks(struct seq_file *s) @@ -473,7 +522,7 @@ static int omap_dss_probe(struct platform_device *pdev) } #endif - r = dpi_init(); + r = dpi_init(pdev); if (r) { DSSERR("Failed to initialize dpi\n"); goto fail0; @@ -901,6 +950,21 @@ static int __init omap_dss_init(void) static void __exit omap_dss_exit(void) { + if (core.vdds_dsi_reg != NULL) { + regulator_put(core.vdds_dsi_reg); + core.vdds_dsi_reg = NULL; + } + + if (core.vdds_sdi_reg != NULL) { + regulator_put(core.vdds_sdi_reg); + core.vdds_sdi_reg = NULL; + } + + if (core.vdda_dac_reg != NULL) { + regulator_put(core.vdda_dac_reg); + core.vdda_dac_reg = NULL; + } + platform_driver_unregister(&omap_dss_driver); omap_dss_bus_unregister(); diff --git a/drivers/video/omap2/dss/dpi.c b/drivers/video/omap2/dss/dpi.c index 2d71031baa25..69ce31ae2a2f 100644 --- a/drivers/video/omap2/dss/dpi.c +++ b/drivers/video/omap2/dss/dpi.c @@ -25,7 +25,10 @@ #include #include #include +#include #include +#include +#include #include #include @@ -34,6 +37,7 @@ static struct { int update_enabled; + struct regulator *vdds_dsi_reg; } dpi; #ifdef CONFIG_OMAP2_DSS_USE_DSI_PLL @@ -166,21 +170,27 @@ static int dpi_display_enable(struct omap_dss_device *dssdev) goto err1; } + if (cpu_is_omap34xx()) { + r = regulator_enable(dpi.vdds_dsi_reg); + if (r) + goto err2; + } + dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1); r = dpi_basic_init(dssdev); if (r) - goto err2; + goto err3; #ifdef CONFIG_OMAP2_DSS_USE_DSI_PLL dss_clk_enable(DSS_CLK_FCK2); r = dsi_pll_init(dssdev, 0, 1); if (r) - goto err3; + goto err4; #endif r = dpi_set_mode(dssdev); if (r) - goto err4; + goto err5; mdelay(2); @@ -188,22 +198,25 @@ static int dpi_display_enable(struct omap_dss_device *dssdev) r = dssdev->driver->enable(dssdev); if (r) - goto err5; + goto err6; dssdev->state = OMAP_DSS_DISPLAY_ACTIVE; return 0; -err5: +err6: dispc_enable_lcd_out(0); -err4: +err5: #ifdef CONFIG_OMAP2_DSS_USE_DSI_PLL dsi_pll_uninit(); -err3: +err4: dss_clk_disable(DSS_CLK_FCK2); #endif -err2: +err3: dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1); +err2: + if (cpu_is_omap34xx()) + regulator_disable(dpi.vdds_dsi_reg); err1: omap_dss_stop_device(dssdev); err0: @@ -232,6 +245,9 @@ static void dpi_display_disable(struct omap_dss_device *dssdev) dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1); + if (cpu_is_omap34xx()) + regulator_disable(dpi.vdds_dsi_reg); + dssdev->state = OMAP_DSS_DISPLAY_DISABLED; omap_dss_stop_device(dssdev); @@ -251,6 +267,9 @@ static int dpi_display_suspend(struct omap_dss_device *dssdev) dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1); + if (cpu_is_omap34xx()) + regulator_disable(dpi.vdds_dsi_reg); + dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED; return 0; @@ -258,11 +277,19 @@ static int dpi_display_suspend(struct omap_dss_device *dssdev) static int dpi_display_resume(struct omap_dss_device *dssdev) { + int r; + if (dssdev->state != OMAP_DSS_DISPLAY_SUSPENDED) return -EINVAL; DSSDBG("dpi_display_resume\n"); + if (cpu_is_omap34xx()) { + r = regulator_enable(dpi.vdds_dsi_reg); + if (r) + goto err0; + } + dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1); dispc_enable_lcd_out(1); @@ -273,6 +300,8 @@ static int dpi_display_resume(struct omap_dss_device *dssdev) dssdev->state = OMAP_DSS_DISPLAY_ACTIVE; return 0; +err0: + return r; } static void dpi_set_timings(struct omap_dss_device *dssdev, @@ -388,8 +417,16 @@ int dpi_init_display(struct omap_dss_device *dssdev) return 0; } -int dpi_init(void) +int dpi_init(struct platform_device *pdev) { + if (cpu_is_omap34xx()) { + dpi.vdds_dsi_reg = dss_get_vdds_dsi(); + if (IS_ERR(dpi.vdds_dsi_reg)) { + DSSERR("can't get VDDS_DSI regulator\n"); + return PTR_ERR(dpi.vdds_dsi_reg); + } + } + return 0; } diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c index 6122178f5f85..036f4221e3df 100644 --- a/drivers/video/omap2/dss/dsi.c +++ b/drivers/video/omap2/dss/dsi.c @@ -3799,7 +3799,7 @@ int dsi_init(struct platform_device *pdev) goto err1; } - dsi.vdds_dsi_reg = regulator_get(&pdev->dev, "vdds_dsi"); + dsi.vdds_dsi_reg = dss_get_vdds_dsi(); if (IS_ERR(dsi.vdds_dsi_reg)) { iounmap(dsi.base); DSSERR("can't get VDDS_DSI regulator\n"); @@ -3830,8 +3830,6 @@ void dsi_exit(void) { kthread_stop(dsi.thread); - regulator_put(dsi.vdds_dsi_reg); - iounmap(dsi.base); DSSDBG("omap_dsi_exit\n"); diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h index 2bcb1245d6c2..41145af36353 100644 --- a/drivers/video/omap2/dss/dss.h +++ b/drivers/video/omap2/dss/dss.h @@ -169,6 +169,9 @@ unsigned long dss_clk_get_rate(enum dss_clock clk); int dss_need_ctx_restore(void); void dss_dump_clocks(struct seq_file *s); struct bus_type *dss_get_bus(void); +struct regulator *dss_get_vdds_dsi(void); +struct regulator *dss_get_vdds_sdi(void); +struct regulator *dss_get_vdda_dac(void); /* display */ int dss_suspend_all_devices(void); @@ -261,7 +264,7 @@ void dsi_get_overlay_fifo_thresholds(enum omap_plane plane, u32 *fifo_low, u32 *fifo_high); /* DPI */ -int dpi_init(void); +int dpi_init(struct platform_device *pdev); void dpi_exit(void); int dpi_init_display(struct omap_dss_device *dssdev); diff --git a/drivers/video/omap2/dss/venc.c b/drivers/video/omap2/dss/venc.c index 749a5a0f5be4..44b4998c2052 100644 --- a/drivers/video/omap2/dss/venc.c +++ b/drivers/video/omap2/dss/venc.c @@ -482,7 +482,7 @@ int venc_init(struct platform_device *pdev) return -ENOMEM; } - venc.vdda_dac_reg = regulator_get(&pdev->dev, "vdda_dac"); + venc.vdda_dac_reg = dss_get_vdda_dac(); if (IS_ERR(venc.vdda_dac_reg)) { iounmap(venc.base); DSSERR("can't get VDDA_DAC regulator\n"); @@ -503,8 +503,6 @@ void venc_exit(void) { omap_dss_unregister_driver(&venc_driver); - regulator_put(venc.vdda_dac_reg); - iounmap(venc.base); } -- cgit v1.2.2 From 80b1cc23ac96373bd5ff17f8959f2587d6fc37dd Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Thu, 4 Feb 2010 17:13:16 +0200 Subject: OMAP: 3430SDP: remove vdvi regulator The regulator is now enabled by DSS driver, and thus the panel driver doesn't need to touch it. Signed-off-by: Tomi Valkeinen --- .../video/omap2/displays/panel-sharp-ls037v7dw01.c | 35 ---------------------- 1 file changed, 35 deletions(-) (limited to 'drivers') diff --git a/drivers/video/omap2/displays/panel-sharp-ls037v7dw01.c b/drivers/video/omap2/displays/panel-sharp-ls037v7dw01.c index bbe880bbe795..e207d66908d6 100644 --- a/drivers/video/omap2/displays/panel-sharp-ls037v7dw01.c +++ b/drivers/video/omap2/displays/panel-sharp-ls037v7dw01.c @@ -25,14 +25,6 @@ #include -struct sharp_data { - /* XXX This regulator should actually be in SDP board file, not here, - * as it doesn't actually power the LCD, but something else that - * affects the output to LCD (I think. Somebody clarify). It doesn't do - * harm here, as SDP is the only board using this currently */ - struct regulator *vdvi_reg; -}; - static struct omap_video_timings sharp_ls_timings = { .x_res = 480, .y_res = 640, @@ -50,48 +42,25 @@ static struct omap_video_timings sharp_ls_timings = { static int sharp_ls_panel_probe(struct omap_dss_device *dssdev) { - struct sharp_data *sd; - dssdev->panel.config = OMAP_DSS_LCD_TFT | OMAP_DSS_LCD_IVS | OMAP_DSS_LCD_IHS; dssdev->panel.acb = 0x28; dssdev->panel.timings = sharp_ls_timings; - sd = kzalloc(sizeof(*sd), GFP_KERNEL); - if (!sd) - return -ENOMEM; - - dev_set_drvdata(&dssdev->dev, sd); - - sd->vdvi_reg = regulator_get(&dssdev->dev, "vdvi"); - if (IS_ERR(sd->vdvi_reg)) { - kfree(sd); - pr_err("failed to get VDVI regulator\n"); - return PTR_ERR(sd->vdvi_reg); - } - return 0; } static void sharp_ls_panel_remove(struct omap_dss_device *dssdev) { - struct sharp_data *sd = dev_get_drvdata(&dssdev->dev); - - regulator_put(sd->vdvi_reg); - - kfree(sd); } static int sharp_ls_panel_enable(struct omap_dss_device *dssdev) { - struct sharp_data *sd = dev_get_drvdata(&dssdev->dev); int r = 0; /* wait couple of vsyncs until enabling the LCD */ msleep(50); - regulator_enable(sd->vdvi_reg); - if (dssdev->platform_enable) r = dssdev->platform_enable(dssdev); @@ -100,13 +69,9 @@ static int sharp_ls_panel_enable(struct omap_dss_device *dssdev) static void sharp_ls_panel_disable(struct omap_dss_device *dssdev) { - struct sharp_data *sd = dev_get_drvdata(&dssdev->dev); - if (dssdev->platform_disable) dssdev->platform_disable(dssdev); - regulator_disable(sd->vdvi_reg); - /* wait at least 5 vsyncs after disabling the LCD */ msleep(100); -- cgit v1.2.2 From 92fe0ff16a9299233104187bd6ceb2101501badc Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Wed, 9 Dec 2009 17:26:25 +0100 Subject: OMAP: DSS: Taal: fix error returns in taal_probe() The workqueue creation error branch attempted to destroy a NULL wq, and, in turn, a failed registration does not destroy the newly created workqueue. The problem was reported by a static analysis tool. Signed-off-by: Aaro Koskinen Signed-off-by: Tomi Valkeinen --- drivers/video/omap2/displays/panel-taal.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/video/omap2/displays/panel-taal.c b/drivers/video/omap2/displays/panel-taal.c index 1f01dfc5e52e..0aaaa8a8e0f5 100644 --- a/drivers/video/omap2/displays/panel-taal.c +++ b/drivers/video/omap2/displays/panel-taal.c @@ -510,7 +510,7 @@ static int taal_probe(struct omap_dss_device *dssdev) if (td->esd_wq == NULL) { dev_err(&dssdev->dev, "can't create ESD workqueue\n"); r = -ENOMEM; - goto err2; + goto err1; } INIT_DELAYED_WORK_DEFERRABLE(&td->esd_work, taal_esd_work); @@ -528,7 +528,7 @@ static int taal_probe(struct omap_dss_device *dssdev) &taal_bl_ops); if (IS_ERR(bldev)) { r = PTR_ERR(bldev); - goto err1; + goto err2; } td->bldev = bldev; -- cgit v1.2.2 From 9bb787f435c86ffed079b66efa3ef6a8c577568c Mon Sep 17 00:00:00 2001 From: Russell King Date: Fri, 20 Nov 2009 13:07:28 +0000 Subject: ARM: PNX4008: convert watchdog clocks to match by device only Acked-by: Wim Van Sebroeck Acked-by: Vitaly Wool Signed-off-by: Russell King --- drivers/watchdog/pnx4008_wdt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/watchdog/pnx4008_wdt.c b/drivers/watchdog/pnx4008_wdt.c index 430a5848a9a5..8c5367fc4e50 100644 --- a/drivers/watchdog/pnx4008_wdt.c +++ b/drivers/watchdog/pnx4008_wdt.c @@ -273,7 +273,7 @@ static int __devinit pnx4008_wdt_probe(struct platform_device *pdev) } wdt_base = (void __iomem *)IO_ADDRESS(res->start); - wdt_clk = clk_get(&pdev->dev, "wdt_ck"); + wdt_clk = clk_get(&pdev->dev, NULL); if (IS_ERR(wdt_clk)) { ret = PTR_ERR(wdt_clk); release_resource(wdt_mem); -- cgit v1.2.2 From 24fd1edaac79fe9554c557f9f93b3197c136c236 Mon Sep 17 00:00:00 2001 From: Russell King Date: Fri, 20 Nov 2009 13:04:14 +0000 Subject: ARM: PNX4008: convert watchdog to use clk API enable/disable calls clk_set_rate() is not supposed to be used to turn clocks on and off. That's what clk_enable/clk_disable is for. Acked-by: Wim Van Sebroeck Acked-by: Vitaly Wool Signed-off-by: Russell King --- drivers/watchdog/pnx4008_wdt.c | 37 ++++++++++++++++++++++++------------- 1 file changed, 24 insertions(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/watchdog/pnx4008_wdt.c b/drivers/watchdog/pnx4008_wdt.c index 8c5367fc4e50..c7a9479934af 100644 --- a/drivers/watchdog/pnx4008_wdt.c +++ b/drivers/watchdog/pnx4008_wdt.c @@ -96,9 +96,6 @@ static void wdt_enable(void) { spin_lock(&io_lock); - if (wdt_clk) - clk_set_rate(wdt_clk, 1); - /* stop counter, initiate counter reset */ __raw_writel(RESET_COUNT, WDTIM_CTRL(wdt_base)); /*wait for reset to complete. 100% guarantee event */ @@ -125,19 +122,25 @@ static void wdt_disable(void) spin_lock(&io_lock); __raw_writel(0, WDTIM_CTRL(wdt_base)); /*stop counter */ - if (wdt_clk) - clk_set_rate(wdt_clk, 0); spin_unlock(&io_lock); } static int pnx4008_wdt_open(struct inode *inode, struct file *file) { + int ret; + if (test_and_set_bit(WDT_IN_USE, &wdt_status)) return -EBUSY; clear_bit(WDT_OK_TO_CLOSE, &wdt_status); + ret = clk_enable(wdt_clk); + if (ret) { + clear_bit(WDT_IN_USE, &wdt_status); + return ret; + } + wdt_enable(); return nonseekable_open(inode, file); @@ -225,6 +228,7 @@ static int pnx4008_wdt_release(struct inode *inode, struct file *file) printk(KERN_WARNING "WATCHDOG: Device closed unexpectdly\n"); wdt_disable(); + clk_disable(wdt_clk); clear_bit(WDT_IN_USE, &wdt_status); clear_bit(WDT_OK_TO_CLOSE, &wdt_status); @@ -279,19 +283,27 @@ static int __devinit pnx4008_wdt_probe(struct platform_device *pdev) release_resource(wdt_mem); kfree(wdt_mem); goto out; - } else - clk_set_rate(wdt_clk, 1); + } + + ret = clk_enable(wdt_clk); + if (ret) { + release_resource(wdt_mem); + kfree(wdt_mem); + goto out; + } ret = misc_register(&pnx4008_wdt_miscdev); if (ret < 0) { printk(KERN_ERR MODULE_NAME "cannot register misc device\n"); release_resource(wdt_mem); kfree(wdt_mem); - clk_set_rate(wdt_clk, 0); + clk_disable(wdt_clk); + clk_put(wdt_clk); } else { boot_status = (__raw_readl(WDTIM_RES(wdt_base)) & WDOG_RESET) ? WDIOF_CARDRESET : 0; wdt_disable(); /*disable for now */ + clk_disable(wdt_clk); set_bit(WDT_DEVICE_INITED, &wdt_status); } @@ -302,11 +314,10 @@ out: static int __devexit pnx4008_wdt_remove(struct platform_device *pdev) { misc_deregister(&pnx4008_wdt_miscdev); - if (wdt_clk) { - clk_set_rate(wdt_clk, 0); - clk_put(wdt_clk); - wdt_clk = NULL; - } + + clk_disable(wdt_clk); + clk_put(wdt_clk); + if (wdt_mem) { release_resource(wdt_mem); kfree(wdt_mem); -- cgit v1.2.2 From a0dcf19f59d4f37150a6b7e115925d72aca15293 Mon Sep 17 00:00:00 2001 From: Russell King Date: Fri, 20 Nov 2009 10:50:34 +0000 Subject: ARM: PNX4008: move i2c suspend/resume callbacks into driver Acked-by: Vitaly Wool Signed-off-by: Russell King --- drivers/i2c/busses/i2c-pnx.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/i2c/busses/i2c-pnx.c b/drivers/i2c/busses/i2c-pnx.c index 5d1c2603a130..bc8075514e53 100644 --- a/drivers/i2c/busses/i2c-pnx.c +++ b/drivers/i2c/busses/i2c-pnx.c @@ -545,18 +545,23 @@ static struct i2c_algorithm pnx_algorithm = { .functionality = i2c_pnx_func, }; +#ifdef CONFIG_PM static int i2c_pnx_controller_suspend(struct platform_device *pdev, pm_message_t state) { struct i2c_pnx_data *i2c_pnx = platform_get_drvdata(pdev); - return i2c_pnx->suspend(pdev, state); + return i2c_pnx->set_clock_run(pdev); } static int i2c_pnx_controller_resume(struct platform_device *pdev) { struct i2c_pnx_data *i2c_pnx = platform_get_drvdata(pdev); - return i2c_pnx->resume(pdev); + return i2c_pnx->set_clock_run(pdev); } +#else +#define i2c_pnx_controller_suspend NULL +#define i2c_pnx_controller_resume NULL +#endif static int __devinit i2c_pnx_probe(struct platform_device *pdev) { -- cgit v1.2.2 From 0321cb83e1c3f3a4282bd620c6cec78c5b80b572 Mon Sep 17 00:00:00 2001 From: Russell King Date: Fri, 20 Nov 2009 11:12:26 +0000 Subject: ARM: PNX4008: move i2c clock start/stop into driver Acked-by: Vitaly Wool Signed-off-by: Russell King --- drivers/i2c/busses/i2c-pnx.c | 39 ++++++++++++++++++++++++++++++--------- 1 file changed, 30 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/i2c/busses/i2c-pnx.c b/drivers/i2c/busses/i2c-pnx.c index bc8075514e53..98462671cdf7 100644 --- a/drivers/i2c/busses/i2c-pnx.c +++ b/drivers/i2c/busses/i2c-pnx.c @@ -20,6 +20,9 @@ #include #include #include +#include +#include + #include #include #include @@ -550,13 +553,22 @@ static int i2c_pnx_controller_suspend(struct platform_device *pdev, pm_message_t state) { struct i2c_pnx_data *i2c_pnx = platform_get_drvdata(pdev); - return i2c_pnx->set_clock_run(pdev); + struct i2c_pnx_algo_data *alg_data = i2c_pnx->adapter->algo_data; + + /* FIXME: disable clock? */ + clk_set_rate(alg_data->clk, 1); + + return 0; } static int i2c_pnx_controller_resume(struct platform_device *pdev) { struct i2c_pnx_data *i2c_pnx = platform_get_drvdata(pdev); - return i2c_pnx->set_clock_run(pdev); + struct i2c_pnx_algo_data *alg_data = i2c_pnx->adapter->algo_data; + + clk_set_rate(alg_data->clk, 1); + + return 0; } #else #define i2c_pnx_controller_suspend NULL @@ -580,6 +592,15 @@ static int __devinit i2c_pnx_probe(struct platform_device *pdev) platform_set_drvdata(pdev, i2c_pnx); + i2c_pnx->adapter->algo = &pnx_algorithm; + alg_data = i2c_pnx->adapter->algo_data; + + alg_data->clk = clk_get(&pdev->dev, NULL); + if (IS_ERR(alg_data->clk)) { + ret = PTR_ERR(alg_data->clk); + goto out_drvdata; + } + if (i2c_pnx->calculate_input_freq) freq_mhz = i2c_pnx->calculate_input_freq(pdev); else { @@ -588,9 +609,6 @@ static int __devinit i2c_pnx_probe(struct platform_device *pdev) "%d MHz\n", freq_mhz); } - i2c_pnx->adapter->algo = &pnx_algorithm; - - alg_data = i2c_pnx->adapter->algo_data; init_timer(&alg_data->mif.timer); alg_data->mif.timer.function = i2c_pnx_timeout; alg_data->mif.timer.data = (unsigned long)i2c_pnx->adapter; @@ -602,7 +620,7 @@ static int __devinit i2c_pnx_probe(struct platform_device *pdev) "I/O region 0x%08x for I2C already in use.\n", alg_data->base); ret = -ENODEV; - goto out_drvdata; + goto out_clkget; } if (!(alg_data->ioaddr = @@ -612,7 +630,7 @@ static int __devinit i2c_pnx_probe(struct platform_device *pdev) goto out_release; } - i2c_pnx->set_clock_run(pdev); + clk_set_rate(alg_data->clk, 1); /* * Clock Divisor High This value is the number of system clocks @@ -658,11 +676,13 @@ static int __devinit i2c_pnx_probe(struct platform_device *pdev) out_irq: free_irq(alg_data->irq, i2c_pnx->adapter); out_clock: - i2c_pnx->set_clock_stop(pdev); + clk_set_rate(alg_data->clk, 0); out_unmap: iounmap((void *)alg_data->ioaddr); out_release: release_mem_region(alg_data->base, I2C_PNX_REGION_SIZE); +out_clkget: + clk_put(alg_data->clk); out_drvdata: platform_set_drvdata(pdev, NULL); out: @@ -677,9 +697,10 @@ static int __devexit i2c_pnx_remove(struct platform_device *pdev) free_irq(alg_data->irq, i2c_pnx->adapter); i2c_del_adapter(adap); - i2c_pnx->set_clock_stop(pdev); + clk_set_rate(alg_data->clk, 0); iounmap((void *)alg_data->ioaddr); release_mem_region(alg_data->base, I2C_PNX_REGION_SIZE); + clk_put(alg_data->clk); platform_set_drvdata(pdev, NULL); return 0; -- cgit v1.2.2 From ebdbbf2003ae2342147c87c2a6c6ed8984b9cede Mon Sep 17 00:00:00 2001 From: Russell King Date: Fri, 20 Nov 2009 11:44:46 +0000 Subject: ARM: PNX4008: convert i2c-pnx to use clk API enable/disable calls clk_set_rate() is not supposed to be used to turn clocks on and off. That's what clk_enable/clk_disable is for. Acked-by: Vitaly Wool Signed-off-by: Russell King --- drivers/i2c/busses/i2c-pnx.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/i2c/busses/i2c-pnx.c b/drivers/i2c/busses/i2c-pnx.c index 98462671cdf7..29f91774c4df 100644 --- a/drivers/i2c/busses/i2c-pnx.c +++ b/drivers/i2c/busses/i2c-pnx.c @@ -555,8 +555,8 @@ static int i2c_pnx_controller_suspend(struct platform_device *pdev, struct i2c_pnx_data *i2c_pnx = platform_get_drvdata(pdev); struct i2c_pnx_algo_data *alg_data = i2c_pnx->adapter->algo_data; - /* FIXME: disable clock? */ - clk_set_rate(alg_data->clk, 1); + /* FIXME: shouldn't this be clk_disable? */ + clk_enable(alg_data->clk); return 0; } @@ -566,9 +566,7 @@ static int i2c_pnx_controller_resume(struct platform_device *pdev) struct i2c_pnx_data *i2c_pnx = platform_get_drvdata(pdev); struct i2c_pnx_algo_data *alg_data = i2c_pnx->adapter->algo_data; - clk_set_rate(alg_data->clk, 1); - - return 0; + return clk_enable(alg_data->clk); } #else #define i2c_pnx_controller_suspend NULL @@ -630,7 +628,9 @@ static int __devinit i2c_pnx_probe(struct platform_device *pdev) goto out_release; } - clk_set_rate(alg_data->clk, 1); + ret = clk_enable(alg_data->clk); + if (ret) + goto out_unmap; /* * Clock Divisor High This value is the number of system clocks @@ -650,7 +650,7 @@ static int __devinit i2c_pnx_probe(struct platform_device *pdev) iowrite32(mcntrl_reset, I2C_REG_CTL(alg_data)); if (wait_reset(I2C_PNX_TIMEOUT, alg_data)) { ret = -ENODEV; - goto out_unmap; + goto out_clock; } init_completion(&alg_data->mif.complete); @@ -676,7 +676,7 @@ static int __devinit i2c_pnx_probe(struct platform_device *pdev) out_irq: free_irq(alg_data->irq, i2c_pnx->adapter); out_clock: - clk_set_rate(alg_data->clk, 0); + clk_disable(alg_data->clk); out_unmap: iounmap((void *)alg_data->ioaddr); out_release: @@ -697,7 +697,7 @@ static int __devexit i2c_pnx_remove(struct platform_device *pdev) free_irq(alg_data->irq, i2c_pnx->adapter); i2c_del_adapter(adap); - clk_set_rate(alg_data->clk, 0); + clk_disable(alg_data->clk); iounmap((void *)alg_data->ioaddr); release_mem_region(alg_data->base, I2C_PNX_REGION_SIZE); clk_put(alg_data->clk); -- cgit v1.2.2 From 6fff3da998ac3cc9ed8a84bf4f19911bd63c8c32 Mon Sep 17 00:00:00 2001 From: Russell King Date: Fri, 20 Nov 2009 12:46:07 +0000 Subject: ARM: PNX4008: get i2c clock rate from clk API Acked-by: Vitaly Wool Signed-off-by: Russell King --- drivers/i2c/busses/i2c-pnx.c | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/i2c/busses/i2c-pnx.c b/drivers/i2c/busses/i2c-pnx.c index 29f91774c4df..bfcd079e885c 100644 --- a/drivers/i2c/busses/i2c-pnx.c +++ b/drivers/i2c/busses/i2c-pnx.c @@ -31,7 +31,6 @@ #define I2C_PNX_TIMEOUT 10 /* msec */ #define I2C_PNX_SPEED_KHZ 100 #define I2C_PNX_REGION_SIZE 0x100 -#define PNX_DEFAULT_FREQ 13 /* MHz */ static inline int wait_timeout(long timeout, struct i2c_pnx_algo_data *data) { @@ -578,7 +577,7 @@ static int __devinit i2c_pnx_probe(struct platform_device *pdev) unsigned long tmp; int ret = 0; struct i2c_pnx_algo_data *alg_data; - int freq_mhz; + unsigned long freq; struct i2c_pnx_data *i2c_pnx = pdev->dev.platform_data; if (!i2c_pnx || !i2c_pnx->adapter) { @@ -599,14 +598,6 @@ static int __devinit i2c_pnx_probe(struct platform_device *pdev) goto out_drvdata; } - if (i2c_pnx->calculate_input_freq) - freq_mhz = i2c_pnx->calculate_input_freq(pdev); - else { - freq_mhz = PNX_DEFAULT_FREQ; - dev_info(&pdev->dev, "Setting bus frequency to default value: " - "%d MHz\n", freq_mhz); - } - init_timer(&alg_data->mif.timer); alg_data->mif.timer.function = i2c_pnx_timeout; alg_data->mif.timer.data = (unsigned long)i2c_pnx->adapter; @@ -632,6 +623,8 @@ static int __devinit i2c_pnx_probe(struct platform_device *pdev) if (ret) goto out_unmap; + freq = clk_get_rate(alg_data->clk); + /* * Clock Divisor High This value is the number of system clocks * the serial clock (SCL) will be high. @@ -643,7 +636,7 @@ static int __devinit i2c_pnx_probe(struct platform_device *pdev) * the deglitching filter length. */ - tmp = ((freq_mhz * 1000) / I2C_PNX_SPEED_KHZ) / 2 - 2; + tmp = ((freq / 1000) / I2C_PNX_SPEED_KHZ) / 2 - 2; iowrite32(tmp, I2C_REG_CKH(alg_data)); iowrite32(tmp, I2C_REG_CKL(alg_data)); -- cgit v1.2.2 From 88d968b22fa26d5e3a8cab46fc7c3a21c89a91d3 Mon Sep 17 00:00:00 2001 From: Russell King Date: Sat, 21 Nov 2009 11:58:36 +0000 Subject: ARM: PNX4008: Make ioaddr 'void __iomem *' rather than 'u32' This avoids unnecessary casting. Signed-off-by: Russell King --- drivers/i2c/busses/i2c-pnx.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/i2c/busses/i2c-pnx.c b/drivers/i2c/busses/i2c-pnx.c index bfcd079e885c..882579e64111 100644 --- a/drivers/i2c/busses/i2c-pnx.c +++ b/drivers/i2c/busses/i2c-pnx.c @@ -612,8 +612,8 @@ static int __devinit i2c_pnx_probe(struct platform_device *pdev) goto out_clkget; } - if (!(alg_data->ioaddr = - (u32)ioremap(alg_data->base, I2C_PNX_REGION_SIZE))) { + alg_data->ioaddr = ioremap(alg_data->base, I2C_PNX_REGION_SIZE); + if (!alg_data->ioaddr) { dev_err(&pdev->dev, "Couldn't ioremap I2C I/O region\n"); ret = -ENOMEM; goto out_release; @@ -671,7 +671,7 @@ out_irq: out_clock: clk_disable(alg_data->clk); out_unmap: - iounmap((void *)alg_data->ioaddr); + iounmap(alg_data->ioaddr); out_release: release_mem_region(alg_data->base, I2C_PNX_REGION_SIZE); out_clkget: @@ -691,7 +691,7 @@ static int __devexit i2c_pnx_remove(struct platform_device *pdev) free_irq(alg_data->irq, i2c_pnx->adapter); i2c_del_adapter(adap); clk_disable(alg_data->clk); - iounmap((void *)alg_data->ioaddr); + iounmap(alg_data->ioaddr); release_mem_region(alg_data->base, I2C_PNX_REGION_SIZE); clk_put(alg_data->clk); platform_set_drvdata(pdev, NULL); -- cgit v1.2.2 From 44c5d739181886cff8e3903dfa38cd704f3d9640 Mon Sep 17 00:00:00 2001 From: Russell King Date: Sat, 21 Nov 2009 12:10:54 +0000 Subject: ARM: PNX4008: kzalloc i2c drivers internal data Signed-off-by: Russell King --- drivers/i2c/busses/i2c-pnx.c | 29 +++++++++++++++++++---------- 1 file changed, 19 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/i2c/busses/i2c-pnx.c b/drivers/i2c/busses/i2c-pnx.c index 882579e64111..1d66856a22fd 100644 --- a/drivers/i2c/busses/i2c-pnx.c +++ b/drivers/i2c/busses/i2c-pnx.c @@ -587,10 +587,16 @@ static int __devinit i2c_pnx_probe(struct platform_device *pdev) goto out; } + alg_data = kzalloc(sizeof(*alg_data), GFP_KERNEL); + if (!alg_data) { + ret = -ENOMEM; + goto err_kzalloc; + } + platform_set_drvdata(pdev, i2c_pnx); i2c_pnx->adapter->algo = &pnx_algorithm; - alg_data = i2c_pnx->adapter->algo_data; + i2c_pnx->adapter->algo_data = alg_data; alg_data->clk = clk_get(&pdev->dev, NULL); if (IS_ERR(alg_data->clk)) { @@ -603,16 +609,16 @@ static int __devinit i2c_pnx_probe(struct platform_device *pdev) alg_data->mif.timer.data = (unsigned long)i2c_pnx->adapter; /* Register I/O resource */ - if (!request_mem_region(alg_data->base, I2C_PNX_REGION_SIZE, + if (!request_mem_region(i2c_pnx->base, I2C_PNX_REGION_SIZE, pdev->name)) { dev_err(&pdev->dev, "I/O region 0x%08x for I2C already in use.\n", - alg_data->base); + i2c_pnx->base); ret = -ENODEV; goto out_clkget; } - alg_data->ioaddr = ioremap(alg_data->base, I2C_PNX_REGION_SIZE); + alg_data->ioaddr = ioremap(i2c_pnx->base, I2C_PNX_REGION_SIZE); if (!alg_data->ioaddr) { dev_err(&pdev->dev, "Couldn't ioremap I2C I/O region\n"); ret = -ENOMEM; @@ -647,7 +653,7 @@ static int __devinit i2c_pnx_probe(struct platform_device *pdev) } init_completion(&alg_data->mif.complete); - ret = request_irq(alg_data->irq, i2c_pnx_interrupt, + ret = request_irq(i2c_pnx->irq, i2c_pnx_interrupt, 0, pdev->name, i2c_pnx->adapter); if (ret) goto out_clock; @@ -662,21 +668,23 @@ static int __devinit i2c_pnx_probe(struct platform_device *pdev) } dev_dbg(&pdev->dev, "%s: Master at %#8x, irq %d.\n", - i2c_pnx->adapter->name, alg_data->base, alg_data->irq); + i2c_pnx->adapter->name, i2c_pnx->base, i2c_pnx->irq); return 0; out_irq: - free_irq(alg_data->irq, i2c_pnx->adapter); + free_irq(i2c_pnx->irq, i2c_pnx->adapter); out_clock: clk_disable(alg_data->clk); out_unmap: iounmap(alg_data->ioaddr); out_release: - release_mem_region(alg_data->base, I2C_PNX_REGION_SIZE); + release_mem_region(i2c_pnx->base, I2C_PNX_REGION_SIZE); out_clkget: clk_put(alg_data->clk); out_drvdata: + kfree(alg_data); +err_kzalloc: platform_set_drvdata(pdev, NULL); out: return ret; @@ -688,12 +696,13 @@ static int __devexit i2c_pnx_remove(struct platform_device *pdev) struct i2c_adapter *adap = i2c_pnx->adapter; struct i2c_pnx_algo_data *alg_data = adap->algo_data; - free_irq(alg_data->irq, i2c_pnx->adapter); + free_irq(i2c_pnx->irq, i2c_pnx->adapter); i2c_del_adapter(adap); clk_disable(alg_data->clk); iounmap(alg_data->ioaddr); - release_mem_region(alg_data->base, I2C_PNX_REGION_SIZE); + release_mem_region(i2c_pnx->base, I2C_PNX_REGION_SIZE); clk_put(alg_data->clk); + kfree(alg_data); platform_set_drvdata(pdev, NULL); return 0; -- cgit v1.2.2 From 9d7f73632c87ef1b6187eb539d1efd63c3cf0e36 Mon Sep 17 00:00:00 2001 From: Russell King Date: Sat, 21 Nov 2009 12:25:27 +0000 Subject: ARM: PNX4008: move i2c_adapter structure inside the drivers private data Signed-off-by: Russell King --- drivers/i2c/busses/i2c-pnx.c | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) (limited to 'drivers') diff --git a/drivers/i2c/busses/i2c-pnx.c b/drivers/i2c/busses/i2c-pnx.c index 1d66856a22fd..6b413c5300d3 100644 --- a/drivers/i2c/busses/i2c-pnx.c +++ b/drivers/i2c/busses/i2c-pnx.c @@ -551,8 +551,7 @@ static struct i2c_algorithm pnx_algorithm = { static int i2c_pnx_controller_suspend(struct platform_device *pdev, pm_message_t state) { - struct i2c_pnx_data *i2c_pnx = platform_get_drvdata(pdev); - struct i2c_pnx_algo_data *alg_data = i2c_pnx->adapter->algo_data; + struct i2c_pnx_algo_data *alg_data = platform_get_drvdata(pdev); /* FIXME: shouldn't this be clk_disable? */ clk_enable(alg_data->clk); @@ -562,8 +561,7 @@ static int i2c_pnx_controller_suspend(struct platform_device *pdev, static int i2c_pnx_controller_resume(struct platform_device *pdev) { - struct i2c_pnx_data *i2c_pnx = platform_get_drvdata(pdev); - struct i2c_pnx_algo_data *alg_data = i2c_pnx->adapter->algo_data; + struct i2c_pnx_algo_data *alg_data = platform_get_drvdata(pdev); return clk_enable(alg_data->clk); } @@ -580,7 +578,7 @@ static int __devinit i2c_pnx_probe(struct platform_device *pdev) unsigned long freq; struct i2c_pnx_data *i2c_pnx = pdev->dev.platform_data; - if (!i2c_pnx || !i2c_pnx->adapter) { + if (!i2c_pnx || !i2c_pnx->name) { dev_err(&pdev->dev, "%s: no platform data supplied\n", __func__); ret = -EINVAL; @@ -593,10 +591,15 @@ static int __devinit i2c_pnx_probe(struct platform_device *pdev) goto err_kzalloc; } - platform_set_drvdata(pdev, i2c_pnx); + platform_set_drvdata(pdev, alg_data); - i2c_pnx->adapter->algo = &pnx_algorithm; - i2c_pnx->adapter->algo_data = alg_data; + strlcpy(alg_data->adapter.name, i2c_pnx->name, + sizeof(alg_data->adapter.name)); + alg_data->adapter.dev.parent = &pdev->dev; + alg_data->adapter.algo = &pnx_algorithm; + alg_data->adapter.algo_data = alg_data; + alg_data->adapter.nr = pdev->id; + alg_data->i2c_pnx = i2c_pnx; alg_data->clk = clk_get(&pdev->dev, NULL); if (IS_ERR(alg_data->clk)) { @@ -606,7 +609,7 @@ static int __devinit i2c_pnx_probe(struct platform_device *pdev) init_timer(&alg_data->mif.timer); alg_data->mif.timer.function = i2c_pnx_timeout; - alg_data->mif.timer.data = (unsigned long)i2c_pnx->adapter; + alg_data->mif.timer.data = (unsigned long)&alg_data->adapter; /* Register I/O resource */ if (!request_mem_region(i2c_pnx->base, I2C_PNX_REGION_SIZE, @@ -654,26 +657,24 @@ static int __devinit i2c_pnx_probe(struct platform_device *pdev) init_completion(&alg_data->mif.complete); ret = request_irq(i2c_pnx->irq, i2c_pnx_interrupt, - 0, pdev->name, i2c_pnx->adapter); + 0, pdev->name, &alg_data->adapter); if (ret) goto out_clock; /* Register this adapter with the I2C subsystem */ - i2c_pnx->adapter->dev.parent = &pdev->dev; - i2c_pnx->adapter->nr = pdev->id; - ret = i2c_add_numbered_adapter(i2c_pnx->adapter); + ret = i2c_add_numbered_adapter(&alg_data->adapter); if (ret < 0) { dev_err(&pdev->dev, "I2C: Failed to add bus\n"); goto out_irq; } dev_dbg(&pdev->dev, "%s: Master at %#8x, irq %d.\n", - i2c_pnx->adapter->name, i2c_pnx->base, i2c_pnx->irq); + alg_data->adapter.name, i2c_pnx->base, i2c_pnx->irq); return 0; out_irq: - free_irq(i2c_pnx->irq, i2c_pnx->adapter); + free_irq(i2c_pnx->irq, &alg_data->adapter); out_clock: clk_disable(alg_data->clk); out_unmap: @@ -692,12 +693,11 @@ out: static int __devexit i2c_pnx_remove(struct platform_device *pdev) { - struct i2c_pnx_data *i2c_pnx = platform_get_drvdata(pdev); - struct i2c_adapter *adap = i2c_pnx->adapter; - struct i2c_pnx_algo_data *alg_data = adap->algo_data; + struct i2c_pnx_algo_data *alg_data = platform_get_drvdata(pdev); + struct i2c_pnx_data *i2c_pnx = alg_data->i2c_pnx; - free_irq(i2c_pnx->irq, i2c_pnx->adapter); - i2c_del_adapter(adap); + free_irq(i2c_pnx->irq, &alg_data->adapter); + i2c_del_adapter(&alg_data->adapter); clk_disable(alg_data->clk); iounmap(alg_data->ioaddr); release_mem_region(i2c_pnx->base, I2C_PNX_REGION_SIZE); -- cgit v1.2.2 From 81d6724a564fa5bd20b006eae0da4462d599bb92 Mon Sep 17 00:00:00 2001 From: Russell King Date: Sat, 21 Nov 2009 12:40:00 +0000 Subject: ARM: PNX4008: Use i2c driver data for passing between internal functions Since the drivers data now contains the i2c adapter structure, we can pass around the drivers data between internal functions (which is what they want) rather than using the i2c adapter structure and having an additional pointer dereference each time. Signed-off-by: Russell King --- drivers/i2c/busses/i2c-pnx.c | 132 ++++++++++++++++++++----------------------- 1 file changed, 62 insertions(+), 70 deletions(-) (limited to 'drivers') diff --git a/drivers/i2c/busses/i2c-pnx.c b/drivers/i2c/busses/i2c-pnx.c index 6b413c5300d3..181e69211e4f 100644 --- a/drivers/i2c/busses/i2c-pnx.c +++ b/drivers/i2c/busses/i2c-pnx.c @@ -52,10 +52,9 @@ static inline int wait_reset(long timeout, struct i2c_pnx_algo_data *data) return (timeout <= 0); } -static inline void i2c_pnx_arm_timer(struct i2c_adapter *adap) +static inline void i2c_pnx_arm_timer(struct i2c_pnx_algo_data *alg_data) { - struct i2c_pnx_algo_data *data = adap->algo_data; - struct timer_list *timer = &data->mif.timer; + struct timer_list *timer = &alg_data->mif.timer; int expires = I2C_PNX_TIMEOUT / (1000 / HZ); if (expires <= 1) @@ -63,11 +62,11 @@ static inline void i2c_pnx_arm_timer(struct i2c_adapter *adap) del_timer_sync(timer); - dev_dbg(&adap->dev, "Timer armed at %lu plus %u jiffies.\n", + dev_dbg(&alg_data->adapter.dev, "Timer armed at %lu plus %u jiffies.\n", jiffies, expires); timer->expires = jiffies + expires; - timer->data = (unsigned long)adap; + timer->data = (unsigned long)&alg_data; add_timer(timer); } @@ -79,34 +78,33 @@ static inline void i2c_pnx_arm_timer(struct i2c_adapter *adap) * * Generate a START signal in the desired mode. */ -static int i2c_pnx_start(unsigned char slave_addr, struct i2c_adapter *adap) +static int i2c_pnx_start(unsigned char slave_addr, + struct i2c_pnx_algo_data *alg_data) { - struct i2c_pnx_algo_data *alg_data = adap->algo_data; - - dev_dbg(&adap->dev, "%s(): addr 0x%x mode %d\n", __func__, + dev_dbg(&alg_data->adapter.dev, "%s(): addr 0x%x mode %d\n", __func__, slave_addr, alg_data->mif.mode); /* Check for 7 bit slave addresses only */ if (slave_addr & ~0x7f) { - dev_err(&adap->dev, "%s: Invalid slave address %x. " + dev_err(&alg_data->adapter.dev, "%s: Invalid slave address %x. " "Only 7-bit addresses are supported\n", - adap->name, slave_addr); + alg_data->adapter.name, slave_addr); return -EINVAL; } /* First, make sure bus is idle */ if (wait_timeout(I2C_PNX_TIMEOUT, alg_data)) { /* Somebody else is monopolizing the bus */ - dev_err(&adap->dev, "%s: Bus busy. Slave addr = %02x, " + dev_err(&alg_data->adapter.dev, "%s: Bus busy. Slave addr = %02x, " "cntrl = %x, stat = %x\n", - adap->name, slave_addr, + alg_data->adapter.name, slave_addr, ioread32(I2C_REG_CTL(alg_data)), ioread32(I2C_REG_STS(alg_data))); return -EBUSY; } else if (ioread32(I2C_REG_STS(alg_data)) & mstatus_afi) { /* Sorry, we lost the bus */ - dev_err(&adap->dev, "%s: Arbitration failure. " - "Slave addr = %02x\n", adap->name, slave_addr); + dev_err(&alg_data->adapter.dev, "%s: Arbitration failure. " + "Slave addr = %02x\n", alg_data->adapter.name, slave_addr); return -EIO; } @@ -117,14 +115,14 @@ static int i2c_pnx_start(unsigned char slave_addr, struct i2c_adapter *adap) iowrite32(ioread32(I2C_REG_STS(alg_data)) | mstatus_tdi | mstatus_afi, I2C_REG_STS(alg_data)); - dev_dbg(&adap->dev, "%s(): sending %#x\n", __func__, + dev_dbg(&alg_data->adapter.dev, "%s(): sending %#x\n", __func__, (slave_addr << 1) | start_bit | alg_data->mif.mode); /* Write the slave address, START bit and R/W bit */ iowrite32((slave_addr << 1) | start_bit | alg_data->mif.mode, I2C_REG_TX(alg_data)); - dev_dbg(&adap->dev, "%s(): exit\n", __func__); + dev_dbg(&alg_data->adapter.dev, "%s(): exit\n", __func__); return 0; } @@ -135,13 +133,12 @@ static int i2c_pnx_start(unsigned char slave_addr, struct i2c_adapter *adap) * * Generate a STOP signal to terminate the master transaction. */ -static void i2c_pnx_stop(struct i2c_adapter *adap) +static void i2c_pnx_stop(struct i2c_pnx_algo_data *alg_data) { - struct i2c_pnx_algo_data *alg_data = adap->algo_data; /* Only 1 msec max timeout due to interrupt context */ long timeout = 1000; - dev_dbg(&adap->dev, "%s(): entering: stat = %04x.\n", + dev_dbg(&alg_data->adapter.dev, "%s(): entering: stat = %04x.\n", __func__, ioread32(I2C_REG_STS(alg_data))); /* Write a STOP bit to TX FIFO */ @@ -155,7 +152,7 @@ static void i2c_pnx_stop(struct i2c_adapter *adap) timeout--; } - dev_dbg(&adap->dev, "%s(): exiting: stat = %04x.\n", + dev_dbg(&alg_data->adapter.dev, "%s(): exiting: stat = %04x.\n", __func__, ioread32(I2C_REG_STS(alg_data))); } @@ -165,12 +162,11 @@ static void i2c_pnx_stop(struct i2c_adapter *adap) * * Sends one byte of data to the slave */ -static int i2c_pnx_master_xmit(struct i2c_adapter *adap) +static int i2c_pnx_master_xmit(struct i2c_pnx_algo_data *alg_data) { - struct i2c_pnx_algo_data *alg_data = adap->algo_data; u32 val; - dev_dbg(&adap->dev, "%s(): entering: stat = %04x.\n", + dev_dbg(&alg_data->adapter.dev, "%s(): entering: stat = %04x.\n", __func__, ioread32(I2C_REG_STS(alg_data))); if (alg_data->mif.len > 0) { @@ -186,14 +182,14 @@ static int i2c_pnx_master_xmit(struct i2c_adapter *adap) alg_data->mif.len--; iowrite32(val, I2C_REG_TX(alg_data)); - dev_dbg(&adap->dev, "%s(): xmit %#x [%d]\n", __func__, + dev_dbg(&alg_data->adapter.dev, "%s(): xmit %#x [%d]\n", __func__, val, alg_data->mif.len + 1); if (alg_data->mif.len == 0) { if (alg_data->last) { /* Wait until the STOP is seen. */ if (wait_timeout(I2C_PNX_TIMEOUT, alg_data)) - dev_err(&adap->dev, "The bus is still " + dev_err(&alg_data->adapter.dev, "The bus is still " "active after timeout\n"); } /* Disable master interrupts */ @@ -203,14 +199,14 @@ static int i2c_pnx_master_xmit(struct i2c_adapter *adap) del_timer_sync(&alg_data->mif.timer); - dev_dbg(&adap->dev, "%s(): Waking up xfer routine.\n", + dev_dbg(&alg_data->adapter.dev, "%s(): Waking up xfer routine.\n", __func__); complete(&alg_data->mif.complete); } } else if (alg_data->mif.len == 0) { /* zero-sized transfer */ - i2c_pnx_stop(adap); + i2c_pnx_stop(alg_data); /* Disable master interrupts. */ iowrite32(ioread32(I2C_REG_CTL(alg_data)) & @@ -219,13 +215,13 @@ static int i2c_pnx_master_xmit(struct i2c_adapter *adap) /* Stop timer. */ del_timer_sync(&alg_data->mif.timer); - dev_dbg(&adap->dev, "%s(): Waking up xfer routine after " + dev_dbg(&alg_data->adapter.dev, "%s(): Waking up xfer routine after " "zero-xfer.\n", __func__); complete(&alg_data->mif.complete); } - dev_dbg(&adap->dev, "%s(): exiting: stat = %04x.\n", + dev_dbg(&alg_data->adapter.dev, "%s(): exiting: stat = %04x.\n", __func__, ioread32(I2C_REG_STS(alg_data))); return 0; @@ -237,20 +233,19 @@ static int i2c_pnx_master_xmit(struct i2c_adapter *adap) * * Reads one byte data from the slave */ -static int i2c_pnx_master_rcv(struct i2c_adapter *adap) +static int i2c_pnx_master_rcv(struct i2c_pnx_algo_data *alg_data) { - struct i2c_pnx_algo_data *alg_data = adap->algo_data; unsigned int val = 0; u32 ctl = 0; - dev_dbg(&adap->dev, "%s(): entering: stat = %04x.\n", + dev_dbg(&alg_data->adapter.dev, "%s(): entering: stat = %04x.\n", __func__, ioread32(I2C_REG_STS(alg_data))); /* Check, whether there is already data, * or we didn't 'ask' for it yet. */ if (ioread32(I2C_REG_STS(alg_data)) & mstatus_rfe) { - dev_dbg(&adap->dev, "%s(): Write dummy data to fill " + dev_dbg(&alg_data->adapter.dev, "%s(): Write dummy data to fill " "Rx-fifo...\n", __func__); if (alg_data->mif.len == 1) { @@ -283,7 +278,7 @@ static int i2c_pnx_master_rcv(struct i2c_adapter *adap) if (alg_data->mif.len > 0) { val = ioread32(I2C_REG_RX(alg_data)); *alg_data->mif.buf++ = (u8) (val & 0xff); - dev_dbg(&adap->dev, "%s(): rcv 0x%x [%d]\n", __func__, val, + dev_dbg(&alg_data->adapter.dev, "%s(): rcv 0x%x [%d]\n", __func__, val, alg_data->mif.len); alg_data->mif.len--; @@ -291,7 +286,7 @@ static int i2c_pnx_master_rcv(struct i2c_adapter *adap) if (alg_data->last) /* Wait until the STOP is seen. */ if (wait_timeout(I2C_PNX_TIMEOUT, alg_data)) - dev_err(&adap->dev, "The bus is still " + dev_err(&alg_data->adapter.dev, "The bus is still " "active after timeout\n"); /* Disable master interrupts */ @@ -306,7 +301,7 @@ static int i2c_pnx_master_rcv(struct i2c_adapter *adap) } } - dev_dbg(&adap->dev, "%s(): exiting: stat = %04x.\n", + dev_dbg(&alg_data->adapter.dev, "%s(): exiting: stat = %04x.\n", __func__, ioread32(I2C_REG_STS(alg_data))); return 0; @@ -314,11 +309,10 @@ static int i2c_pnx_master_rcv(struct i2c_adapter *adap) static irqreturn_t i2c_pnx_interrupt(int irq, void *dev_id) { + struct i2c_pnx_algo_data *alg_data = dev_id; u32 stat, ctl; - struct i2c_adapter *adap = dev_id; - struct i2c_pnx_algo_data *alg_data = adap->algo_data; - dev_dbg(&adap->dev, "%s(): mstat = %x mctrl = %x, mode = %d\n", + dev_dbg(&alg_data->adapter.dev, "%s(): mstat = %x mctrl = %x, mode = %d\n", __func__, ioread32(I2C_REG_STS(alg_data)), ioread32(I2C_REG_CTL(alg_data)), @@ -341,10 +335,10 @@ static irqreturn_t i2c_pnx_interrupt(int irq, void *dev_id) complete(&alg_data->mif.complete); } else if (stat & mstatus_nai) { /* Slave did not acknowledge, generate a STOP */ - dev_dbg(&adap->dev, "%s(): " + dev_dbg(&alg_data->adapter.dev, "%s(): " "Slave did not acknowledge, generating a STOP.\n", __func__); - i2c_pnx_stop(adap); + i2c_pnx_stop(alg_data); /* Disable master interrupts. */ ctl = ioread32(I2C_REG_CTL(alg_data)); @@ -370,9 +364,9 @@ static irqreturn_t i2c_pnx_interrupt(int irq, void *dev_id) */ if ((stat & mstatus_drmi) || !(stat & mstatus_rfe)) { if (alg_data->mif.mode == I2C_SMBUS_WRITE) { - i2c_pnx_master_xmit(adap); + i2c_pnx_master_xmit(alg_data); } else if (alg_data->mif.mode == I2C_SMBUS_READ) { - i2c_pnx_master_rcv(adap); + i2c_pnx_master_rcv(alg_data); } } } @@ -381,7 +375,7 @@ static irqreturn_t i2c_pnx_interrupt(int irq, void *dev_id) stat = ioread32(I2C_REG_STS(alg_data)); iowrite32(stat | mstatus_tdi | mstatus_afi, I2C_REG_STS(alg_data)); - dev_dbg(&adap->dev, "%s(): exiting, stat = %x ctrl = %x.\n", + dev_dbg(&alg_data->adapter.dev, "%s(): exiting, stat = %x ctrl = %x.\n", __func__, ioread32(I2C_REG_STS(alg_data)), ioread32(I2C_REG_CTL(alg_data))); @@ -390,11 +384,10 @@ static irqreturn_t i2c_pnx_interrupt(int irq, void *dev_id) static void i2c_pnx_timeout(unsigned long data) { - struct i2c_adapter *adap = (struct i2c_adapter *)data; - struct i2c_pnx_algo_data *alg_data = adap->algo_data; + struct i2c_pnx_algo_data *alg_data = (struct i2c_pnx_algo_data *)data; u32 ctl; - dev_err(&adap->dev, "Master timed out. stat = %04x, cntrl = %04x. " + dev_err(&alg_data->adapter.dev, "Master timed out. stat = %04x, cntrl = %04x. " "Resetting master...\n", ioread32(I2C_REG_STS(alg_data)), ioread32(I2C_REG_CTL(alg_data))); @@ -411,15 +404,14 @@ static void i2c_pnx_timeout(unsigned long data) complete(&alg_data->mif.complete); } -static inline void bus_reset_if_active(struct i2c_adapter *adap) +static inline void bus_reset_if_active(struct i2c_pnx_algo_data *alg_data) { - struct i2c_pnx_algo_data *alg_data = adap->algo_data; u32 stat; if ((stat = ioread32(I2C_REG_STS(alg_data))) & mstatus_active) { - dev_err(&adap->dev, + dev_err(&alg_data->adapter.dev, "%s: Bus is still active after xfer. Reset it...\n", - adap->name); + alg_data->adapter.name); iowrite32(ioread32(I2C_REG_CTL(alg_data)) | mcntrl_reset, I2C_REG_CTL(alg_data)); wait_reset(I2C_PNX_TIMEOUT, alg_data); @@ -453,10 +445,10 @@ i2c_pnx_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num) struct i2c_pnx_algo_data *alg_data = adap->algo_data; u32 stat = ioread32(I2C_REG_STS(alg_data)); - dev_dbg(&adap->dev, "%s(): entering: %d messages, stat = %04x.\n", + dev_dbg(&alg_data->adapter.dev, "%s(): entering: %d messages, stat = %04x.\n", __func__, num, ioread32(I2C_REG_STS(alg_data))); - bus_reset_if_active(adap); + bus_reset_if_active(alg_data); /* Process transactions in a loop. */ for (i = 0; rc >= 0 && i < num; i++) { @@ -466,9 +458,9 @@ i2c_pnx_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num) addr = pmsg->addr; if (pmsg->flags & I2C_M_TEN) { - dev_err(&adap->dev, + dev_err(&alg_data->adapter.dev, "%s: 10 bits addr not supported!\n", - adap->name); + alg_data->adapter.name); rc = -EINVAL; break; } @@ -480,11 +472,11 @@ i2c_pnx_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num) alg_data->mif.ret = 0; alg_data->last = (i == num - 1); - dev_dbg(&adap->dev, "%s(): mode %d, %d bytes\n", __func__, + dev_dbg(&alg_data->adapter.dev, "%s(): mode %d, %d bytes\n", __func__, alg_data->mif.mode, alg_data->mif.len); - i2c_pnx_arm_timer(adap); + i2c_pnx_arm_timer(alg_data); /* initialize the completion var */ init_completion(&alg_data->mif.complete); @@ -495,7 +487,7 @@ i2c_pnx_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num) I2C_REG_CTL(alg_data)); /* Put start-code and slave-address on the bus. */ - rc = i2c_pnx_start(addr, adap); + rc = i2c_pnx_start(addr, alg_data); if (rc < 0) break; @@ -504,31 +496,31 @@ i2c_pnx_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num) if (!(rc = alg_data->mif.ret)) completed++; - dev_dbg(&adap->dev, "%s(): Complete, return code = %d.\n", + dev_dbg(&alg_data->adapter.dev, "%s(): Complete, return code = %d.\n", __func__, rc); /* Clear TDI and AFI bits in case they are set. */ if ((stat = ioread32(I2C_REG_STS(alg_data))) & mstatus_tdi) { - dev_dbg(&adap->dev, + dev_dbg(&alg_data->adapter.dev, "%s: TDI still set... clearing now.\n", - adap->name); + alg_data->adapter.name); iowrite32(stat, I2C_REG_STS(alg_data)); } if ((stat = ioread32(I2C_REG_STS(alg_data))) & mstatus_afi) { - dev_dbg(&adap->dev, + dev_dbg(&alg_data->adapter.dev, "%s: AFI still set... clearing now.\n", - adap->name); + alg_data->adapter.name); iowrite32(stat, I2C_REG_STS(alg_data)); } } - bus_reset_if_active(adap); + bus_reset_if_active(alg_data); /* Cleanup to be sure... */ alg_data->mif.buf = NULL; alg_data->mif.len = 0; - dev_dbg(&adap->dev, "%s(): exiting, stat = %x\n", + dev_dbg(&alg_data->adapter.dev, "%s(): exiting, stat = %x\n", __func__, ioread32(I2C_REG_STS(alg_data))); if (completed != num) @@ -609,7 +601,7 @@ static int __devinit i2c_pnx_probe(struct platform_device *pdev) init_timer(&alg_data->mif.timer); alg_data->mif.timer.function = i2c_pnx_timeout; - alg_data->mif.timer.data = (unsigned long)&alg_data->adapter; + alg_data->mif.timer.data = (unsigned long)alg_data; /* Register I/O resource */ if (!request_mem_region(i2c_pnx->base, I2C_PNX_REGION_SIZE, @@ -657,7 +649,7 @@ static int __devinit i2c_pnx_probe(struct platform_device *pdev) init_completion(&alg_data->mif.complete); ret = request_irq(i2c_pnx->irq, i2c_pnx_interrupt, - 0, pdev->name, &alg_data->adapter); + 0, pdev->name, alg_data); if (ret) goto out_clock; @@ -674,7 +666,7 @@ static int __devinit i2c_pnx_probe(struct platform_device *pdev) return 0; out_irq: - free_irq(i2c_pnx->irq, &alg_data->adapter); + free_irq(i2c_pnx->irq, alg_data); out_clock: clk_disable(alg_data->clk); out_unmap: @@ -696,7 +688,7 @@ static int __devexit i2c_pnx_remove(struct platform_device *pdev) struct i2c_pnx_algo_data *alg_data = platform_get_drvdata(pdev); struct i2c_pnx_data *i2c_pnx = alg_data->i2c_pnx; - free_irq(i2c_pnx->irq, &alg_data->adapter); + free_irq(i2c_pnx->irq, alg_data); i2c_del_adapter(&alg_data->adapter); clk_disable(alg_data->clk); iounmap(alg_data->ioaddr); -- cgit v1.2.2 From 4be53dbe74818a12cc737a89b5d0aec6095956e0 Mon Sep 17 00:00:00 2001 From: Russell King Date: Sat, 21 Nov 2009 12:46:31 +0000 Subject: ARM: PNX4008: i2c-pnx: don't split messages across several lines It makes them harder to grep for. Signed-off-by: Russell King --- drivers/i2c/busses/i2c-pnx.c | 81 ++++++++++++++++++++++++-------------------- 1 file changed, 44 insertions(+), 37 deletions(-) (limited to 'drivers') diff --git a/drivers/i2c/busses/i2c-pnx.c b/drivers/i2c/busses/i2c-pnx.c index 181e69211e4f..afc9c968deec 100644 --- a/drivers/i2c/busses/i2c-pnx.c +++ b/drivers/i2c/busses/i2c-pnx.c @@ -86,25 +86,26 @@ static int i2c_pnx_start(unsigned char slave_addr, /* Check for 7 bit slave addresses only */ if (slave_addr & ~0x7f) { - dev_err(&alg_data->adapter.dev, "%s: Invalid slave address %x. " - "Only 7-bit addresses are supported\n", - alg_data->adapter.name, slave_addr); + dev_err(&alg_data->adapter.dev, + "%s: Invalid slave address %x. Only 7-bit addresses are supported\n", + alg_data->adapter.name, slave_addr); return -EINVAL; } /* First, make sure bus is idle */ if (wait_timeout(I2C_PNX_TIMEOUT, alg_data)) { /* Somebody else is monopolizing the bus */ - dev_err(&alg_data->adapter.dev, "%s: Bus busy. Slave addr = %02x, " - "cntrl = %x, stat = %x\n", - alg_data->adapter.name, slave_addr, - ioread32(I2C_REG_CTL(alg_data)), - ioread32(I2C_REG_STS(alg_data))); + dev_err(&alg_data->adapter.dev, + "%s: Bus busy. Slave addr = %02x, cntrl = %x, stat = %x\n", + alg_data->adapter.name, slave_addr, + ioread32(I2C_REG_CTL(alg_data)), + ioread32(I2C_REG_STS(alg_data))); return -EBUSY; } else if (ioread32(I2C_REG_STS(alg_data)) & mstatus_afi) { /* Sorry, we lost the bus */ - dev_err(&alg_data->adapter.dev, "%s: Arbitration failure. " - "Slave addr = %02x\n", alg_data->adapter.name, slave_addr); + dev_err(&alg_data->adapter.dev, + "%s: Arbitration failure. Slave addr = %02x\n", + alg_data->adapter.name, slave_addr); return -EIO; } @@ -182,15 +183,15 @@ static int i2c_pnx_master_xmit(struct i2c_pnx_algo_data *alg_data) alg_data->mif.len--; iowrite32(val, I2C_REG_TX(alg_data)); - dev_dbg(&alg_data->adapter.dev, "%s(): xmit %#x [%d]\n", __func__, - val, alg_data->mif.len + 1); + dev_dbg(&alg_data->adapter.dev, "%s(): xmit %#x [%d]\n", + __func__, val, alg_data->mif.len + 1); if (alg_data->mif.len == 0) { if (alg_data->last) { /* Wait until the STOP is seen. */ if (wait_timeout(I2C_PNX_TIMEOUT, alg_data)) - dev_err(&alg_data->adapter.dev, "The bus is still " - "active after timeout\n"); + dev_err(&alg_data->adapter.dev, + "The bus is still active after timeout\n"); } /* Disable master interrupts */ iowrite32(ioread32(I2C_REG_CTL(alg_data)) & @@ -199,7 +200,8 @@ static int i2c_pnx_master_xmit(struct i2c_pnx_algo_data *alg_data) del_timer_sync(&alg_data->mif.timer); - dev_dbg(&alg_data->adapter.dev, "%s(): Waking up xfer routine.\n", + dev_dbg(&alg_data->adapter.dev, + "%s(): Waking up xfer routine.\n", __func__); complete(&alg_data->mif.complete); @@ -215,8 +217,9 @@ static int i2c_pnx_master_xmit(struct i2c_pnx_algo_data *alg_data) /* Stop timer. */ del_timer_sync(&alg_data->mif.timer); - dev_dbg(&alg_data->adapter.dev, "%s(): Waking up xfer routine after " - "zero-xfer.\n", __func__); + dev_dbg(&alg_data->adapter.dev, + "%s(): Waking up xfer routine after zero-xfer.\n", + __func__); complete(&alg_data->mif.complete); } @@ -245,8 +248,9 @@ static int i2c_pnx_master_rcv(struct i2c_pnx_algo_data *alg_data) * or we didn't 'ask' for it yet. */ if (ioread32(I2C_REG_STS(alg_data)) & mstatus_rfe) { - dev_dbg(&alg_data->adapter.dev, "%s(): Write dummy data to fill " - "Rx-fifo...\n", __func__); + dev_dbg(&alg_data->adapter.dev, + "%s(): Write dummy data to fill Rx-fifo...\n", + __func__); if (alg_data->mif.len == 1) { /* Last byte, do not acknowledge next rcv. */ @@ -278,16 +282,16 @@ static int i2c_pnx_master_rcv(struct i2c_pnx_algo_data *alg_data) if (alg_data->mif.len > 0) { val = ioread32(I2C_REG_RX(alg_data)); *alg_data->mif.buf++ = (u8) (val & 0xff); - dev_dbg(&alg_data->adapter.dev, "%s(): rcv 0x%x [%d]\n", __func__, val, - alg_data->mif.len); + dev_dbg(&alg_data->adapter.dev, "%s(): rcv 0x%x [%d]\n", + __func__, val, alg_data->mif.len); alg_data->mif.len--; if (alg_data->mif.len == 0) { if (alg_data->last) /* Wait until the STOP is seen. */ if (wait_timeout(I2C_PNX_TIMEOUT, alg_data)) - dev_err(&alg_data->adapter.dev, "The bus is still " - "active after timeout\n"); + dev_err(&alg_data->adapter.dev, + "The bus is still active after timeout\n"); /* Disable master interrupts */ ctl = ioread32(I2C_REG_CTL(alg_data)); @@ -312,7 +316,8 @@ static irqreturn_t i2c_pnx_interrupt(int irq, void *dev_id) struct i2c_pnx_algo_data *alg_data = dev_id; u32 stat, ctl; - dev_dbg(&alg_data->adapter.dev, "%s(): mstat = %x mctrl = %x, mode = %d\n", + dev_dbg(&alg_data->adapter.dev, + "%s(): mstat = %x mctrl = %x, mode = %d\n", __func__, ioread32(I2C_REG_STS(alg_data)), ioread32(I2C_REG_CTL(alg_data)), @@ -335,8 +340,8 @@ static irqreturn_t i2c_pnx_interrupt(int irq, void *dev_id) complete(&alg_data->mif.complete); } else if (stat & mstatus_nai) { /* Slave did not acknowledge, generate a STOP */ - dev_dbg(&alg_data->adapter.dev, "%s(): " - "Slave did not acknowledge, generating a STOP.\n", + dev_dbg(&alg_data->adapter.dev, + "%s(): Slave did not acknowledge, generating a STOP.\n", __func__); i2c_pnx_stop(alg_data); @@ -375,7 +380,8 @@ static irqreturn_t i2c_pnx_interrupt(int irq, void *dev_id) stat = ioread32(I2C_REG_STS(alg_data)); iowrite32(stat | mstatus_tdi | mstatus_afi, I2C_REG_STS(alg_data)); - dev_dbg(&alg_data->adapter.dev, "%s(): exiting, stat = %x ctrl = %x.\n", + dev_dbg(&alg_data->adapter.dev, + "%s(): exiting, stat = %x ctrl = %x.\n", __func__, ioread32(I2C_REG_STS(alg_data)), ioread32(I2C_REG_CTL(alg_data))); @@ -387,10 +393,10 @@ static void i2c_pnx_timeout(unsigned long data) struct i2c_pnx_algo_data *alg_data = (struct i2c_pnx_algo_data *)data; u32 ctl; - dev_err(&alg_data->adapter.dev, "Master timed out. stat = %04x, cntrl = %04x. " - "Resetting master...\n", - ioread32(I2C_REG_STS(alg_data)), - ioread32(I2C_REG_CTL(alg_data))); + dev_err(&alg_data->adapter.dev, + "Master timed out. stat = %04x, cntrl = %04x. Resetting master...\n", + ioread32(I2C_REG_STS(alg_data)), + ioread32(I2C_REG_CTL(alg_data))); /* Reset master and disable interrupts */ ctl = ioread32(I2C_REG_CTL(alg_data)); @@ -411,7 +417,7 @@ static inline void bus_reset_if_active(struct i2c_pnx_algo_data *alg_data) if ((stat = ioread32(I2C_REG_STS(alg_data))) & mstatus_active) { dev_err(&alg_data->adapter.dev, "%s: Bus is still active after xfer. Reset it...\n", - alg_data->adapter.name); + alg_data->adapter.name); iowrite32(ioread32(I2C_REG_CTL(alg_data)) | mcntrl_reset, I2C_REG_CTL(alg_data)); wait_reset(I2C_PNX_TIMEOUT, alg_data); @@ -445,7 +451,8 @@ i2c_pnx_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num) struct i2c_pnx_algo_data *alg_data = adap->algo_data; u32 stat = ioread32(I2C_REG_STS(alg_data)); - dev_dbg(&alg_data->adapter.dev, "%s(): entering: %d messages, stat = %04x.\n", + dev_dbg(&alg_data->adapter.dev, + "%s(): entering: %d messages, stat = %04x.\n", __func__, num, ioread32(I2C_REG_STS(alg_data))); bus_reset_if_active(alg_data); @@ -472,9 +479,8 @@ i2c_pnx_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num) alg_data->mif.ret = 0; alg_data->last = (i == num - 1); - dev_dbg(&alg_data->adapter.dev, "%s(): mode %d, %d bytes\n", __func__, - alg_data->mif.mode, - alg_data->mif.len); + dev_dbg(&alg_data->adapter.dev, "%s(): mode %d, %d bytes\n", + __func__, alg_data->mif.mode, alg_data->mif.len); i2c_pnx_arm_timer(alg_data); @@ -496,7 +502,8 @@ i2c_pnx_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num) if (!(rc = alg_data->mif.ret)) completed++; - dev_dbg(&alg_data->adapter.dev, "%s(): Complete, return code = %d.\n", + dev_dbg(&alg_data->adapter.dev, + "%s(): Complete, return code = %d.\n", __func__, rc); /* Clear TDI and AFI bits in case they are set. */ -- cgit v1.2.2 From 7e20c837208f6fdd553d04f5fe3e80f44570698b Mon Sep 17 00:00:00 2001 From: Russell King Date: Sat, 21 Nov 2009 12:56:13 +0000 Subject: ARM: PNX4008: i2c-pnx makes no use of asm/uaccess.h nor asm/irq.h Remove unnecessary includes Signed-off-by: Russell King --- drivers/i2c/busses/i2c-pnx.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers') diff --git a/drivers/i2c/busses/i2c-pnx.c b/drivers/i2c/busses/i2c-pnx.c index afc9c968deec..ecdd5230ae36 100644 --- a/drivers/i2c/busses/i2c-pnx.c +++ b/drivers/i2c/busses/i2c-pnx.c @@ -25,8 +25,6 @@ #include #include -#include -#include #define I2C_PNX_TIMEOUT 10 /* msec */ #define I2C_PNX_SPEED_KHZ 100 -- cgit v1.2.2 From eed18b5fa4d297c681b00144e8c6942dd35d39a7 Mon Sep 17 00:00:00 2001 From: Russell King Date: Sat, 21 Nov 2009 12:58:13 +0000 Subject: ARM: PNX4008: use msecs_to_jiffies() rather than open-coding it Signed-off-by: Russell King --- drivers/i2c/busses/i2c-pnx.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/i2c/busses/i2c-pnx.c b/drivers/i2c/busses/i2c-pnx.c index ecdd5230ae36..2b0bd0b042d6 100644 --- a/drivers/i2c/busses/i2c-pnx.c +++ b/drivers/i2c/busses/i2c-pnx.c @@ -53,14 +53,14 @@ static inline int wait_reset(long timeout, struct i2c_pnx_algo_data *data) static inline void i2c_pnx_arm_timer(struct i2c_pnx_algo_data *alg_data) { struct timer_list *timer = &alg_data->mif.timer; - int expires = I2C_PNX_TIMEOUT / (1000 / HZ); + unsigned long expires = msecs_to_jiffies(I2C_PNX_TIMEOUT); if (expires <= 1) expires = 2; del_timer_sync(timer); - dev_dbg(&alg_data->adapter.dev, "Timer armed at %lu plus %u jiffies.\n", + dev_dbg(&alg_data->adapter.dev, "Timer armed at %lu plus %lu jiffies.\n", jiffies, expires); timer->expires = jiffies + expires; -- cgit v1.2.2 From 6dd2e42bd892b2e16080ceba451fd9c3ed633145 Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Thu, 14 Jan 2010 17:32:13 +0200 Subject: OMAP: DSS2: OMAPFB: implement OMAPFB_GET_DISPLAY_INFO Previously the only place to get the size of the display was from the DSS's sysfs interface, making, for example, configuring overlays and doing updates on manual displays more difficult. Signed-off-by: Tomi Valkeinen --- drivers/video/omap2/omapfb/omapfb-ioctl.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) (limited to 'drivers') diff --git a/drivers/video/omap2/omapfb/omapfb-ioctl.c b/drivers/video/omap2/omapfb/omapfb-ioctl.c index 4c4bafdfaa43..33fc1459a7c9 100644 --- a/drivers/video/omap2/omapfb/omapfb-ioctl.c +++ b/drivers/video/omap2/omapfb/omapfb-ioctl.c @@ -483,6 +483,7 @@ int omapfb_ioctl(struct fb_info *fbi, unsigned int cmd, unsigned long arg) struct omapfb_memory_read memory_read; struct omapfb_vram_info vram_info; struct omapfb_tearsync_info tearsync_info; + struct omapfb_display_info display_info; } p; int r = 0; @@ -741,6 +742,29 @@ int omapfb_ioctl(struct fb_info *fbi, unsigned int cmd, unsigned long arg) break; } + case OMAPFB_GET_DISPLAY_INFO: { + u16 xres, yres; + + DBG("ioctl GET_DISPLAY_INFO\n"); + + if (display == NULL) { + r = -ENODEV; + break; + } + + display->get_resolution(display, &xres, &yres); + + p.display_info.xres = xres; + p.display_info.yres = yres; + p.display_info.width = 0; + p.display_info.height = 0; + + if (copy_to_user((void __user *)arg, &p.display_info, + sizeof(p.display_info))) + r = -EFAULT; + break; + } + default: dev_err(fbdev->dev, "Unknown ioctl 0x%x\n", cmd); r = -EINVAL; -- cgit v1.2.2 From 853525d7785761d2d9c121b41326ab19d3af4a22 Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Mon, 8 Feb 2010 12:19:46 +0200 Subject: OMAP: DSS2: fix irq-stats compilation Fix compilation of the CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS feature. Signed-off-by: Tomi Valkeinen --- drivers/video/omap2/dss/core.c | 4 +++- drivers/video/omap2/dss/dispc.c | 2 -- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/video/omap2/dss/core.c b/drivers/video/omap2/dss/core.c index 791e1cb7c0bc..5939da9cf021 100644 --- a/drivers/video/omap2/dss/core.c +++ b/drivers/video/omap2/dss/core.c @@ -446,10 +446,12 @@ static int dss_initialize_debugfs(void) debugfs_create_file("clk", S_IRUGO, dss_debugfs_dir, &dss_debug_dump_clocks, &dss_debug_fops); +#ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS debugfs_create_file("dispc_irq", S_IRUGO, dss_debugfs_dir, &dispc_dump_irqs, &dss_debug_fops); +#endif -#ifdef CONFIG_OMAP2_DSS_DSI +#if defined(CONFIG_OMAP2_DSS_DSI) && defined(CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS) debugfs_create_file("dsi_irq", S_IRUGO, dss_debugfs_dir, &dsi_dump_irqs, &dss_debug_fops); #endif diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c index de8bfbac9e26..7781c65bbeba 100644 --- a/drivers/video/omap2/dss/dispc.c +++ b/drivers/video/omap2/dss/dispc.c @@ -2301,8 +2301,6 @@ void dispc_dump_irqs(struct seq_file *s) PIS(WAKEUP); #undef PIS } -#else -void dispc_dump_irqs(struct seq_file *s) { } #endif void dispc_dump_regs(struct seq_file *s) -- cgit v1.2.2 From b63c97f5184684c841be84ec80928e3c5fe57fbe Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Fri, 5 Feb 2010 14:46:19 +0200 Subject: OMAP: DSS2: OMAPFB: Add omapfb_update_window prototype Signed-off-by: Tomi Valkeinen --- drivers/video/omap2/omapfb/omapfb.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/video/omap2/omapfb/omapfb.h b/drivers/video/omap2/omapfb/omapfb.h index f7c9c739e5ef..4ae0b64b3f43 100644 --- a/drivers/video/omap2/omapfb/omapfb.h +++ b/drivers/video/omap2/omapfb/omapfb.h @@ -105,6 +105,9 @@ void omapfb_remove_sysfs(struct omapfb2_device *fbdev); int omapfb_ioctl(struct fb_info *fbi, unsigned int cmd, unsigned long arg); +int omapfb_update_window(struct fb_info *fbi, + u32 x, u32 y, u32 w, u32 h); + int dss_mode_to_fb_mode(enum omap_color_mode dssmode, struct fb_var_screeninfo *var); -- cgit v1.2.2 From 2f18c4d89861fc1abdfa2531ba76017acb78edc5 Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Fri, 8 Jan 2010 18:00:36 +0200 Subject: OMAP: DSS2: improve DSS clk src selection dss_select_clk_source() was rather confusing. Selecting the source with enums is much clearer. The clk source selection is also stored into memory, so that we know what is the selected source, even when clocks are off. This is important during setup, as we need to what clocks to turn on before the clocks are turned on. Signed-off-by: Tomi Valkeinen --- drivers/video/omap2/dss/dpi.c | 4 ++-- drivers/video/omap2/dss/dsi.c | 9 ++++++--- drivers/video/omap2/dss/dss.c | 42 ++++++++++++++++++++++++++++++++---------- drivers/video/omap2/dss/dss.h | 14 +++++++++++--- 4 files changed, 51 insertions(+), 18 deletions(-) (limited to 'drivers') diff --git a/drivers/video/omap2/dss/dpi.c b/drivers/video/omap2/dss/dpi.c index 69ce31ae2a2f..c5091ed12a7d 100644 --- a/drivers/video/omap2/dss/dpi.c +++ b/drivers/video/omap2/dss/dpi.c @@ -57,7 +57,7 @@ static int dpi_set_dsi_clk(bool is_tft, unsigned long pck_req, if (r) return r; - dss_select_clk_source(0, 1); + dss_select_dispc_clk_source(DSS_SRC_DSI1_PLL_FCLK); r = dispc_set_clock_div(&dispc_cinfo); if (r) @@ -238,7 +238,7 @@ static void dpi_display_disable(struct omap_dss_device *dssdev) dispc_enable_lcd_out(0); #ifdef CONFIG_OMAP2_DSS_USE_DSI_PLL - dss_select_clk_source(0, 0); + dss_select_dispc_clk_source(DSS_SRC_DSS1_ALWON_FCLK); dsi_pll_uninit(); dss_clk_disable(DSS_CLK_FCK2); #endif diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c index 036f4221e3df..4fdb628427e0 100644 --- a/drivers/video/omap2/dss/dsi.c +++ b/drivers/video/omap2/dss/dsi.c @@ -3203,7 +3203,8 @@ static int dsi_display_init_dsi(struct omap_dss_device *dssdev) if (r) goto err1; - dss_select_clk_source(true, true); + dss_select_dispc_clk_source(DSS_SRC_DSI1_PLL_FCLK); + dss_select_dsi_clk_source(DSS_SRC_DSI2_PLL_FCLK); DSSDBG("PLL OK\n"); @@ -3247,7 +3248,8 @@ err4: err3: dsi_complexio_uninit(); err2: - dss_select_clk_source(false, false); + dss_select_dispc_clk_source(DSS_SRC_DSS1_ALWON_FCLK); + dss_select_dsi_clk_source(DSS_SRC_DSS1_ALWON_FCLK); err1: dsi_pll_uninit(); err0: @@ -3259,7 +3261,8 @@ static void dsi_display_uninit_dsi(struct omap_dss_device *dssdev) if (dssdev->driver->disable) dssdev->driver->disable(dssdev); - dss_select_clk_source(false, false); + dss_select_dispc_clk_source(DSS_SRC_DSS1_ALWON_FCLK); + dss_select_dsi_clk_source(DSS_SRC_DSS1_ALWON_FCLK); dsi_complexio_uninit(); dsi_pll_uninit(); } diff --git a/drivers/video/omap2/dss/dss.c b/drivers/video/omap2/dss/dss.c index 0a26b7d84d41..8254a4232a53 100644 --- a/drivers/video/omap2/dss/dss.c +++ b/drivers/video/omap2/dss/dss.c @@ -68,6 +68,9 @@ static struct { struct dss_clock_info cache_dss_cinfo; struct dispc_clock_info cache_dispc_cinfo; + enum dss_clk_source dsi_clk_source; + enum dss_clk_source dispc_clk_source; + u32 ctx[DSS_SZ_REGS / sizeof(u32)]; } dss; @@ -247,23 +250,42 @@ void dss_dump_regs(struct seq_file *s) #undef DUMPREG } -void dss_select_clk_source(bool dsi, bool dispc) +void dss_select_dispc_clk_source(enum dss_clk_source clk_src) +{ + int b; + + BUG_ON(clk_src != DSS_SRC_DSI1_PLL_FCLK && + clk_src != DSS_SRC_DSS1_ALWON_FCLK); + + b = clk_src == DSS_SRC_DSS1_ALWON_FCLK ? 0 : 1; + + REG_FLD_MOD(DSS_CONTROL, b, 0, 0); /* DISPC_CLK_SWITCH */ + + dss.dispc_clk_source = clk_src; +} + +void dss_select_dsi_clk_source(enum dss_clk_source clk_src) { - u32 r; - r = dss_read_reg(DSS_CONTROL); - r = FLD_MOD(r, dsi, 1, 1); /* DSI_CLK_SWITCH */ - r = FLD_MOD(r, dispc, 0, 0); /* DISPC_CLK_SWITCH */ - dss_write_reg(DSS_CONTROL, r); + int b; + + BUG_ON(clk_src != DSS_SRC_DSI2_PLL_FCLK && + clk_src != DSS_SRC_DSS1_ALWON_FCLK); + + b = clk_src == DSS_SRC_DSS1_ALWON_FCLK ? 0 : 1; + + REG_FLD_MOD(DSS_CONTROL, b, 1, 1); /* DSI_CLK_SWITCH */ + + dss.dsi_clk_source = clk_src; } -int dss_get_dsi_clk_source(void) +enum dss_clk_source dss_get_dispc_clk_source(void) { - return FLD_GET(dss_read_reg(DSS_CONTROL), 1, 1); + return dss.dispc_clk_source; } -int dss_get_dispc_clk_source(void) +enum dss_clk_source dss_get_dsi_clk_source(void) { - return FLD_GET(dss_read_reg(DSS_CONTROL), 0, 0); + return dss.dsi_clk_source; } /* calculate clock rates using dividers in cinfo */ diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h index 41145af36353..3713dc698259 100644 --- a/drivers/video/omap2/dss/dss.h +++ b/drivers/video/omap2/dss/dss.h @@ -119,6 +119,12 @@ enum dss_clock { DSS_CLK_96M = 1 << 4, }; +enum dss_clk_source { + DSS_SRC_DSI1_PLL_FCLK, + DSS_SRC_DSI2_PLL_FCLK, + DSS_SRC_DSS1_ALWON_FCLK, +}; + struct dss_clock_info { /* rates that we get with dividers below */ unsigned long fck; @@ -219,9 +225,11 @@ void dss_sdi_init(u8 datapairs); int dss_sdi_enable(void); void dss_sdi_disable(void); -void dss_select_clk_source(bool dsi, bool dispc); -int dss_get_dsi_clk_source(void); -int dss_get_dispc_clk_source(void); +void dss_select_dispc_clk_source(enum dss_clk_source clk_src); +void dss_select_dsi_clk_source(enum dss_clk_source clk_src); +enum dss_clk_source dss_get_dispc_clk_source(void); +enum dss_clk_source dss_get_dsi_clk_source(void); + void dss_set_venc_output(enum omap_dss_venc_type type); void dss_set_dac_pwrdn_bgz(bool enable); -- cgit v1.2.2 From 4f76502374ff91bc80a48a32cabb1009087a3b9d Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Mon, 18 Jan 2010 16:27:52 +0200 Subject: OMAP: DSS2: DSI: add dsi_bus_is_locked() Helper function to clean up the checking of the bus lock. Signed-off-by: Tomi Valkeinen --- drivers/video/omap2/dss/dsi.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c index 4fdb628427e0..b38974523d48 100644 --- a/drivers/video/omap2/dss/dsi.c +++ b/drivers/video/omap2/dss/dsi.c @@ -309,6 +309,11 @@ void dsi_bus_unlock(void) } EXPORT_SYMBOL(dsi_bus_unlock); +static bool dsi_bus_is_locked(void) +{ + return mutex_is_locked(&dsi.bus_lock); +} + static inline int wait_for_bit_change(const struct dsi_reg idx, int bitnum, int value) { @@ -1959,7 +1964,7 @@ static int dsi_vc_send_bta(int channel) (dsi.debug_write || dsi.debug_read)) DSSDBG("dsi_vc_send_bta %d\n", channel); - WARN_ON(!mutex_is_locked(&dsi.bus_lock)); + WARN_ON(!dsi_bus_is_locked()); if (REG_GET(DSI_VC_CTRL(channel), 20, 20)) { /* RX_FIFO_NOT_EMPTY */ DSSERR("rx fifo not empty when sending BTA, dumping data:\n"); @@ -2010,7 +2015,7 @@ static inline void dsi_vc_write_long_header(int channel, u8 data_type, u32 val; u8 data_id; - WARN_ON(!mutex_is_locked(&dsi.bus_lock)); + WARN_ON(!dsi_bus_is_locked()); /*data_id = data_type | channel << 6; */ data_id = data_type | dsi.vc[channel].dest_per << 6; @@ -2105,7 +2110,7 @@ static int dsi_vc_send_short(int channel, u8 data_type, u16 data, u8 ecc) u32 r; u8 data_id; - WARN_ON(!mutex_is_locked(&dsi.bus_lock)); + WARN_ON(!dsi_bus_is_locked()); if (dsi.debug_write) DSSDBG("dsi_vc_send_short(ch%d, dt %#x, b1 %#x, b2 %#x)\n", @@ -2895,7 +2900,7 @@ static int dsi_set_update_mode(struct omap_dss_device *dssdev, int r = 0; int i; - WARN_ON(!mutex_is_locked(&dsi.bus_lock)); + WARN_ON(!dsi_bus_is_locked()); if (dsi.update_mode != mode) { dsi.update_mode = mode; -- cgit v1.2.2 From 828c48f8c51ebfc2a00e1a834b0bc9e7fd35060f Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Wed, 16 Dec 2009 14:53:15 +0200 Subject: OMAP: DSS2: DSI: add helpers for DCS read/write Add helper functions for most common DCS read and write operations. Signed-off-by: Tomi Valkeinen --- drivers/video/omap2/dss/dsi.c | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) (limited to 'drivers') diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c index b38974523d48..e49f063fb615 100644 --- a/drivers/video/omap2/dss/dsi.c +++ b/drivers/video/omap2/dss/dsi.c @@ -2176,6 +2176,21 @@ int dsi_vc_dcs_write(int channel, u8 *data, int len) } EXPORT_SYMBOL(dsi_vc_dcs_write); +int dsi_vc_dcs_write_0(int channel, u8 dcs_cmd) +{ + return dsi_vc_dcs_write(channel, &dcs_cmd, 1); +} +EXPORT_SYMBOL(dsi_vc_dcs_write_0); + +int dsi_vc_dcs_write_1(int channel, u8 dcs_cmd, u8 param) +{ + u8 buf[2]; + buf[0] = dcs_cmd; + buf[1] = param; + return dsi_vc_dcs_write(channel, buf, 2); +} +EXPORT_SYMBOL(dsi_vc_dcs_write_1); + int dsi_vc_dcs_read(int channel, u8 dcs_cmd, u8 *buf, int buflen) { u32 val; @@ -2268,6 +2283,21 @@ int dsi_vc_dcs_read(int channel, u8 dcs_cmd, u8 *buf, int buflen) } EXPORT_SYMBOL(dsi_vc_dcs_read); +int dsi_vc_dcs_read_1(int channel, u8 dcs_cmd, u8 *data) +{ + int r; + + r = dsi_vc_dcs_read(channel, dcs_cmd, data, 1); + + if (r < 0) + return r; + + if (r != 1) + return -EIO; + + return 0; +} +EXPORT_SYMBOL(dsi_vc_dcs_read_1); int dsi_vc_set_max_rx_packet_size(int channel, u16 len) { -- cgit v1.2.2 From 61140c9a88ce1f1dee4e98a0c442f9a84b4c5e6b Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Tue, 12 Jan 2010 16:00:30 +0200 Subject: OMAP: DSS2: DSI: export dsi_vc_enable_hs() Rename and export dsi_vc_enable_hs() so that the display drivers can control the mode of the DSI link. Signed-off-by: Tomi Valkeinen --- drivers/video/omap2/dss/dsi.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c index e49f063fb615..e003fe9ee9c4 100644 --- a/drivers/video/omap2/dss/dsi.c +++ b/drivers/video/omap2/dss/dsi.c @@ -1864,10 +1864,12 @@ static void dsi_vc_config_vp(int channel) } -static void dsi_vc_enable_hs(int channel, bool enable) +void omapdss_dsi_vc_enable_hs(int channel, bool enable) { DSSDBG("dsi_vc_enable_hs(%d, %d)\n", channel, enable); + WARN_ON(!dsi_bus_is_locked()); + dsi_vc_enable(channel, 0); dsi_if_enable(0); @@ -1878,6 +1880,7 @@ static void dsi_vc_enable_hs(int channel, bool enable) dsi_force_tx_stop_mode_io(); } +EXPORT_SYMBOL(omapdss_dsi_vc_enable_hs); static void dsi_vc_flush_long_data(int channel) { @@ -3275,7 +3278,7 @@ static int dsi_display_init_dsi(struct omap_dss_device *dssdev) } /* enable high-speed after initial config */ - dsi_vc_enable_hs(0, 1); + omapdss_dsi_vc_enable_hs(0, 1); return 0; err4: @@ -3688,7 +3691,7 @@ static int dsi_display_run_test(struct omap_dss_device *dssdev, int test_num) dsi_bus_lock(); /* run test first in low speed mode */ - dsi_vc_enable_hs(0, 0); + omapdss_dsi_vc_enable_hs(0, 0); if (dssdev->driver->run_test) { r = dssdev->driver->run_test(dssdev, test_num); @@ -3697,7 +3700,7 @@ static int dsi_display_run_test(struct omap_dss_device *dssdev, int test_num) } /* then in high speed */ - dsi_vc_enable_hs(0, 1); + omapdss_dsi_vc_enable_hs(0, 1); if (dssdev->driver->run_test) { r = dssdev->driver->run_test(dssdev, test_num); @@ -3706,7 +3709,7 @@ static int dsi_display_run_test(struct omap_dss_device *dssdev, int test_num) } end: - dsi_vc_enable_hs(0, 1); + omapdss_dsi_vc_enable_hs(0, 1); dsi_bus_unlock(); -- cgit v1.2.2 From dd8079d6a9c2aa292dacaf1b42f526558e20379f Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Wed, 16 Dec 2009 16:49:03 +0200 Subject: OMAP: DSS2: DSI: configure all DSI VCs Instead of configuring only VC0 to be usable, configure all four VCs similarly. This is needed to utilize the other VCs. Setting the FIFO sizes evenly for all VCs, regardless of how many VCs are actually used, is not optimal. However, this affects only cases when larger amounts of data are written or read via L4, meaning that normal use cases are not affected. At some point this could be optimized better to suit different use cases. Signed-off-by: Tomi Valkeinen --- drivers/video/omap2/dss/dsi.c | 39 +++++++++++++++++---------------------- 1 file changed, 17 insertions(+), 22 deletions(-) (limited to 'drivers') diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c index e003fe9ee9c4..131bd53b6b6d 100644 --- a/drivers/video/omap2/dss/dsi.c +++ b/drivers/video/omap2/dss/dsi.c @@ -224,7 +224,6 @@ static struct enum dsi_vc_mode mode; struct omap_dss_device *dssdev; enum fifo_size fifo_size; - int dest_per; /* destination peripheral 0-3 */ } vc[4]; struct mutex lock; @@ -2020,8 +2019,7 @@ static inline void dsi_vc_write_long_header(int channel, u8 data_type, WARN_ON(!dsi_bus_is_locked()); - /*data_id = data_type | channel << 6; */ - data_id = data_type | dsi.vc[channel].dest_per << 6; + data_id = data_type | channel << 6; val = FLD_VAL(data_id, 7, 0) | FLD_VAL(len, 23, 8) | FLD_VAL(ecc, 31, 24); @@ -2127,7 +2125,7 @@ static int dsi_vc_send_short(int channel, u8 data_type, u16 data, u8 ecc) return -EINVAL; } - data_id = data_type | dsi.vc[channel].dest_per << 6; + data_id = data_type | channel << 6; r = (data_id << 0) | (data << 8) | (ecc << 24); @@ -2529,15 +2527,15 @@ static int dsi_proto_config(struct omap_dss_device *dssdev) u32 r; int buswidth = 0; - dsi_config_tx_fifo(DSI_FIFO_SIZE_128, - DSI_FIFO_SIZE_0, - DSI_FIFO_SIZE_0, - DSI_FIFO_SIZE_0); + dsi_config_tx_fifo(DSI_FIFO_SIZE_32, + DSI_FIFO_SIZE_32, + DSI_FIFO_SIZE_32, + DSI_FIFO_SIZE_32); - dsi_config_rx_fifo(DSI_FIFO_SIZE_128, - DSI_FIFO_SIZE_0, - DSI_FIFO_SIZE_0, - DSI_FIFO_SIZE_0); + dsi_config_rx_fifo(DSI_FIFO_SIZE_32, + DSI_FIFO_SIZE_32, + DSI_FIFO_SIZE_32, + DSI_FIFO_SIZE_32); /* XXX what values for the timeouts? */ dsi_set_stop_state_counter(1000); @@ -2575,12 +2573,9 @@ static int dsi_proto_config(struct omap_dss_device *dssdev) dsi_write_reg(DSI_CTRL, r); dsi_vc_initial_config(0); - - /* set all vc targets to peripheral 0 */ - dsi.vc[0].dest_per = 0; - dsi.vc[1].dest_per = 0; - dsi.vc[2].dest_per = 0; - dsi.vc[3].dest_per = 0; + dsi_vc_initial_config(1); + dsi_vc_initial_config(2); + dsi_vc_initial_config(3); return 0; } @@ -2846,9 +2841,6 @@ static void dsi_update_screen_dispc(struct omap_dss_device *dssdev, if (bytespf % packet_payload) total_len += (bytespf % packet_payload) + 1; - if (0) - dsi_vc_print_status(1); - l = FLD_VAL(total_len, 23, 0); /* TE_SIZE */ dsi_write_reg(DSI_VC_TE(channel), l); @@ -3014,7 +3006,7 @@ static void dsi_handle_framedone(void) /* RX_FIFO_NOT_EMPTY */ if (REG_GET(DSI_VC_CTRL(channel), 20, 20)) { DSSERR("Received error during frame transfer:\n"); - dsi_vc_flush_receive_data(0); + dsi_vc_flush_receive_data(channel); } #ifdef CONFIG_OMAP2_DSS_FAKE_VSYNC @@ -3268,6 +3260,9 @@ static int dsi_display_init_dsi(struct omap_dss_device *dssdev) /* enable interface */ dsi_vc_enable(0, 1); + dsi_vc_enable(1, 1); + dsi_vc_enable(2, 1); + dsi_vc_enable(3, 1); dsi_if_enable(1); dsi_force_tx_stop_mode_io(); -- cgit v1.2.2 From 6eed73debf5840a42ebe9ea90958d2ce4a38c6b0 Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Fri, 5 Feb 2010 14:44:05 +0200 Subject: OMAP: DSS2: DSI: remove dsi_vc_print_status() It was not used. Signed-off-by: Tomi Valkeinen --- drivers/video/omap2/dss/dsi.c | 21 --------------------- 1 file changed, 21 deletions(-) (limited to 'drivers') diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c index 131bd53b6b6d..4b85ed202d50 100644 --- a/drivers/video/omap2/dss/dsi.c +++ b/drivers/video/omap2/dss/dsi.c @@ -1760,24 +1760,6 @@ static int dsi_force_tx_stop_mode_io(void) return 0; } -static void dsi_vc_print_status(int channel) -{ - u32 r; - - r = dsi_read_reg(DSI_VC_CTRL(channel)); - DSSDBG("vc %d: TX_FIFO_NOT_EMPTY %d, BTA_EN %d, VC_BUSY %d, " - "TX_FIFO_FULL %d, RX_FIFO_NOT_EMPTY %d, ", - channel, - FLD_GET(r, 5, 5), - FLD_GET(r, 6, 6), - FLD_GET(r, 15, 15), - FLD_GET(r, 16, 16), - FLD_GET(r, 20, 20)); - - r = dsi_read_reg(DSI_TX_FIFO_VC_EMPTINESS); - DSSDBG("EMPTINESS %d\n", (r >> (8 * channel)) & 0xff); -} - static int dsi_vc_enable(int channel, bool enable) { if (dsi.update_mode != OMAP_DSS_UPDATE_AUTO) @@ -2062,13 +2044,10 @@ static int dsi_vc_send_long(int channel, u8 data_type, u8 *data, u16 len, dsi_vc_write_long_header(channel, data_type, len, ecc); - /*dsi_vc_print_status(0); */ - p = data; for (i = 0; i < len >> 2; i++) { if (dsi.debug_write) DSSDBG("\tsending full packet %d\n", i); - /*dsi_vc_print_status(0); */ b1 = *p++; b2 = *p++; -- cgit v1.2.2 From e296264977f68ddf395b8f93f8e174930f88499a Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Tue, 1 Dec 2009 13:23:25 +0200 Subject: OMAP: DSS2: Check ctx loss count only when starting the first clock When OMAP PM layer is no-op/debug, the PM layer will increment context loss count with every call. This resulted DSS2 to restore context whenever a clock was enabled. This commit checks the context loss count only when the context actually could have been lost, ie. when enabling a clock when no clocks had been previously enabled. Signed-off-by: Tomi Valkeinen --- drivers/video/omap2/dss/core.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/video/omap2/dss/core.c b/drivers/video/omap2/dss/core.c index 5939da9cf021..72547dfc56b8 100644 --- a/drivers/video/omap2/dss/core.c +++ b/drivers/video/omap2/dss/core.c @@ -289,9 +289,11 @@ static void dss_clk_enable_no_ctx(enum dss_clock clks) void dss_clk_enable(enum dss_clock clks) { + bool check_ctx = core.num_clks_enabled == 0; + dss_clk_enable_no_ctx(clks); - if (cpu_is_omap34xx() && dss_need_ctx_restore()) + if (check_ctx && cpu_is_omap34xx() && dss_need_ctx_restore()) restore_all_ctx(); } -- cgit v1.2.2 From 088ef950dc0dd58d2f339e1616c9092fea923f06 Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Fri, 12 Feb 2010 12:26:47 -0800 Subject: omap2: Convert ARCH_OMAP24XX to ARCH_OMAP2 Convert ARCH_OMAP24XX to ARCH_OMAP2 Signed-off-by: Tony Lindgren --- drivers/char/hw_random/Kconfig | 2 +- drivers/mfd/Kconfig | 2 +- drivers/net/smc911x.h | 2 +- drivers/spi/Kconfig | 2 +- drivers/watchdog/Kconfig | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/char/hw_random/Kconfig b/drivers/char/hw_random/Kconfig index 87060266ef91..c0df30faa66a 100644 --- a/drivers/char/hw_random/Kconfig +++ b/drivers/char/hw_random/Kconfig @@ -114,7 +114,7 @@ config HW_RANDOM_IXP4XX config HW_RANDOM_OMAP tristate "OMAP Random Number Generator support" - depends on HW_RANDOM && (ARCH_OMAP16XX || ARCH_OMAP24XX) + depends on HW_RANDOM && (ARCH_OMAP16XX || ARCH_OMAP2) default HW_RANDOM ---help--- This driver provides kernel-side support for the Random Number diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig index 87829789243e..1380e1c44e4b 100644 --- a/drivers/mfd/Kconfig +++ b/drivers/mfd/Kconfig @@ -94,7 +94,7 @@ config TPS65010 config MENELAUS bool "Texas Instruments TWL92330/Menelaus PM chip" - depends on I2C=y && ARCH_OMAP24XX + depends on I2C=y && ARCH_OMAP2 help If you say yes here you get support for the Texas Instruments TWL92330/Menelaus Power Management chip. This include voltage diff --git a/drivers/net/smc911x.h b/drivers/net/smc911x.h index 05adb6a666cf..1477ff8f85f6 100644 --- a/drivers/net/smc911x.h +++ b/drivers/net/smc911x.h @@ -47,7 +47,7 @@ #define SMC_USE_32BIT 1 #define SMC_IRQ_SENSE IRQF_TRIGGER_LOW #define SMC_MEM_RESERVED 1 -#elif defined(CONFIG_ARCH_OMAP24XX) +#elif defined(CONFIG_ARCH_OMAP2) #define SMC_USE_16BIT 0 #define SMC_USE_32BIT 1 #define SMC_IRQ_SENSE IRQF_TRIGGER_LOW diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig index f55eb0107336..23bd252f3a44 100644 --- a/drivers/spi/Kconfig +++ b/drivers/spi/Kconfig @@ -164,7 +164,7 @@ config SPI_OMAP_UWIRE config SPI_OMAP24XX tristate "McSPI driver for OMAP24xx/OMAP34xx" - depends on ARCH_OMAP24XX || ARCH_OMAP34XX + depends on ARCH_OMAP2 || ARCH_OMAP34XX help SPI master controller for OMAP24xx/OMAP34xx Multichannel SPI (McSPI) modules. diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig index 050ee147592f..b45e2896ac87 100644 --- a/drivers/watchdog/Kconfig +++ b/drivers/watchdog/Kconfig @@ -194,7 +194,7 @@ config EP93XX_WATCHDOG config OMAP_WATCHDOG tristate "OMAP Watchdog" - depends on ARCH_OMAP16XX || ARCH_OMAP24XX || ARCH_OMAP34XX + depends on ARCH_OMAP16XX || ARCH_OMAP2 || ARCH_OMAP34XX help Support for TI OMAP1610/OMAP1710/OMAP2420/OMAP3430 watchdog. Say 'Y' here to enable the OMAP1610/OMAP1710/OMAP2420/OMAP3430 watchdog timer. -- cgit v1.2.2 From a8eb7ca0cbb41c9cd379b8d2a2a5efb503aa65e9 Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Fri, 12 Feb 2010 12:26:48 -0800 Subject: omap3: Replace ARCH_OMAP34XX with ARCH_OMAP3 Replace ARCH_OMAP34XX with ARCH_OMAP3 Signed-off-by: Tony Lindgren --- drivers/net/smc911x.h | 2 +- drivers/spi/Kconfig | 2 +- drivers/spi/omap2_mcspi.c | 2 +- drivers/usb/Kconfig | 2 +- drivers/usb/host/ehci-hcd.c | 2 +- drivers/usb/musb/Kconfig | 6 +++--- drivers/usb/musb/musb_core.c | 2 +- drivers/usb/musb/musb_core.h | 2 +- drivers/w1/masters/Kconfig | 2 +- drivers/watchdog/Kconfig | 2 +- 10 files changed, 12 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/net/smc911x.h b/drivers/net/smc911x.h index 1477ff8f85f6..3269292efecc 100644 --- a/drivers/net/smc911x.h +++ b/drivers/net/smc911x.h @@ -42,7 +42,7 @@ #define SMC_USE_16BIT 0 #define SMC_USE_32BIT 1 #define SMC_IRQ_SENSE IRQF_TRIGGER_LOW -#elif defined(CONFIG_ARCH_OMAP34XX) +#elif defined(CONFIG_ARCH_OMAP3) #define SMC_USE_16BIT 0 #define SMC_USE_32BIT 1 #define SMC_IRQ_SENSE IRQF_TRIGGER_LOW diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig index 23bd252f3a44..66c35d74a76b 100644 --- a/drivers/spi/Kconfig +++ b/drivers/spi/Kconfig @@ -164,7 +164,7 @@ config SPI_OMAP_UWIRE config SPI_OMAP24XX tristate "McSPI driver for OMAP24xx/OMAP34xx" - depends on ARCH_OMAP2 || ARCH_OMAP34XX + depends on ARCH_OMAP2 || ARCH_OMAP3 help SPI master controller for OMAP24xx/OMAP34xx Multichannel SPI (McSPI) modules. diff --git a/drivers/spi/omap2_mcspi.c b/drivers/spi/omap2_mcspi.c index bf5f95a19413..715c518b1b68 100644 --- a/drivers/spi/omap2_mcspi.c +++ b/drivers/spi/omap2_mcspi.c @@ -1014,7 +1014,7 @@ static u8 __initdata spi2_txdma_id[] = { OMAP24XX_DMA_SPI2_TX1, }; -#if defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP34XX) \ +#if defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP3) \ || defined(CONFIG_ARCH_OMAP4) static u8 __initdata spi3_rxdma_id[] = { OMAP24XX_DMA_SPI3_RX0, diff --git a/drivers/usb/Kconfig b/drivers/usb/Kconfig index 81aac7f4ca59..4f5bb5698f5d 100644 --- a/drivers/usb/Kconfig +++ b/drivers/usb/Kconfig @@ -61,7 +61,7 @@ config USB_ARCH_HAS_EHCI default y if ARCH_W90X900 default y if ARCH_AT91SAM9G45 default y if ARCH_MXC - default y if ARCH_OMAP34XX + default y if ARCH_OMAP3 default PCI # ARM SA1111 chips have a non-PCI based "OHCI-compatible" USB host interface. diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index 1ec3857f22e6..d8d6d3461d32 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c @@ -1118,7 +1118,7 @@ MODULE_LICENSE ("GPL"); #define PLATFORM_DRIVER ehci_hcd_au1xxx_driver #endif -#ifdef CONFIG_ARCH_OMAP34XX +#ifdef CONFIG_ARCH_OMAP3 #include "ehci-omap.c" #define PLATFORM_DRIVER ehci_hcd_omap_driver #endif diff --git a/drivers/usb/musb/Kconfig b/drivers/usb/musb/Kconfig index d9db86498022..b4c783c284ba 100644 --- a/drivers/usb/musb/Kconfig +++ b/drivers/usb/musb/Kconfig @@ -37,7 +37,7 @@ config USB_MUSB_SOC depends on USB_MUSB_HDRC default y if ARCH_DAVINCI default y if ARCH_OMAP2430 - default y if ARCH_OMAP34XX + default y if ARCH_OMAP3 default y if (BF54x && !BF544) default y if (BF52x && !BF522 && !BF523) @@ -48,7 +48,7 @@ comment "OMAP 243x high speed USB support" depends on USB_MUSB_HDRC && ARCH_OMAP2430 comment "OMAP 343x high speed USB support" - depends on USB_MUSB_HDRC && ARCH_OMAP34XX + depends on USB_MUSB_HDRC && ARCH_OMAP3 comment "Blackfin high speed USB Support" depends on USB_MUSB_HDRC && ((BF54x && !BF544) || (BF52x && !BF522 && !BF523)) @@ -153,7 +153,7 @@ config MUSB_PIO_ONLY config USB_INVENTRA_DMA bool depends on USB_MUSB_HDRC && !MUSB_PIO_ONLY - default ARCH_OMAP2430 || ARCH_OMAP34XX || BLACKFIN + default ARCH_OMAP2430 || ARCH_OMAP3 || BLACKFIN help Enable DMA transfers using Mentor's engine. diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c index 5eb9318cff77..738efd8063b5 100644 --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c @@ -1000,7 +1000,7 @@ static void musb_shutdown(struct platform_device *pdev) * more than selecting one of a bunch of predefined configurations. */ #if defined(CONFIG_USB_TUSB6010) || \ - defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP34XX) + defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP3) static ushort __initdata fifo_mode = 4; #else static ushort __initdata fifo_mode = 2; diff --git a/drivers/usb/musb/musb_core.h b/drivers/usb/musb/musb_core.h index 03d50909b078..5514c7ee85bd 100644 --- a/drivers/usb/musb/musb_core.h +++ b/drivers/usb/musb/musb_core.h @@ -562,7 +562,7 @@ extern void musb_hnp_stop(struct musb *musb); extern int musb_platform_set_mode(struct musb *musb, u8 musb_mode); #if defined(CONFIG_USB_TUSB6010) || defined(CONFIG_BLACKFIN) || \ - defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP34XX) + defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP3) extern void musb_platform_try_idle(struct musb *musb, unsigned long timeout); #else #define musb_platform_try_idle(x, y) do {} while (0) diff --git a/drivers/w1/masters/Kconfig b/drivers/w1/masters/Kconfig index 3195fb8b7d9a..80b3b123dd7f 100644 --- a/drivers/w1/masters/Kconfig +++ b/drivers/w1/masters/Kconfig @@ -60,7 +60,7 @@ config W1_MASTER_GPIO config HDQ_MASTER_OMAP tristate "OMAP HDQ driver" - depends on ARCH_OMAP2430 || ARCH_OMAP34XX + depends on ARCH_OMAP2430 || ARCH_OMAP3 help Say Y here if you want support for the 1-wire or HDQ Interface on an OMAP processor. diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig index b45e2896ac87..3da3f48720a7 100644 --- a/drivers/watchdog/Kconfig +++ b/drivers/watchdog/Kconfig @@ -194,7 +194,7 @@ config EP93XX_WATCHDOG config OMAP_WATCHDOG tristate "OMAP Watchdog" - depends on ARCH_OMAP16XX || ARCH_OMAP2 || ARCH_OMAP34XX + depends on ARCH_OMAP16XX || ARCH_OMAP2 || ARCH_OMAP3 help Support for TI OMAP1610/OMAP1710/OMAP2420/OMAP3430 watchdog. Say 'Y' here to enable the OMAP1610/OMAP1710/OMAP2420/OMAP3430 watchdog timer. -- cgit v1.2.2 From cc87edb173effdf74e680ee6d622a935ff0c1d6f Mon Sep 17 00:00:00 2001 From: Ladislav Michl Date: Mon, 15 Feb 2010 10:03:32 -0800 Subject: MTD: remove no longer used OMAP flash map All OMAP boards are now using physmap-flash. Cc: linux-mtd@lists.infradead.org Signed-off-by: Ladislav Michl Signed-off-by: Tony Lindgren --- drivers/mtd/maps/Kconfig | 9 --- drivers/mtd/maps/Makefile | 1 - drivers/mtd/maps/omap_nor.c | 188 -------------------------------------------- 3 files changed, 198 deletions(-) (limited to 'drivers') diff --git a/drivers/mtd/maps/Kconfig b/drivers/mtd/maps/Kconfig index 2de0cc823d60..9605cb87c746 100644 --- a/drivers/mtd/maps/Kconfig +++ b/drivers/mtd/maps/Kconfig @@ -428,15 +428,6 @@ config MTD_H720X This enables access to the flash chips on the Hynix evaluation boards. If you have such a board, say 'Y'. -config MTD_OMAP_NOR - tristate "TI OMAP board mappings" - depends on MTD_CFI && ARCH_OMAP - help - This enables access to the NOR flash chips on TI OMAP-based - boards defining flash platform devices and flash platform data. - These boards include the Innovator, H2, H3, OSK, Perseus2, and - more. If you have such a board, say 'Y'. - # This needs CFI or JEDEC, depending on the cards found. config MTD_PCI tristate "PCI MTD driver" diff --git a/drivers/mtd/maps/Makefile b/drivers/mtd/maps/Makefile index ce315214ff2b..faa9fef19585 100644 --- a/drivers/mtd/maps/Makefile +++ b/drivers/mtd/maps/Makefile @@ -55,7 +55,6 @@ obj-$(CONFIG_MTD_IXP2000) += ixp2000.o obj-$(CONFIG_MTD_WRSBC8260) += wr_sbc82xx_flash.o obj-$(CONFIG_MTD_DMV182) += dmv182.o obj-$(CONFIG_MTD_PLATRAM) += plat-ram.o -obj-$(CONFIG_MTD_OMAP_NOR) += omap_nor.o obj-$(CONFIG_MTD_INTEL_VR_NOR) += intel_vr_nor.o obj-$(CONFIG_MTD_BFIN_ASYNC) += bfin-async-flash.o obj-$(CONFIG_MTD_RBTX4939) += rbtx4939-flash.o diff --git a/drivers/mtd/maps/omap_nor.c b/drivers/mtd/maps/omap_nor.c index ead0b2fab670..e69de29bb2d1 100644 --- a/drivers/mtd/maps/omap_nor.c +++ b/drivers/mtd/maps/omap_nor.c @@ -1,188 +0,0 @@ -/* - * Flash memory support for various TI OMAP boards - * - * Copyright (C) 2001-2002 MontaVista Software Inc. - * Copyright (C) 2003-2004 Texas Instruments - * Copyright (C) 2004 Nokia Corporation - * - * Assembled using driver code copyright the companies above - * and written by David Brownell, Jian Zhang , - * Tony Lindgren and others. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN - * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * 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., - * 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include -#include -#include -#include - -#ifdef CONFIG_MTD_PARTITIONS -static const char *part_probes[] = { /* "RedBoot", */ "cmdlinepart", NULL }; -#endif - -struct omapflash_info { - struct mtd_partition *parts; - struct mtd_info *mtd; - struct map_info map; -}; - -static void omap_set_vpp(struct map_info *map, int enable) -{ - static int count; - u32 l; - - if (cpu_class_is_omap1()) { - if (enable) { - if (count++ == 0) { - l = omap_readl(EMIFS_CONFIG); - l |= OMAP_EMIFS_CONFIG_WP; - omap_writel(l, EMIFS_CONFIG); - } - } else { - if (count && (--count == 0)) { - l = omap_readl(EMIFS_CONFIG); - l &= ~OMAP_EMIFS_CONFIG_WP; - omap_writel(l, EMIFS_CONFIG); - } - } - } -} - -static int __init omapflash_probe(struct platform_device *pdev) -{ - int err; - struct omapflash_info *info; - struct flash_platform_data *pdata = pdev->dev.platform_data; - struct resource *res = pdev->resource; - unsigned long size = res->end - res->start + 1; - - info = kzalloc(sizeof(struct omapflash_info), GFP_KERNEL); - if (!info) - return -ENOMEM; - - if (!request_mem_region(res->start, size, "flash")) { - err = -EBUSY; - goto out_free_info; - } - - info->map.virt = ioremap(res->start, size); - if (!info->map.virt) { - err = -ENOMEM; - goto out_release_mem_region; - } - info->map.name = dev_name(&pdev->dev); - info->map.phys = res->start; - info->map.size = size; - info->map.bankwidth = pdata->width; - info->map.set_vpp = omap_set_vpp; - - simple_map_init(&info->map); - info->mtd = do_map_probe(pdata->map_name, &info->map); - if (!info->mtd) { - err = -EIO; - goto out_iounmap; - } - info->mtd->owner = THIS_MODULE; - - info->mtd->dev.parent = &pdev->dev; - -#ifdef CONFIG_MTD_PARTITIONS - err = parse_mtd_partitions(info->mtd, part_probes, &info->parts, 0); - if (err > 0) - add_mtd_partitions(info->mtd, info->parts, err); - else if (err <= 0 && pdata->parts) - add_mtd_partitions(info->mtd, pdata->parts, pdata->nr_parts); - else -#endif - add_mtd_device(info->mtd); - - platform_set_drvdata(pdev, info); - - return 0; - -out_iounmap: - iounmap(info->map.virt); -out_release_mem_region: - release_mem_region(res->start, size); -out_free_info: - kfree(info); - - return err; -} - -static int __exit omapflash_remove(struct platform_device *pdev) -{ - struct omapflash_info *info = platform_get_drvdata(pdev); - - platform_set_drvdata(pdev, NULL); - - if (info) { - if (info->parts) { - del_mtd_partitions(info->mtd); - kfree(info->parts); - } else - del_mtd_device(info->mtd); - map_destroy(info->mtd); - release_mem_region(info->map.phys, info->map.size); - iounmap((void __iomem *) info->map.virt); - kfree(info); - } - - return 0; -} - -static struct platform_driver omapflash_driver = { - .remove = __exit_p(omapflash_remove), - .driver = { - .name = "omapflash", - .owner = THIS_MODULE, - }, -}; - -static int __init omapflash_init(void) -{ - return platform_driver_probe(&omapflash_driver, omapflash_probe); -} - -static void __exit omapflash_exit(void) -{ - platform_driver_unregister(&omapflash_driver); -} - -module_init(omapflash_init); -module_exit(omapflash_exit); - -MODULE_LICENSE("GPL"); -MODULE_DESCRIPTION("MTD NOR map driver for TI OMAP boards"); -MODULE_ALIAS("platform:omapflash"); -- cgit v1.2.2 From 2f70a1e93657bea0baa7d449aa49e44a08582dc8 Mon Sep 17 00:00:00 2001 From: Vimal Singh Date: Mon, 15 Feb 2010 10:03:33 -0800 Subject: omap2/3/4: Introducing 'gpmc-nand.c' for GPMC specific NAND init Introducing 'gpmc-nand.c' for GPMC specific NAND init. For example: GPMC timing parameters and all. This patch also migrates gpmc related calls from 'nand/omap2.c' to 'gpmc-nand.c'. Signed-off-by: Vimal Singh Signed-off-by: Tony Lindgren --- drivers/mtd/nand/omap2.c | 35 ++++------------------------------- 1 file changed, 4 insertions(+), 31 deletions(-) (limited to 'drivers') diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c index 1bb799f0125c..26aec0080184 100644 --- a/drivers/mtd/nand/omap2.c +++ b/drivers/mtd/nand/omap2.c @@ -30,12 +30,8 @@ #define DRIVER_NAME "omap2-nand" -/* size (4 KiB) for IO mapping */ -#define NAND_IO_SIZE SZ_4K - #define NAND_WP_OFF 0 #define NAND_WP_BIT 0x00000010 -#define WR_RD_PIN_MONITORING 0x00600000 #define GPMC_BUF_FULL 0x00000001 #define GPMC_BUF_EMPTY 0x00000000 @@ -882,8 +878,6 @@ static int __devinit omap_nand_probe(struct platform_device *pdev) struct omap_nand_info *info; struct omap_nand_platform_data *pdata; int err; - unsigned long val; - pdata = pdev->dev.platform_data; if (pdata == NULL) { @@ -905,28 +899,14 @@ static int __devinit omap_nand_probe(struct platform_device *pdev) info->gpmc_cs = pdata->cs; info->gpmc_baseaddr = pdata->gpmc_baseaddr; info->gpmc_cs_baseaddr = pdata->gpmc_cs_baseaddr; + info->phys_base = pdata->phys_base; info->mtd.priv = &info->nand; info->mtd.name = dev_name(&pdev->dev); info->mtd.owner = THIS_MODULE; - err = gpmc_cs_request(info->gpmc_cs, NAND_IO_SIZE, &info->phys_base); - if (err < 0) { - dev_err(&pdev->dev, "Cannot request GPMC CS\n"); - goto out_free_info; - } - - /* Enable RD PIN Monitoring Reg */ - if (pdata->dev_ready) { - val = gpmc_cs_read_reg(info->gpmc_cs, GPMC_CS_CONFIG1); - val |= WR_RD_PIN_MONITORING; - gpmc_cs_write_reg(info->gpmc_cs, GPMC_CS_CONFIG1, val); - } - - val = gpmc_cs_read_reg(info->gpmc_cs, GPMC_CS_CONFIG7); - val &= ~(0xf << 8); - val |= (0xc & 0xf) << 8; - gpmc_cs_write_reg(info->gpmc_cs, GPMC_CS_CONFIG7, val); + info->nand.options |= pdata->devsize ? NAND_BUSWIDTH_16 : 0; + info->nand.options |= NAND_SKIP_BBTSCAN; /* NAND write protect off */ omap_nand_wp(&info->mtd, NAND_WP_OFF); @@ -934,7 +914,7 @@ static int __devinit omap_nand_probe(struct platform_device *pdev) if (!request_mem_region(info->phys_base, NAND_IO_SIZE, pdev->dev.driver->name)) { err = -EBUSY; - goto out_free_cs; + goto out_free_info; } info->nand.IO_ADDR_R = ioremap(info->phys_base, NAND_IO_SIZE); @@ -963,11 +943,6 @@ static int __devinit omap_nand_probe(struct platform_device *pdev) info->nand.chip_delay = 50; } - info->nand.options |= NAND_SKIP_BBTSCAN; - if ((gpmc_cs_read_reg(info->gpmc_cs, GPMC_CS_CONFIG1) & 0x3000) - == 0x1000) - info->nand.options |= NAND_BUSWIDTH_16; - if (use_prefetch) { /* copy the virtual address of nand base for fifo access */ info->nand_pref_fifo_add = info->nand.IO_ADDR_R; @@ -1043,8 +1018,6 @@ static int __devinit omap_nand_probe(struct platform_device *pdev) out_release_mem_region: release_mem_region(info->phys_base, NAND_IO_SIZE); -out_free_cs: - gpmc_cs_free(info->gpmc_cs); out_free_info: kfree(info); -- cgit v1.2.2 From db0fefc5119e2cfaa8f57565331e0abe47f0801e Mon Sep 17 00:00:00 2001 From: Adrian Hunter Date: Mon, 15 Feb 2010 10:03:34 -0800 Subject: omap_hsmmc: Move gpio and regulator control from board file This patch moves the setup code for GPIO's and Voltage Regulators from the board file mmc-twl4030.c to the driver omap_hsmmc.c. PBIAS and other system control configuration remains in the board file. Moving GPIO code to the driver makes the board initialisation code independent of when GPIO's are defined. That makes the board initialisation now entirely independent of its original twl4030 roots. Moving Voltage Regulator code to the driver allows for further development of regulator support in the core MMC code. It also permits the MMC core to be compiled as a module, because the board code no longer calls MMC core functions. Signed-off-by: Adrian Hunter Signed-off-by: Tony Lindgren --- drivers/mmc/host/omap_hsmmc.c | 352 ++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 339 insertions(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c index 4b2322518909..2c5e15d9f864 100644 --- a/drivers/mmc/host/omap_hsmmc.c +++ b/drivers/mmc/host/omap_hsmmc.c @@ -30,6 +30,8 @@ #include #include #include +#include +#include #include #include #include @@ -146,6 +148,15 @@ struct omap_hsmmc_host { struct clk *fclk; struct clk *iclk; struct clk *dbclk; + /* + * vcc == configured supply + * vcc_aux == optional + * - MMC1, supply for DAT4..DAT7 + * - MMC2/MMC2, external level shifter voltage supply, for + * chip (SDIO, eMMC, etc) or transceiver (MMC2 only) + */ + struct regulator *vcc; + struct regulator *vcc_aux; struct semaphore sem; struct work_struct mmc_carddetect_work; void __iomem *base; @@ -171,10 +182,308 @@ struct omap_hsmmc_host { int vdd; int protect_card; int reqs_blocked; + int use_reg; struct omap_mmc_platform_data *pdata; }; +static int omap_hsmmc_card_detect(struct device *dev, int slot) +{ + struct omap_mmc_platform_data *mmc = dev->platform_data; + + /* NOTE: assumes card detect signal is active-low */ + return !gpio_get_value_cansleep(mmc->slots[0].switch_pin); +} + +static int omap_hsmmc_get_wp(struct device *dev, int slot) +{ + struct omap_mmc_platform_data *mmc = dev->platform_data; + + /* NOTE: assumes write protect signal is active-high */ + return gpio_get_value_cansleep(mmc->slots[0].gpio_wp); +} + +static int omap_hsmmc_get_cover_state(struct device *dev, int slot) +{ + struct omap_mmc_platform_data *mmc = dev->platform_data; + + /* NOTE: assumes card detect signal is active-low */ + return !gpio_get_value_cansleep(mmc->slots[0].switch_pin); +} + +#ifdef CONFIG_PM + +static int omap_hsmmc_suspend_cdirq(struct device *dev, int slot) +{ + struct omap_mmc_platform_data *mmc = dev->platform_data; + + disable_irq(mmc->slots[0].card_detect_irq); + return 0; +} + +static int omap_hsmmc_resume_cdirq(struct device *dev, int slot) +{ + struct omap_mmc_platform_data *mmc = dev->platform_data; + + enable_irq(mmc->slots[0].card_detect_irq); + return 0; +} + +#else + +#define omap_hsmmc_suspend_cdirq NULL +#define omap_hsmmc_resume_cdirq NULL + +#endif + +static int omap_hsmmc_1_set_power(struct device *dev, int slot, int power_on, + int vdd) +{ + struct omap_hsmmc_host *host = + platform_get_drvdata(to_platform_device(dev)); + int ret; + + if (mmc_slot(host).before_set_reg) + mmc_slot(host).before_set_reg(dev, slot, power_on, vdd); + + if (power_on) + ret = mmc_regulator_set_ocr(host->vcc, vdd); + else + ret = mmc_regulator_set_ocr(host->vcc, 0); + + if (mmc_slot(host).after_set_reg) + mmc_slot(host).after_set_reg(dev, slot, power_on, vdd); + + return ret; +} + +static int omap_hsmmc_23_set_power(struct device *dev, int slot, int power_on, + int vdd) +{ + struct omap_hsmmc_host *host = + platform_get_drvdata(to_platform_device(dev)); + int ret = 0; + + /* + * If we don't see a Vcc regulator, assume it's a fixed + * voltage always-on regulator. + */ + if (!host->vcc) + return 0; + + if (mmc_slot(host).before_set_reg) + mmc_slot(host).before_set_reg(dev, slot, power_on, vdd); + + /* + * Assume Vcc regulator is used only to power the card ... OMAP + * VDDS is used to power the pins, optionally with a transceiver to + * support cards using voltages other than VDDS (1.8V nominal). When a + * transceiver is used, DAT3..7 are muxed as transceiver control pins. + * + * In some cases this regulator won't support enable/disable; + * e.g. it's a fixed rail for a WLAN chip. + * + * In other cases vcc_aux switches interface power. Example, for + * eMMC cards it represents VccQ. Sometimes transceivers or SDIO + * chips/cards need an interface voltage rail too. + */ + if (power_on) { + ret = mmc_regulator_set_ocr(host->vcc, vdd); + /* Enable interface voltage rail, if needed */ + if (ret == 0 && host->vcc_aux) { + ret = regulator_enable(host->vcc_aux); + if (ret < 0) + ret = mmc_regulator_set_ocr(host->vcc, 0); + } + } else { + if (host->vcc_aux) { + ret = regulator_is_enabled(host->vcc_aux); + if (ret > 0) + ret = regulator_disable(host->vcc_aux); + } + if (ret == 0) + ret = mmc_regulator_set_ocr(host->vcc, 0); + } + + if (mmc_slot(host).after_set_reg) + mmc_slot(host).after_set_reg(dev, slot, power_on, vdd); + + return ret; +} + +static int omap_hsmmc_1_set_sleep(struct device *dev, int slot, int sleep, + int vdd, int cardsleep) +{ + struct omap_hsmmc_host *host = + platform_get_drvdata(to_platform_device(dev)); + int mode = sleep ? REGULATOR_MODE_STANDBY : REGULATOR_MODE_NORMAL; + + return regulator_set_mode(host->vcc, mode); +} + +static int omap_hsmmc_23_set_sleep(struct device *dev, int slot, int sleep, + int vdd, int cardsleep) +{ + struct omap_hsmmc_host *host = + platform_get_drvdata(to_platform_device(dev)); + int err, mode; + + /* + * If we don't see a Vcc regulator, assume it's a fixed + * voltage always-on regulator. + */ + if (!host->vcc) + return 0; + + mode = sleep ? REGULATOR_MODE_STANDBY : REGULATOR_MODE_NORMAL; + + if (!host->vcc_aux) + return regulator_set_mode(host->vcc, mode); + + if (cardsleep) { + /* VCC can be turned off if card is asleep */ + if (sleep) + err = mmc_regulator_set_ocr(host->vcc, 0); + else + err = mmc_regulator_set_ocr(host->vcc, vdd); + } else + err = regulator_set_mode(host->vcc, mode); + if (err) + return err; + return regulator_set_mode(host->vcc_aux, mode); +} + +static int omap_hsmmc_gpio_init(struct omap_mmc_platform_data *pdata) +{ + int ret; + + if (gpio_is_valid(pdata->slots[0].switch_pin)) { + pdata->suspend = omap_hsmmc_suspend_cdirq; + pdata->resume = omap_hsmmc_resume_cdirq; + if (pdata->slots[0].cover) + pdata->slots[0].get_cover_state = + omap_hsmmc_get_cover_state; + else + pdata->slots[0].card_detect = omap_hsmmc_card_detect; + pdata->slots[0].card_detect_irq = + gpio_to_irq(pdata->slots[0].switch_pin); + ret = gpio_request(pdata->slots[0].switch_pin, "mmc_cd"); + if (ret) + return ret; + ret = gpio_direction_input(pdata->slots[0].switch_pin); + if (ret) + goto err_free_sp; + } else + pdata->slots[0].switch_pin = -EINVAL; + + if (gpio_is_valid(pdata->slots[0].gpio_wp)) { + pdata->slots[0].get_ro = omap_hsmmc_get_wp; + ret = gpio_request(pdata->slots[0].gpio_wp, "mmc_wp"); + if (ret) + goto err_free_cd; + ret = gpio_direction_input(pdata->slots[0].gpio_wp); + if (ret) + goto err_free_wp; + } else + pdata->slots[0].gpio_wp = -EINVAL; + + return 0; + +err_free_wp: + gpio_free(pdata->slots[0].gpio_wp); +err_free_cd: + if (gpio_is_valid(pdata->slots[0].switch_pin)) +err_free_sp: + gpio_free(pdata->slots[0].switch_pin); + return ret; +} + +static void omap_hsmmc_gpio_free(struct omap_mmc_platform_data *pdata) +{ + if (gpio_is_valid(pdata->slots[0].gpio_wp)) + gpio_free(pdata->slots[0].gpio_wp); + if (gpio_is_valid(pdata->slots[0].switch_pin)) + gpio_free(pdata->slots[0].switch_pin); +} + +static int omap_hsmmc_reg_get(struct omap_hsmmc_host *host) +{ + struct regulator *reg; + int ret = 0; + + switch (host->id) { + case OMAP_MMC1_DEVID: + /* On-chip level shifting via PBIAS0/PBIAS1 */ + mmc_slot(host).set_power = omap_hsmmc_1_set_power; + mmc_slot(host).set_sleep = omap_hsmmc_1_set_sleep; + break; + case OMAP_MMC2_DEVID: + case OMAP_MMC3_DEVID: + /* Off-chip level shifting, or none */ + mmc_slot(host).set_power = omap_hsmmc_23_set_power; + mmc_slot(host).set_sleep = omap_hsmmc_23_set_sleep; + break; + default: + pr_err("MMC%d configuration not supported!\n", host->id); + return -EINVAL; + } + + reg = regulator_get(host->dev, "vmmc"); + if (IS_ERR(reg)) { + dev_dbg(host->dev, "vmmc regulator missing\n"); + /* + * HACK: until fixed.c regulator is usable, + * we don't require a main regulator + * for MMC2 or MMC3 + */ + if (host->id == OMAP_MMC1_DEVID) { + ret = PTR_ERR(reg); + goto err; + } + } else { + host->vcc = reg; + mmc_slot(host).ocr_mask = mmc_regulator_get_ocrmask(reg); + + /* Allow an aux regulator */ + reg = regulator_get(host->dev, "vmmc_aux"); + host->vcc_aux = IS_ERR(reg) ? NULL : reg; + + /* + * UGLY HACK: workaround regulator framework bugs. + * When the bootloader leaves a supply active, it's + * initialized with zero usecount ... and we can't + * disable it without first enabling it. Until the + * framework is fixed, we need a workaround like this + * (which is safe for MMC, but not in general). + */ + if (regulator_is_enabled(host->vcc) > 0) { + regulator_enable(host->vcc); + regulator_disable(host->vcc); + } + if (host->vcc_aux) { + if (regulator_is_enabled(reg) > 0) { + regulator_enable(reg); + regulator_disable(reg); + } + } + } + + return 0; + +err: + mmc_slot(host).set_power = NULL; + mmc_slot(host).set_sleep = NULL; + return ret; +} + +static void omap_hsmmc_reg_put(struct omap_hsmmc_host *host) +{ + regulator_put(host->vcc); + regulator_put(host->vcc_aux); + mmc_slot(host).set_power = NULL; + mmc_slot(host).set_sleep = NULL; +} + /* * Stop clock to the card */ @@ -835,7 +1144,7 @@ static void omap_hsmmc_detect(struct work_struct *work) sysfs_notify(&host->mmc->class_dev.kobj, NULL, "cover_switch"); if (slot->card_detect) - carddetect = slot->card_detect(slot->card_detect_irq); + carddetect = slot->card_detect(host->dev, host->slot_id); else { omap_hsmmc_protect_card(host); carddetect = -ENOSYS; @@ -1242,7 +1551,7 @@ static int omap_hsmmc_get_cd(struct mmc_host *mmc) if (!mmc_slot(host).card_detect) return -ENOSYS; - return mmc_slot(host).card_detect(mmc_slot(host).card_detect_irq); + return mmc_slot(host).card_detect(host->dev, host->slot_id); } static int omap_hsmmc_get_ro(struct mmc_host *mmc) @@ -1616,7 +1925,7 @@ static int __init omap_hsmmc_probe(struct platform_device *pdev) struct mmc_host *mmc; struct omap_hsmmc_host *host = NULL; struct resource *res; - int ret = 0, irq; + int ret, irq; if (pdata == NULL) { dev_err(&pdev->dev, "Platform Data is missing\n"); @@ -1638,10 +1947,14 @@ static int __init omap_hsmmc_probe(struct platform_device *pdev) if (res == NULL) return -EBUSY; + ret = omap_hsmmc_gpio_init(pdata); + if (ret) + goto err; + mmc = mmc_alloc_host(sizeof(struct omap_hsmmc_host), &pdev->dev); if (!mmc) { ret = -ENOMEM; - goto err; + goto err_alloc; } host = mmc_priv(mmc); @@ -1781,7 +2094,6 @@ static int __init omap_hsmmc_probe(struct platform_device *pdev) goto err_irq; } - /* initialize power supplies, gpios, etc */ if (pdata->init != NULL) { if (pdata->init(&pdev->dev) != 0) { dev_dbg(mmc_dev(host->mmc), @@ -1789,6 +2101,14 @@ static int __init omap_hsmmc_probe(struct platform_device *pdev) goto err_irq_cd_init; } } + + if (!mmc_slot(host).set_power) { + ret = omap_hsmmc_reg_get(host); + if (ret) + goto err_reg; + host->use_reg = 1; + } + mmc->ocr_avail = mmc_slot(host).ocr_mask; /* Request IRQ for card detect */ @@ -1823,19 +2143,22 @@ static int __init omap_hsmmc_probe(struct platform_device *pdev) ret = device_create_file(&mmc->class_dev, &dev_attr_cover_switch); if (ret < 0) - goto err_cover_switch; + goto err_slot_name; } omap_hsmmc_debugfs(mmc); return 0; -err_cover_switch: - device_remove_file(&mmc->class_dev, &dev_attr_cover_switch); err_slot_name: mmc_remove_host(mmc); -err_irq_cd: free_irq(mmc_slot(host).card_detect_irq, host); +err_irq_cd: + if (host->use_reg) + omap_hsmmc_reg_put(host); +err_reg: + if (host->pdata->cleanup) + host->pdata->cleanup(&pdev->dev); err_irq_cd_init: free_irq(host->irq, host); err_irq: @@ -1847,14 +2170,14 @@ err_irq: clk_disable(host->dbclk); clk_put(host->dbclk); } - err1: iounmap(host->base); + platform_set_drvdata(pdev, NULL); + mmc_free_host(mmc); +err_alloc: + omap_hsmmc_gpio_free(pdata); err: - dev_dbg(mmc_dev(host->mmc), "Probe Failed\n"); release_mem_region(res->start, res->end - res->start + 1); - if (host) - mmc_free_host(mmc); return ret; } @@ -1866,6 +2189,8 @@ static int omap_hsmmc_remove(struct platform_device *pdev) if (host) { mmc_host_enable(host->mmc); mmc_remove_host(host->mmc); + if (host->use_reg) + omap_hsmmc_reg_put(host); if (host->pdata->cleanup) host->pdata->cleanup(&pdev->dev); free_irq(host->irq, host); @@ -1884,6 +2209,7 @@ static int omap_hsmmc_remove(struct platform_device *pdev) mmc_free_host(host->mmc); iounmap(host->base); + omap_hsmmc_gpio_free(pdev->dev.platform_data); } res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -- cgit v1.2.2 From 1df58db8a25ec7656005f1dd161a9ede044551b7 Mon Sep 17 00:00:00 2001 From: Adrian Hunter Date: Mon, 15 Feb 2010 10:03:34 -0800 Subject: omap_hsmmc: Allow for power saving without going off An eMMC may be always powered on, so that the lowest power saving state possible is sleeping. Add a field to the platform data to indicate that. Signed-off-by: Adrian Hunter Signed-off-by: Tony Lindgren --- drivers/mmc/host/omap_hsmmc.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'drivers') diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c index 2c5e15d9f864..e15d0f42569d 100644 --- a/drivers/mmc/host/omap_hsmmc.c +++ b/drivers/mmc/host/omap_hsmmc.c @@ -1656,6 +1656,9 @@ static int omap_hsmmc_disabled_to_sleep(struct omap_hsmmc_host *host) dev_dbg(mmc_dev(host->mmc), "DISABLED -> %s\n", host->dpm_state == CARDSLEEP ? "CARDSLEEP" : "REGSLEEP"); + if (mmc_slot(host).no_off) + return 0; + if ((host->mmc->caps & MMC_CAP_NONREMOVABLE) || mmc_slot(host).card_detect || (mmc_slot(host).get_cover_state && @@ -1671,6 +1674,9 @@ static int omap_hsmmc_sleep_to_off(struct omap_hsmmc_host *host) if (!mmc_try_claim_host(host->mmc)) return 0; + if (mmc_slot(host).no_off) + return 0; + if (!((host->mmc->caps & MMC_CAP_NONREMOVABLE) || mmc_slot(host).card_detect || (mmc_slot(host).get_cover_state && -- cgit v1.2.2 From 4380eea266940a82e5b8edd5c16ce0289679bcfe Mon Sep 17 00:00:00 2001 From: Adrian Hunter Date: Mon, 15 Feb 2010 10:03:34 -0800 Subject: omap_hsmmc: Fix disable timeouts Disable timeouts are in msecs not jiffies. Signed-off-by: Adrian Hunter Signed-off-by: Tony Lindgren --- drivers/mmc/host/omap_hsmmc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c index e15d0f42569d..cb94044f3fc4 100644 --- a/drivers/mmc/host/omap_hsmmc.c +++ b/drivers/mmc/host/omap_hsmmc.c @@ -1620,7 +1620,7 @@ static int omap_hsmmc_enabled_to_disabled(struct omap_hsmmc_host *host) if (host->power_mode == MMC_POWER_OFF) return 0; - return msecs_to_jiffies(OMAP_MMC_SLEEP_TIMEOUT); + return OMAP_MMC_SLEEP_TIMEOUT; } /* Handler for [DISABLED -> REGSLEEP / CARDSLEEP] transition */ @@ -1663,7 +1663,7 @@ static int omap_hsmmc_disabled_to_sleep(struct omap_hsmmc_host *host) mmc_slot(host).card_detect || (mmc_slot(host).get_cover_state && mmc_slot(host).get_cover_state(host->dev, host->slot_id))) - return msecs_to_jiffies(OMAP_MMC_OFF_TIMEOUT); + return OMAP_MMC_OFF_TIMEOUT; return 0; } -- cgit v1.2.2 From 6da20c89af64b75302399369a90b9d50c1a87665 Mon Sep 17 00:00:00 2001 From: Adrian Hunter Date: Mon, 15 Feb 2010 10:03:34 -0800 Subject: omap_hsmmc: Ensure regulator enable / disable are paired Stop using 'regulator_is_enabled()' and just pair enables with disables so that the regulator reference counts can work correctly. Signed-off-by: Adrian Hunter Signed-off-by: Tony Lindgren --- drivers/mmc/host/omap_hsmmc.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c index cb94044f3fc4..d2fad587f371 100644 --- a/drivers/mmc/host/omap_hsmmc.c +++ b/drivers/mmc/host/omap_hsmmc.c @@ -296,11 +296,8 @@ static int omap_hsmmc_23_set_power(struct device *dev, int slot, int power_on, ret = mmc_regulator_set_ocr(host->vcc, 0); } } else { - if (host->vcc_aux) { - ret = regulator_is_enabled(host->vcc_aux); - if (ret > 0) - ret = regulator_disable(host->vcc_aux); - } + if (host->vcc_aux) + ret = regulator_disable(host->vcc_aux); if (ret == 0) ret = mmc_regulator_set_ocr(host->vcc, 0); } @@ -1975,7 +1972,7 @@ static int __init omap_hsmmc_probe(struct platform_device *pdev) host->slot_id = 0; host->mapbase = res->start; host->base = ioremap(host->mapbase, SZ_4K); - host->power_mode = -1; + host->power_mode = MMC_POWER_OFF; platform_set_drvdata(pdev, host); INIT_WORK(&host->mmc_carddetect_work, omap_hsmmc_detect); -- cgit v1.2.2 From e0eb2424469ec2333885672d3db8bd07d322455d Mon Sep 17 00:00:00 2001 From: Adrian Hunter Date: Mon, 15 Feb 2010 10:03:34 -0800 Subject: omap_hsmmc: Allow for a shared VccQ EMMC can have two voltage supplies, Vcc and VccQ which are implemented in the code as consumer supplies vmmc and vmmc_aux. If the regulator that supplies vmmc_aux is shared with other consumers, then sending it to sleep will disrupt those consumers. However, the TWL4030-family regulators may have OFF remapped to SLEEP, in which case 'regulator_disable()' will put the regulator to sleep only when all consumers are disabled - which is the desired behaviour. This patch adds a platform data field to allow that option. Signed-off-by: Adrian Hunter Signed-off-by: Tony Lindgren --- drivers/mmc/host/omap_hsmmc.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c index d2fad587f371..af374771bed0 100644 --- a/drivers/mmc/host/omap_hsmmc.c +++ b/drivers/mmc/host/omap_hsmmc.c @@ -347,7 +347,14 @@ static int omap_hsmmc_23_set_sleep(struct device *dev, int slot, int sleep, err = regulator_set_mode(host->vcc, mode); if (err) return err; - return regulator_set_mode(host->vcc_aux, mode); + + if (!mmc_slot(host).vcc_aux_disable_is_sleep) + return regulator_set_mode(host->vcc_aux, mode); + + if (sleep) + return regulator_disable(host->vcc_aux); + else + return regulator_enable(host->vcc_aux); } static int omap_hsmmc_gpio_init(struct omap_mmc_platform_data *pdata) @@ -1982,6 +1989,13 @@ static int __init omap_hsmmc_probe(struct platform_device *pdev) else mmc->ops = &omap_hsmmc_ops; + /* + * If regulator_disable can only put vcc_aux to sleep then there is + * no off state. + */ + if (mmc_slot(host).vcc_aux_disable_is_sleep) + mmc_slot(host).no_off = 1; + mmc->f_min = 400000; mmc->f_max = 52000000; -- cgit v1.2.2 From b702b1060ab1c29ac08b904a0c188c61cda880eb Mon Sep 17 00:00:00 2001 From: Adrian Hunter Date: Mon, 15 Feb 2010 10:03:35 -0800 Subject: omap_hsmmc: allow compile without regulator framework It is still possible to use the omap_hsmmc module without the regulator framework. Accordingly, ifdef out regulator-specific functions. Signed-off-by: Adrian Hunter Signed-off-by: Tony Lindgren --- drivers/mmc/host/omap_hsmmc.c | 133 +++++++++++++++++++++++++----------------- 1 file changed, 79 insertions(+), 54 deletions(-) (limited to 'drivers') diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c index af374771bed0..83f0affadcae 100644 --- a/drivers/mmc/host/omap_hsmmc.c +++ b/drivers/mmc/host/omap_hsmmc.c @@ -236,6 +236,8 @@ static int omap_hsmmc_resume_cdirq(struct device *dev, int slot) #endif +#ifdef CONFIG_REGULATOR + static int omap_hsmmc_1_set_power(struct device *dev, int slot, int power_on, int vdd) { @@ -357,59 +359,6 @@ static int omap_hsmmc_23_set_sleep(struct device *dev, int slot, int sleep, return regulator_enable(host->vcc_aux); } -static int omap_hsmmc_gpio_init(struct omap_mmc_platform_data *pdata) -{ - int ret; - - if (gpio_is_valid(pdata->slots[0].switch_pin)) { - pdata->suspend = omap_hsmmc_suspend_cdirq; - pdata->resume = omap_hsmmc_resume_cdirq; - if (pdata->slots[0].cover) - pdata->slots[0].get_cover_state = - omap_hsmmc_get_cover_state; - else - pdata->slots[0].card_detect = omap_hsmmc_card_detect; - pdata->slots[0].card_detect_irq = - gpio_to_irq(pdata->slots[0].switch_pin); - ret = gpio_request(pdata->slots[0].switch_pin, "mmc_cd"); - if (ret) - return ret; - ret = gpio_direction_input(pdata->slots[0].switch_pin); - if (ret) - goto err_free_sp; - } else - pdata->slots[0].switch_pin = -EINVAL; - - if (gpio_is_valid(pdata->slots[0].gpio_wp)) { - pdata->slots[0].get_ro = omap_hsmmc_get_wp; - ret = gpio_request(pdata->slots[0].gpio_wp, "mmc_wp"); - if (ret) - goto err_free_cd; - ret = gpio_direction_input(pdata->slots[0].gpio_wp); - if (ret) - goto err_free_wp; - } else - pdata->slots[0].gpio_wp = -EINVAL; - - return 0; - -err_free_wp: - gpio_free(pdata->slots[0].gpio_wp); -err_free_cd: - if (gpio_is_valid(pdata->slots[0].switch_pin)) -err_free_sp: - gpio_free(pdata->slots[0].switch_pin); - return ret; -} - -static void omap_hsmmc_gpio_free(struct omap_mmc_platform_data *pdata) -{ - if (gpio_is_valid(pdata->slots[0].gpio_wp)) - gpio_free(pdata->slots[0].gpio_wp); - if (gpio_is_valid(pdata->slots[0].switch_pin)) - gpio_free(pdata->slots[0].switch_pin); -} - static int omap_hsmmc_reg_get(struct omap_hsmmc_host *host) { struct regulator *reg; @@ -488,6 +437,82 @@ static void omap_hsmmc_reg_put(struct omap_hsmmc_host *host) mmc_slot(host).set_sleep = NULL; } +static inline int omap_hsmmc_have_reg(void) +{ + return 1; +} + +#else + +static inline int omap_hsmmc_reg_get(struct omap_hsmmc_host *host) +{ + return -EINVAL; +} + +static inline void omap_hsmmc_reg_put(struct omap_hsmmc_host *host) +{ +} + +static inline int omap_hsmmc_have_reg(void) +{ + return 0; +} + +#endif + +static int omap_hsmmc_gpio_init(struct omap_mmc_platform_data *pdata) +{ + int ret; + + if (gpio_is_valid(pdata->slots[0].switch_pin)) { + pdata->suspend = omap_hsmmc_suspend_cdirq; + pdata->resume = omap_hsmmc_resume_cdirq; + if (pdata->slots[0].cover) + pdata->slots[0].get_cover_state = + omap_hsmmc_get_cover_state; + else + pdata->slots[0].card_detect = omap_hsmmc_card_detect; + pdata->slots[0].card_detect_irq = + gpio_to_irq(pdata->slots[0].switch_pin); + ret = gpio_request(pdata->slots[0].switch_pin, "mmc_cd"); + if (ret) + return ret; + ret = gpio_direction_input(pdata->slots[0].switch_pin); + if (ret) + goto err_free_sp; + } else + pdata->slots[0].switch_pin = -EINVAL; + + if (gpio_is_valid(pdata->slots[0].gpio_wp)) { + pdata->slots[0].get_ro = omap_hsmmc_get_wp; + ret = gpio_request(pdata->slots[0].gpio_wp, "mmc_wp"); + if (ret) + goto err_free_cd; + ret = gpio_direction_input(pdata->slots[0].gpio_wp); + if (ret) + goto err_free_wp; + } else + pdata->slots[0].gpio_wp = -EINVAL; + + return 0; + +err_free_wp: + gpio_free(pdata->slots[0].gpio_wp); +err_free_cd: + if (gpio_is_valid(pdata->slots[0].switch_pin)) +err_free_sp: + gpio_free(pdata->slots[0].switch_pin); + return ret; +} + +static void omap_hsmmc_gpio_free(struct omap_mmc_platform_data *pdata) +{ + if (gpio_is_valid(pdata->slots[0].gpio_wp)) + gpio_free(pdata->slots[0].gpio_wp); + if (gpio_is_valid(pdata->slots[0].switch_pin)) + gpio_free(pdata->slots[0].switch_pin); +} + /* * Stop clock to the card */ @@ -2119,7 +2144,7 @@ static int __init omap_hsmmc_probe(struct platform_device *pdev) } } - if (!mmc_slot(host).set_power) { + if (omap_hsmmc_have_reg() && !mmc_slot(host).set_power) { ret = omap_hsmmc_reg_get(host); if (ret) goto err_reg; -- cgit v1.2.2 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') 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.2 From e020f9af6d8311cd935217219f49175e161be100 Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Wed, 17 Feb 2010 13:36:48 +0200 Subject: OMAP: DSS2: remove sub-panel system The system to allow panel drivers to exists as attached to ctrl drivers did never work very well. It is not useed, and this patch removes it to make the driver cleaner. For now, controller drivers need to include also the panel driver code. In the future a proper mechanism for this should be developed, perhaps by creating busses for controllers. Signed-off-by: Tomi Valkeinen --- drivers/video/omap2/dss/core.c | 35 +++-------------------------------- drivers/video/omap2/dss/display.c | 32 ++------------------------------ 2 files changed, 5 insertions(+), 62 deletions(-) (limited to 'drivers') diff --git a/drivers/video/omap2/dss/core.c b/drivers/video/omap2/dss/core.c index 72547dfc56b8..967cbda1fd72 100644 --- a/drivers/video/omap2/dss/core.c +++ b/drivers/video/omap2/dss/core.c @@ -771,11 +771,8 @@ static int dss_driver_probe(struct device *dev) dss_init_device(core.pdev, dssdev); - /* skip this if the device is behind a ctrl */ - if (!dssdev->panel.ctrl) { - force = pdata->default_device == dssdev; - dss_recheck_connections(dssdev, force); - } + force = pdata->default_device == dssdev; + dss_recheck_connections(dssdev, force); r = dssdrv->probe(dssdev); @@ -861,8 +858,6 @@ static void omap_dss_dev_release(struct device *dev) int omap_dss_register_device(struct omap_dss_device *dssdev) { static int dev_num; - static int panel_num; - int r; WARN_ON(!dssdev->driver_name); @@ -871,36 +866,12 @@ int omap_dss_register_device(struct omap_dss_device *dssdev) dssdev->dev.parent = &dss_bus; dssdev->dev.release = omap_dss_dev_release; dev_set_name(&dssdev->dev, "display%d", dev_num++); - r = device_register(&dssdev->dev); - if (r) - return r; - - if (dssdev->ctrl.panel) { - struct omap_dss_device *panel = dssdev->ctrl.panel; - - panel->panel.ctrl = dssdev; - - reset_device(&panel->dev, 1); - panel->dev.bus = &dss_bus_type; - panel->dev.parent = &dssdev->dev; - panel->dev.release = omap_dss_dev_release; - dev_set_name(&panel->dev, "panel%d", panel_num++); - r = device_register(&panel->dev); - if (r) - return r; - } - - return 0; + return device_register(&dssdev->dev); } void omap_dss_unregister_device(struct omap_dss_device *dssdev) { device_unregister(&dssdev->dev); - - if (dssdev->ctrl.panel) { - struct omap_dss_device *panel = dssdev->ctrl.panel; - device_unregister(&panel->dev); - } } /* BUS */ diff --git a/drivers/video/omap2/dss/display.c b/drivers/video/omap2/dss/display.c index 3b92b84b9560..3f345b8cbcb0 100644 --- a/drivers/video/omap2/dss/display.c +++ b/drivers/video/omap2/dss/display.c @@ -591,10 +591,6 @@ struct omap_dss_device *omap_dss_get_next_device(struct omap_dss_device *from) int match(struct device *dev, void *data) { - /* skip panels connected to controllers */ - if (to_dss_device(dev)->panel.ctrl) - return 0; - return 1; } @@ -626,45 +622,21 @@ EXPORT_SYMBOL(omap_dss_find_device); int omap_dss_start_device(struct omap_dss_device *dssdev) { - int r; - if (!dssdev->driver) { DSSDBG("no driver\n"); - r = -ENODEV; - goto err0; - } - - if (dssdev->ctrl.panel && !dssdev->ctrl.panel->driver) { - DSSDBG("no panel driver\n"); - r = -ENODEV; - goto err0; + return -ENODEV; } if (!try_module_get(dssdev->dev.driver->owner)) { - r = -ENODEV; - goto err0; - } - - if (dssdev->ctrl.panel) { - if (!try_module_get(dssdev->ctrl.panel->dev.driver->owner)) { - r = -ENODEV; - goto err1; - } + return -ENODEV; } return 0; -err1: - module_put(dssdev->dev.driver->owner); -err0: - return r; } EXPORT_SYMBOL(omap_dss_start_device); void omap_dss_stop_device(struct omap_dss_device *dssdev) { - if (dssdev->ctrl.panel) - module_put(dssdev->ctrl.panel->dev.driver->owner); - module_put(dssdev->dev.driver->owner); } EXPORT_SYMBOL(omap_dss_stop_device); -- cgit v1.2.2 From c121b15244c53637c3e9ca608b8816abcfbe2f8e Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Wed, 17 Feb 2010 11:50:07 +0200 Subject: OMAP: DSS2: fix driver probe error handling If driver's probe failed, the uninit was not called. Signed-off-by: Tomi Valkeinen --- drivers/video/omap2/dss/core.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/video/omap2/dss/core.c b/drivers/video/omap2/dss/core.c index 967cbda1fd72..39b1a20a298c 100644 --- a/drivers/video/omap2/dss/core.c +++ b/drivers/video/omap2/dss/core.c @@ -778,6 +778,7 @@ static int dss_driver_probe(struct device *dev) if (r) { DSSERR("driver probe failed: %d\n", r); + dss_uninit_device(core.pdev, dssdev); return r; } -- cgit v1.2.2 From b3f91eb8d8d17ad3ca5da4fa9f20d2e46133fd99 Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Wed, 17 Feb 2010 12:00:01 +0200 Subject: OMAP: DSS2: OMAPFB: fix dssdev cleanup on error If there was a dss device without a driver and thus omapfb probe failed, ref counts could be left to dss devices. Signed-off-by: Tomi Valkeinen --- drivers/video/omap2/omapfb/omapfb-main.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/video/omap2/omapfb/omapfb-main.c b/drivers/video/omap2/omapfb/omapfb-main.c index d17caef6915a..973bf7938086 100644 --- a/drivers/video/omap2/omapfb/omapfb-main.c +++ b/drivers/video/omap2/omapfb/omapfb-main.c @@ -2111,18 +2111,23 @@ static int omapfb_probe(struct platform_device *pdev) fbdev->dev = &pdev->dev; platform_set_drvdata(pdev, fbdev); + r = 0; fbdev->num_displays = 0; dssdev = NULL; for_each_dss_dev(dssdev) { omap_dss_get_device(dssdev); + if (!dssdev->driver) { dev_err(&pdev->dev, "no driver for display\n"); - r = -EINVAL; - goto cleanup; + r = -ENODEV; } + fbdev->displays[fbdev->num_displays++] = dssdev; } + if (r) + goto cleanup; + if (fbdev->num_displays == 0) { dev_err(&pdev->dev, "no displays\n"); r = -EINVAL; -- cgit v1.2.2 From 6d2e0bd60848e97756f40e49da207e862f4f3851 Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Wed, 17 Feb 2010 13:38:08 +0200 Subject: OMAP: DSS2: OMAPFB: fix cleanup on dssdev enable error If enabling a dss device failed, omapfb didn't exit, leading to crash. Signed-off-by: Tomi Valkeinen --- drivers/video/omap2/omapfb/omapfb-main.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/video/omap2/omapfb/omapfb-main.c b/drivers/video/omap2/omapfb/omapfb-main.c index 973bf7938086..6a383ab2bef2 100644 --- a/drivers/video/omap2/omapfb/omapfb-main.c +++ b/drivers/video/omap2/omapfb/omapfb-main.c @@ -2176,9 +2176,11 @@ static int omapfb_probe(struct platform_device *pdev) u16 w, h; #endif r = def_display->enable(def_display); - if (r) + if (r) { dev_warn(fbdev->dev, "Failed to enable display '%s'\n", def_display->name); + goto cleanup; + } /* set the update mode */ if (def_display->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE) { -- cgit v1.2.2 From 3b43816f685fc6c2531f43514662f796f4601ffc Mon Sep 17 00:00:00 2001 From: Rabin Vincent Date: Fri, 12 Feb 2010 06:43:11 +0100 Subject: ARM: 5933/1: amba-pl011: support hardware flow control Enable/disable automatic hardware flow control as requested by the termios. The controller does not allow us to control the RTS line when auto-RTS is enabled, so we enable auto-RTS only if the kernel has not disabled RTS. Acked-by: Linus Walleij Signed-off-by: Rabin Vincent Signed-off-by: Russell King --- drivers/serial/amba-pl011.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) (limited to 'drivers') diff --git a/drivers/serial/amba-pl011.c b/drivers/serial/amba-pl011.c index ef7adc8135dd..ce6c35333ff7 100644 --- a/drivers/serial/amba-pl011.c +++ b/drivers/serial/amba-pl011.c @@ -71,6 +71,7 @@ struct uart_amba_port { unsigned int im; /* interrupt mask */ unsigned int old_status; unsigned int ifls; /* vendor-specific */ + bool autorts; }; /* There is by now at least one vendor with differing details, so handle it */ @@ -308,6 +309,11 @@ static void pl011_set_mctrl(struct uart_port *port, unsigned int mctrl) TIOCMBIT(TIOCM_OUT1, UART011_CR_OUT1); TIOCMBIT(TIOCM_OUT2, UART011_CR_OUT2); TIOCMBIT(TIOCM_LOOP, UART011_CR_LBE); + + if (uap->autorts) { + /* We need to disable auto-RTS if we want to turn RTS off */ + TIOCMBIT(TIOCM_RTS, UART011_CR_RTSEN); + } #undef TIOCMBIT writew(cr, uap->port.membase + UART011_CR); @@ -437,6 +443,7 @@ static void pl011_shutdown(struct uart_port *port) /* * disable the port */ + uap->autorts = false; writew(UART01x_CR_UARTEN | UART011_CR_TXE, uap->port.membase + UART011_CR); /* @@ -456,6 +463,7 @@ static void pl011_set_termios(struct uart_port *port, struct ktermios *termios, struct ktermios *old) { + struct uart_amba_port *uap = (struct uart_amba_port *)port; unsigned int lcr_h, old_cr; unsigned long flags; unsigned int baud, quot; @@ -532,6 +540,17 @@ pl011_set_termios(struct uart_port *port, struct ktermios *termios, old_cr = readw(port->membase + UART011_CR); writew(0, port->membase + UART011_CR); + if (termios->c_cflag & CRTSCTS) { + if (old_cr & UART011_CR_RTS) + old_cr |= UART011_CR_RTSEN; + + old_cr |= UART011_CR_CTSEN; + uap->autorts = true; + } else { + old_cr &= ~(UART011_CR_CTSEN | UART011_CR_RTSEN); + uap->autorts = false; + } + /* Set baud rate */ writew(quot & 0x3f, port->membase + UART011_FBRD); writew(quot >> 6, port->membase + UART011_IBRD); -- cgit v1.2.2 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') 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.2 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') 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.2 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') 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.2 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') 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.2 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') 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.2 From 64de028948f449af17cf387f45a45f36ffd3c960 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Fri, 19 Feb 2010 01:09:10 +0100 Subject: ARM: 5940/2: ARM: MMCI: remove custom DBG macro and printk This removes the custom DBG macro in favor of the in-kernel dev_dbg() macro. Probably a leftover from a time when dev_dbg() didn't yet exist. Also remove a printk() in favor of dev_err(). Signed-off-by: Linus Walleij Signed-off-by: Russell King --- drivers/mmc/host/mmci.c | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-) (limited to 'drivers') diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c index 643818a5ac45..84c103a7ee13 100644 --- a/drivers/mmc/host/mmci.c +++ b/drivers/mmc/host/mmci.c @@ -2,6 +2,7 @@ * linux/drivers/mmc/host/mmci.c - ARM PrimeCell MMCI PL180/1 driver * * Copyright (C) 2003 Deep Blue Solutions, Ltd, All Rights Reserved. + * Copyright (C) 2010 ST-Ericsson AB. * * 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 @@ -34,9 +35,6 @@ #define DRIVER_NAME "mmci-pl18x" -#define DBG(host,fmt,args...) \ - pr_debug("%s: %s: " fmt, mmc_hostname(host->mmc), __func__ , args) - static unsigned int fmax = 515633; /* @@ -105,8 +103,8 @@ static void mmci_start_data(struct mmci_host *host, struct mmc_data *data) void __iomem *base; int blksz_bits; - DBG(host, "blksz %04x blks %04x flags %08x\n", - data->blksz, data->blocks, data->flags); + dev_dbg(mmc_dev(host->mmc), "blksz %04x blks %04x flags %08x\n", + data->blksz, data->blocks, data->flags); host->data = data; host->size = data->blksz; @@ -155,7 +153,7 @@ mmci_start_command(struct mmci_host *host, struct mmc_command *cmd, u32 c) { void __iomem *base = host->base; - DBG(host, "op %02x arg %08x flags %08x\n", + dev_dbg(mmc_dev(host->mmc), "op %02x arg %08x flags %08x\n", cmd->opcode, cmd->arg, cmd->flags); if (readl(base + MMCICOMMAND) & MCI_CPSM_ENABLE) { @@ -197,6 +195,7 @@ mmci_data_irq(struct mmci_host *host, struct mmc_data *data, #endif } if (status & (MCI_DATACRCFAIL|MCI_DATATIMEOUT|MCI_TXUNDERRUN|MCI_RXOVERRUN)) { + dev_dbg(mmc_dev(host->mmc), "MCI ERROR IRQ (status %08x)\n", status); if (status & MCI_DATACRCFAIL) data->error = -EILSEQ; else if (status & MCI_DATATIMEOUT) @@ -318,7 +317,7 @@ static irqreturn_t mmci_pio_irq(int irq, void *dev_id) status = readl(base + MMCISTATUS); - DBG(host, "irq1 %08x\n", status); + dev_dbg(mmc_dev(host->mmc), "irq1 (pio) %08x\n", status); do { unsigned long flags; @@ -412,7 +411,7 @@ static irqreturn_t mmci_irq(int irq, void *dev_id) status &= readl(host->base + MMCIMASK0); writel(status, host->base + MMCICLEAR); - DBG(host, "irq0 %08x\n", status); + dev_dbg(mmc_dev(host->mmc), "irq0 (data+cmd) %08x\n", status); data = host->data; if (status & (MCI_DATACRCFAIL|MCI_DATATIMEOUT|MCI_TXUNDERRUN| @@ -439,8 +438,8 @@ static void mmci_request(struct mmc_host *mmc, struct mmc_request *mrq) WARN_ON(host->mrq != NULL); if (mrq->data && !is_power_of_2(mrq->data->blksz)) { - printk(KERN_ERR "%s: Unsupported block size (%d bytes)\n", - mmc_hostname(mmc), mrq->data->blksz); + dev_err(mmc_dev(mmc), "unsupported block size (%d bytes)\n", + mrq->data->blksz); mrq->cmd->error = -EINVAL; mmc_request_done(mmc, mrq); return; @@ -593,8 +592,8 @@ static int __devinit mmci_probe(struct amba_device *dev, struct amba_id *id) host->hw_designer = amba_manf(dev); host->hw_revision = amba_rev(dev); - DBG(host, "designer ID = 0x%02x\n", host->hw_designer); - DBG(host, "revision = 0x%01x\n", host->hw_revision); + dev_dbg(mmc_dev(mmc), "designer ID = 0x%02x\n", host->hw_designer); + dev_dbg(mmc_dev(mmc), "revision = 0x%01x\n", host->hw_revision); host->clk = clk_get(&dev->dev, NULL); if (IS_ERR(host->clk)) { @@ -619,7 +618,8 @@ static int __devinit mmci_probe(struct amba_device *dev, struct amba_id *id) if (ret < 0) goto clk_disable; host->mclk = clk_get_rate(host->clk); - DBG(host, "eventual mclk rate: %u Hz\n", host->mclk); + dev_dbg(mmc_dev(mmc), "eventual mclk rate: %u Hz\n", + host->mclk); } host->base = ioremap(dev->res.start, resource_size(&dev->res)); if (!host->base) { @@ -630,6 +630,8 @@ static int __devinit mmci_probe(struct amba_device *dev, struct amba_id *id) mmc->ops = &mmci_ops; mmc->f_min = (host->mclk + 511) / 512; mmc->f_max = min(host->mclk, fmax); + dev_dbg(mmc_dev(mmc), "clocking block at %u Hz\n", mmc->f_max); + #ifdef CONFIG_REGULATOR /* If we're using the regulator framework, try to fetch a regulator */ host->vcc = regulator_get(&dev->dev, "vmmc"); @@ -723,7 +725,7 @@ static int __devinit mmci_probe(struct amba_device *dev, struct amba_id *id) mmc_add_host(mmc); - printk(KERN_INFO "%s: MMCI rev %x cfg %02x at 0x%016llx irq %d,%d\n", + dev_info(&dev->dev, "%s: MMCI rev %x cfg %02x at 0x%016llx irq %d,%d\n", mmc_hostname(mmc), amba_rev(dev), amba_config(dev), (unsigned long long)dev->res.start, dev->irq[0], dev->irq[1]); -- cgit v1.2.2 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') 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.2 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') 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.2 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') 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.2 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') 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.2 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') 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.2 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') 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.2 From b028461d66a4dc2754d4e5dab1b3974c44798c5d Mon Sep 17 00:00:00 2001 From: dann frazier Date: Wed, 17 Feb 2010 16:53:31 -0700 Subject: cciss: remove C99-style comments Some cleanup before the header file split-out so we don't propagate this style into new files. Acked-by: Stephen M. Cameron Signed-off-by: dann frazier Signed-off-by: Jens Axboe --- drivers/block/cciss.c | 37 ++++++++++++++-------------- drivers/block/cciss.h | 9 +++---- drivers/block/cciss_cmd.h | 61 ++++++++++++++++++++++------------------------ drivers/block/cciss_scsi.h | 18 +++++++------- 4 files changed, 61 insertions(+), 64 deletions(-) (limited to 'drivers') diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c index 873e594860d3..8df23c732c46 100644 --- a/drivers/block/cciss.c +++ b/drivers/block/cciss.c @@ -1341,26 +1341,27 @@ static int cciss_ioctl(struct block_device *bdev, fmode_t mode, kfree(buff); return -ENOMEM; } - // Fill in the command type + /* Fill in the command type */ c->cmd_type = CMD_IOCTL_PEND; - // Fill in Command Header - c->Header.ReplyQueue = 0; // unused in simple mode - if (iocommand.buf_size > 0) // buffer to fill + /* Fill in Command Header */ + c->Header.ReplyQueue = 0; /* unused in simple mode */ + if (iocommand.buf_size > 0) /* buffer to fill */ { c->Header.SGList = 1; c->Header.SGTotal = 1; - } else // no buffers to fill + } else /* no buffers to fill */ { c->Header.SGList = 0; c->Header.SGTotal = 0; } c->Header.LUN = iocommand.LUN_info; - c->Header.Tag.lower = c->busaddr; // use the kernel address the cmd block for tag + /* use the kernel address the cmd block for tag */ + c->Header.Tag.lower = c->busaddr; - // Fill in Request block + /* Fill in Request block */ c->Request = iocommand.Request; - // Fill in the scatter gather information + /* Fill in the scatter gather information */ if (iocommand.buf_size > 0) { temp64.val = pci_map_single(host->pdev, buff, iocommand.buf_size, @@ -1368,7 +1369,7 @@ static int cciss_ioctl(struct block_device *bdev, fmode_t mode, c->SG[0].Addr.lower = temp64.val32.lower; c->SG[0].Addr.upper = temp64.val32.upper; c->SG[0].Len = iocommand.buf_size; - c->SG[0].Ext = 0; // we are not chaining + c->SG[0].Ext = 0; /* we are not chaining */ } c->waiting = &wait; @@ -2422,7 +2423,7 @@ static int fill_cmd(CommandList_struct *c, __u8 cmd, int ctlr, void *buff, c->Request.Type.Direction = XFER_READ; c->Request.Timeout = 0; c->Request.CDB[0] = cmd; - c->Request.CDB[6] = (size >> 24) & 0xFF; //MSB + c->Request.CDB[6] = (size >> 24) & 0xFF; /* MSB */ c->Request.CDB[7] = (size >> 16) & 0xFF; c->Request.CDB[8] = (size >> 8) & 0xFF; c->Request.CDB[9] = size & 0xFF; @@ -2691,7 +2692,7 @@ static void cciss_geometry_inquiry(int ctlr, int logvol, "cciss: reading geometry failed, volume " "does not support reading geometry\n"); drv->heads = 255; - drv->sectors = 32; // Sectors per track + drv->sectors = 32; /* Sectors per track */ drv->cylinders = total_size + 1; drv->raid_level = RAID_UNKNOWN; } else { @@ -3109,19 +3110,19 @@ static void do_cciss_request(struct request_queue *q) /* fill in the request */ drv = creq->rq_disk->private_data; - c->Header.ReplyQueue = 0; // unused in simple mode + c->Header.ReplyQueue = 0; /* unused in simple mode */ /* got command from pool, so use the command block index instead */ /* for direct lookups. */ /* The first 2 bits are reserved for controller error reporting. */ c->Header.Tag.lower = (c->cmdindex << 3); c->Header.Tag.lower |= 0x04; /* flag for direct lookup. */ memcpy(&c->Header.LUN, drv->LunID, sizeof(drv->LunID)); - c->Request.CDBLen = 10; // 12 byte commands not in FW yet; - c->Request.Type.Type = TYPE_CMD; // It is a command. + c->Request.CDBLen = 10; /* 12 byte commands not in FW yet; */ + c->Request.Type.Type = TYPE_CMD; /* It is a command. */ c->Request.Type.Attribute = ATTR_SIMPLE; c->Request.Type.Direction = (rq_data_dir(creq) == READ) ? XFER_READ : XFER_WRITE; - c->Request.Timeout = 0; // Don't time out + c->Request.Timeout = 0; /* Don't time out */ c->Request.CDB[0] = (rq_data_dir(creq) == READ) ? h->cciss_read : h->cciss_write; start_blk = blk_rq_pos(creq); @@ -3206,11 +3207,11 @@ static void do_cciss_request(struct request_queue *q) if (likely(blk_fs_request(creq))) { if(h->cciss_read == CCISS_READ_10) { c->Request.CDB[1] = 0; - c->Request.CDB[2] = (start_blk >> 24) & 0xff; //MSB + c->Request.CDB[2] = (start_blk >> 24) & 0xff; /* MSB */ c->Request.CDB[3] = (start_blk >> 16) & 0xff; c->Request.CDB[4] = (start_blk >> 8) & 0xff; c->Request.CDB[5] = start_blk & 0xff; - c->Request.CDB[6] = 0; // (sect >> 24) & 0xff; MSB + c->Request.CDB[6] = 0; /* (sect >> 24) & 0xff; MSB */ c->Request.CDB[7] = (blk_rq_sectors(creq) >> 8) & 0xff; c->Request.CDB[8] = blk_rq_sectors(creq) & 0xff; c->Request.CDB[9] = c->Request.CDB[11] = c->Request.CDB[12] = 0; @@ -3219,7 +3220,7 @@ static void do_cciss_request(struct request_queue *q) c->Request.CDBLen = 16; c->Request.CDB[1]= 0; - c->Request.CDB[2]= (upper32 >> 24) & 0xff; //MSB + c->Request.CDB[2]= (upper32 >> 24) & 0xff; /* MSB */ c->Request.CDB[3]= (upper32 >> 16) & 0xff; c->Request.CDB[4]= (upper32 >> 8) & 0xff; c->Request.CDB[5]= upper32 & 0xff; diff --git a/drivers/block/cciss.h b/drivers/block/cciss.h index 1d95db254069..2b07bdacbd12 100644 --- a/drivers/block/cciss.h +++ b/drivers/block/cciss.h @@ -66,7 +66,7 @@ struct ctlr_info int ctlr; char devname[8]; char *product_name; - char firm_ver[4]; // Firmware version + char firm_ver[4]; /* Firmware version */ struct pci_dev *pdev; __u32 board_id; void __iomem *vaddr; @@ -103,7 +103,7 @@ struct ctlr_info BYTE cciss_write; BYTE cciss_read_capacity; - // information about each logical volume + /* information about each logical volume */ drive_info_struct *drv[CISS_MAX_LUN]; struct access_method access; @@ -116,7 +116,7 @@ struct ctlr_info unsigned int maxSG; spinlock_t lock; - //* pointers to command and error info pool */ + /* pointers to command and error info pool */ CommandList_struct *cmd_pool; dma_addr_t cmd_pool_dhandle; ErrorInfo_struct *errinfo_pool; @@ -134,7 +134,7 @@ struct ctlr_info */ int next_to_run; - // Disk structures we need to pass back + /* Disk structures we need to pass back */ struct gendisk *gendisk[CISS_MAX_LUN]; #ifdef CONFIG_CISS_SCSI_TAPE void *scsi_ctlr; /* ptr to structure containing scsi related stuff */ @@ -315,4 +315,3 @@ struct board_type { #define CCISS_LOCK(i) (&hba[i]->lock) #endif /* CCISS_H */ - diff --git a/drivers/block/cciss_cmd.h b/drivers/block/cciss_cmd.h index 6afa700890ff..277422b7e060 100644 --- a/drivers/block/cciss_cmd.h +++ b/drivers/block/cciss_cmd.h @@ -1,17 +1,16 @@ #ifndef CCISS_CMD_H #define CCISS_CMD_H -//########################################################################### -//DEFINES -//########################################################################### +/* DEFINES */ #define CISS_VERSION "1.00" -//general boundary definitions -#define SENSEINFOBYTES 32//note that this value may vary between host implementations +/* general boundary definitions */ +#define SENSEINFOBYTES 32 /* note that this value may vary + between host implementations */ #define MAXSGENTRIES 32 #define CCISS_SG_CHAIN 0x80000000 #define MAXREPLYQS 256 -//Command Status value +/* Command Status value */ #define CMD_SUCCESS 0x0000 #define CMD_TARGET_STATUS 0x0001 #define CMD_DATA_UNDERRUN 0x0002 @@ -49,30 +48,30 @@ #define ASYM_ACCESS_CHANGED 0x06 #define LUN_CAPACITY_CHANGED 0x09 -//transfer direction +/* transfer direction */ #define XFER_NONE 0x00 #define XFER_WRITE 0x01 #define XFER_READ 0x02 #define XFER_RSVD 0x03 -//task attribute +/* task attribute */ #define ATTR_UNTAGGED 0x00 #define ATTR_SIMPLE 0x04 #define ATTR_HEADOFQUEUE 0x05 #define ATTR_ORDERED 0x06 #define ATTR_ACA 0x07 -//cdb type +/* cdb type */ #define TYPE_CMD 0x00 #define TYPE_MSG 0x01 -//config space register offsets +/* config space register offsets */ #define CFG_VENDORID 0x00 #define CFG_DEVICEID 0x02 #define CFG_I2OBAR 0x10 #define CFG_MEM1BAR 0x14 -//i2o space register offsets +/* i2o space register offsets */ #define I2O_IBDB_SET 0x20 #define I2O_IBDB_CLEAR 0x70 #define I2O_INT_STATUS 0x30 @@ -81,7 +80,7 @@ #define I2O_OBPOST_Q 0x44 #define I2O_DMA1_CFG 0x214 -//Configuration Table +/* Configuration Table */ #define CFGTBL_ChangeReq 0x00000001l #define CFGTBL_AccCmds 0x00000001l @@ -103,24 +102,22 @@ typedef union _u64bit __u64 val; } u64bit; -// Type defs used in the following structs +/* Type defs used in the following structs */ #define BYTE __u8 #define WORD __u16 #define HWORD __u16 #define DWORD __u32 #define QWORD vals32 -//########################################################################### -//STRUCTURES -//########################################################################### +/* STRUCTURES */ #define CISS_MAX_LUN 1024 #define CISS_MAX_PHYS_LUN 1024 -// SCSI-3 Cmmands +/* SCSI-3 Cmmands */ #pragma pack(1) #define CISS_INQUIRY 0x12 -//Date returned +/* Date returned */ typedef struct _InquiryData_struct { BYTE data_byte[36]; @@ -128,7 +125,7 @@ typedef struct _InquiryData_struct #define CISS_REPORT_LOG 0xc2 /* Report Logical LUNs */ #define CISS_REPORT_PHYS 0xc3 /* Report Physical LUNs */ -// Data returned +/* Data returned */ typedef struct _ReportLUNdata_struct { BYTE LUNListLength[4]; @@ -139,8 +136,8 @@ typedef struct _ReportLUNdata_struct #define CCISS_READ_CAPACITY 0x25 /* Read Capacity */ typedef struct _ReadCapdata_struct { - BYTE total_size[4]; // Total size in blocks - BYTE block_size[4]; // Size of blocks in bytes + BYTE total_size[4]; /* Total size in blocks */ + BYTE block_size[4]; /* Size of blocks in bytes */ } ReadCapdata_struct; #define CCISS_READ_CAPACITY_16 0x9e /* Read Capacity 16 */ @@ -172,29 +169,29 @@ typedef struct _ReadCapdata_struct_16 #define CDB_LEN10 10 #define CDB_LEN16 16 -// BMIC commands +/* BMIC commands */ #define BMIC_READ 0x26 #define BMIC_WRITE 0x27 #define BMIC_CACHE_FLUSH 0xc2 -#define CCISS_CACHE_FLUSH 0x01 //C2 was already being used by CCISS +#define CCISS_CACHE_FLUSH 0x01 /* C2 was already being used by CCISS */ -//Command List Structure +/* Command List Structure */ typedef union _SCSI3Addr_struct { struct { BYTE Dev; BYTE Bus:6; - BYTE Mode:2; // b00 + BYTE Mode:2; /* b00 */ } PeripDev; struct { BYTE DevLSB; BYTE DevMSB:6; - BYTE Mode:2; // b01 + BYTE Mode:2; /* b01 */ } LogDev; struct { BYTE Dev:5; BYTE Bus:3; BYTE Targ:6; - BYTE Mode:2; // b10 + BYTE Mode:2; /* b10 */ } LogUnit; } SCSI3Addr_struct; @@ -202,7 +199,7 @@ typedef struct _PhysDevAddr_struct { DWORD TargetId:24; DWORD Bus:6; DWORD Mode:2; - SCSI3Addr_struct Target[2]; //2 level target device addr + SCSI3Addr_struct Target[2]; /* 2 level target device addr */ } PhysDevAddr_struct; typedef struct _LogDevAddr_struct { @@ -255,8 +252,8 @@ typedef union _MoreErrInfo_struct{ }Common_Info; struct{ BYTE Reserved[2]; - BYTE offense_size;//size of offending entry - BYTE offense_num; //byte # of offense 0-base + BYTE offense_size; /* size of offending entry */ + BYTE offense_num; /* byte # of offense 0-base */ DWORD offense_value; }Invalid_Cmd; }MoreErrInfo_struct; @@ -300,7 +297,7 @@ typedef struct _CommandList_struct { char pad[PADSIZE]; } CommandList_struct; -//Configuration Table Structure +/* Configuration Table Structure */ typedef struct _HostWrite_struct { DWORD TransportRequest; DWORD Reserved; @@ -326,4 +323,4 @@ typedef struct _CfgTable_struct { DWORD MaxPhysicalDrivesPerLogicalUnit; } CfgTable_struct; #pragma pack() -#endif // CCISS_CMD_H +#endif /* CCISS_CMD_H */ diff --git a/drivers/block/cciss_scsi.h b/drivers/block/cciss_scsi.h index 7b750245ae76..6d5822fe851a 100644 --- a/drivers/block/cciss_scsi.h +++ b/drivers/block/cciss_scsi.h @@ -25,16 +25,16 @@ #include /* possibly irrelevant, since we don't show disks */ - // the scsi id of the adapter... + /* the scsi id of the adapter... */ #define SELF_SCSI_ID 15 - // 15 is somewhat arbitrary, since the scsi-2 bus - // that's presented by the driver to the OS is - // fabricated. The "real" scsi-3 bus the - // hardware presents is fabricated too. - // The actual, honest-to-goodness physical - // bus that the devices are attached to is not - // addressible natively, and may in fact turn - // out to be not scsi at all. + /* 15 is somewhat arbitrary, since the scsi-2 bus + that's presented by the driver to the OS is + fabricated. The "real" scsi-3 bus the + hardware presents is fabricated too. + The actual, honest-to-goodness physical + bus that the devices are attached to is not + addressible natively, and may in fact turn + out to be not scsi at all. */ #define SCSI_CCISS_CAN_QUEUE 2 -- cgit v1.2.2 From 429c42c9d246f5bda868495c09974312a0177328 Mon Sep 17 00:00:00 2001 From: dann frazier Date: Wed, 17 Feb 2010 16:55:11 -0700 Subject: cciss: Consolidate duplicate bits in cciss_cmd.h & cciss_ioctl.h There are several duplicate definitions in cciss_cmd.h and cciss_ioctl.h. Consolidate these into the new cciss_defs.h file. This patch doesn't change the definitions exposed under include/linux, so userspace apps shouldn't be affected. Acked-by: Stephen M. Cameron Signed-off-by: dann frazier Signed-off-by: Jens Axboe --- drivers/block/cciss_cmd.h | 113 ++-------------------------------------------- 1 file changed, 3 insertions(+), 110 deletions(-) (limited to 'drivers') diff --git a/drivers/block/cciss_cmd.h b/drivers/block/cciss_cmd.h index 277422b7e060..25f97623bacf 100644 --- a/drivers/block/cciss_cmd.h +++ b/drivers/block/cciss_cmd.h @@ -1,30 +1,16 @@ #ifndef CCISS_CMD_H #define CCISS_CMD_H + +#include + /* DEFINES */ #define CISS_VERSION "1.00" /* general boundary definitions */ -#define SENSEINFOBYTES 32 /* note that this value may vary - between host implementations */ #define MAXSGENTRIES 32 #define CCISS_SG_CHAIN 0x80000000 #define MAXREPLYQS 256 -/* Command Status value */ -#define CMD_SUCCESS 0x0000 -#define CMD_TARGET_STATUS 0x0001 -#define CMD_DATA_UNDERRUN 0x0002 -#define CMD_DATA_OVERRUN 0x0003 -#define CMD_INVALID 0x0004 -#define CMD_PROTOCOL_ERR 0x0005 -#define CMD_HARDWARE_ERR 0x0006 -#define CMD_CONNECTION_LOST 0x0007 -#define CMD_ABORTED 0x0008 -#define CMD_ABORT_FAILED 0x0009 -#define CMD_UNSOLICITED_ABORT 0x000A -#define CMD_TIMEOUT 0x000B -#define CMD_UNABORTABLE 0x000C - /* Unit Attentions ASC's as defined for the MSA2012sa */ #define POWER_OR_RESET 0x29 #define STATE_CHANGED 0x2a @@ -48,23 +34,6 @@ #define ASYM_ACCESS_CHANGED 0x06 #define LUN_CAPACITY_CHANGED 0x09 -/* transfer direction */ -#define XFER_NONE 0x00 -#define XFER_WRITE 0x01 -#define XFER_READ 0x02 -#define XFER_RSVD 0x03 - -/* task attribute */ -#define ATTR_UNTAGGED 0x00 -#define ATTR_SIMPLE 0x04 -#define ATTR_HEADOFQUEUE 0x05 -#define ATTR_ORDERED 0x06 -#define ATTR_ACA 0x07 - -/* cdb type */ -#define TYPE_CMD 0x00 -#define TYPE_MSG 0x01 - /* config space register offsets */ #define CFG_VENDORID 0x00 #define CFG_DEVICEID 0x02 @@ -103,14 +72,9 @@ typedef union _u64bit } u64bit; /* Type defs used in the following structs */ -#define BYTE __u8 -#define WORD __u16 -#define HWORD __u16 -#define DWORD __u32 #define QWORD vals32 /* STRUCTURES */ -#define CISS_MAX_LUN 1024 #define CISS_MAX_PHYS_LUN 1024 /* SCSI-3 Cmmands */ @@ -176,45 +140,6 @@ typedef struct _ReadCapdata_struct_16 #define CCISS_CACHE_FLUSH 0x01 /* C2 was already being used by CCISS */ /* Command List Structure */ -typedef union _SCSI3Addr_struct { - struct { - BYTE Dev; - BYTE Bus:6; - BYTE Mode:2; /* b00 */ - } PeripDev; - struct { - BYTE DevLSB; - BYTE DevMSB:6; - BYTE Mode:2; /* b01 */ - } LogDev; - struct { - BYTE Dev:5; - BYTE Bus:3; - BYTE Targ:6; - BYTE Mode:2; /* b10 */ - } LogUnit; -} SCSI3Addr_struct; - -typedef struct _PhysDevAddr_struct { - DWORD TargetId:24; - DWORD Bus:6; - DWORD Mode:2; - SCSI3Addr_struct Target[2]; /* 2 level target device addr */ -} PhysDevAddr_struct; - -typedef struct _LogDevAddr_struct { - DWORD VolId:30; - DWORD Mode:2; - BYTE reserved[4]; -} LogDevAddr_struct; - -typedef union _LUNAddr_struct { - BYTE LunAddrBytes[8]; - SCSI3Addr_struct SCSI3Lun[4]; - PhysDevAddr_struct PhysDev; - LogDevAddr_struct LogDev; -} LUNAddr_struct; - #define CTLR_LUNID "\0\0\0\0\0\0\0\0" typedef struct _CommandListHeader_struct { @@ -224,16 +149,6 @@ typedef struct _CommandListHeader_struct { QWORD Tag; LUNAddr_struct LUN; } CommandListHeader_struct; -typedef struct _RequestBlock_struct { - BYTE CDBLen; - struct { - BYTE Type:3; - BYTE Attribute:3; - BYTE Direction:2; - } Type; - HWORD Timeout; - BYTE CDB[16]; -} RequestBlock_struct; typedef struct _ErrDescriptor_struct { QWORD Addr; DWORD Len; @@ -244,28 +159,6 @@ typedef struct _SGDescriptor_struct { DWORD Ext; } SGDescriptor_struct; -typedef union _MoreErrInfo_struct{ - struct { - BYTE Reserved[3]; - BYTE Type; - DWORD ErrorInfo; - }Common_Info; - struct{ - BYTE Reserved[2]; - BYTE offense_size; /* size of offending entry */ - BYTE offense_num; /* byte # of offense 0-base */ - DWORD offense_value; - }Invalid_Cmd; -}MoreErrInfo_struct; -typedef struct _ErrorInfo_struct { - BYTE ScsiStatus; - BYTE SenseLen; - HWORD CommandStatus; - DWORD ResidualCnt; - MoreErrInfo_struct MoreErrInfo; - BYTE SenseInfo[SENSEINFOBYTES]; -} ErrorInfo_struct; - /* Command types */ #define CMD_RWREQ 0x00 #define CMD_IOCTL_PEND 0x01 -- cgit v1.2.2 From aefbd3e823d4fe219bb6420b0cac505847270507 Mon Sep 17 00:00:00 2001 From: Daniel Mack Date: Tue, 23 Feb 2010 10:30:00 +0100 Subject: usb/gadget/{f_audio,gmidi}.c: follow recent changes in audio.h Some structs in linux/usb/audio.h have got new names to mark them as part of version 1.0 of the USB audio standard. Follow these changes in the gadget drivers. Note that this header and the ALSA USB driver will undergo some refactoring soon, so there might be another update to the gadgets as well. Signed-off-by: Daniel Mack Signed-off-by: Takashi Iwai --- drivers/usb/gadget/f_audio.c | 6 +++--- drivers/usb/gadget/gmidi.c | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/f_audio.c b/drivers/usb/gadget/f_audio.c index df77f6131c73..f1e3aad76c37 100644 --- a/drivers/usb/gadget/f_audio.c +++ b/drivers/usb/gadget/f_audio.c @@ -60,7 +60,7 @@ DECLARE_UAC_AC_HEADER_DESCRIPTOR(2); #define UAC_DT_TOTAL_LENGTH (UAC_DT_AC_HEADER_LENGTH + UAC_DT_INPUT_TERMINAL_SIZE \ + UAC_DT_OUTPUT_TERMINAL_SIZE + UAC_DT_FEATURE_UNIT_SIZE(0)) /* B.3.2 Class-Specific AC Interface Descriptor */ -static struct uac_ac_header_descriptor_2 ac_header_desc = { +static struct uac_ac_header_descriptor_v1_2 ac_header_desc = { .bLength = UAC_DT_AC_HEADER_LENGTH, .bDescriptorType = USB_DT_CS_INTERFACE, .bDescriptorSubtype = UAC_HEADER, @@ -124,7 +124,7 @@ static struct usb_audio_control_selector feature_unit = { }; #define OUTPUT_TERMINAL_ID 3 -static struct uac_output_terminal_descriptor output_terminal_desc = { +static struct uac_output_terminal_descriptor_v1 output_terminal_desc = { .bLength = UAC_DT_OUTPUT_TERMINAL_SIZE, .bDescriptorType = USB_DT_CS_INTERFACE, .bDescriptorSubtype = UAC_OUTPUT_TERMINAL, @@ -154,7 +154,7 @@ static struct usb_interface_descriptor as_interface_alt_1_desc = { }; /* B.4.2 Class-Specific AS Interface Descriptor */ -static struct uac_as_header_descriptor as_header_desc = { +static struct uac_as_header_descriptor_v1 as_header_desc = { .bLength = UAC_DT_AS_HEADER_SIZE, .bDescriptorType = USB_DT_CS_INTERFACE, .bDescriptorSubtype = UAC_AS_GENERAL, diff --git a/drivers/usb/gadget/gmidi.c b/drivers/usb/gadget/gmidi.c index d0b1e836f0e0..5f6a2e0a9357 100644 --- a/drivers/usb/gadget/gmidi.c +++ b/drivers/usb/gadget/gmidi.c @@ -237,7 +237,7 @@ static const struct usb_interface_descriptor ac_interface_desc = { }; /* B.3.2 Class-Specific AC Interface Descriptor */ -static const struct uac_ac_header_descriptor_1 ac_header_desc = { +static const struct uac_ac_header_descriptor_v1_1 ac_header_desc = { .bLength = UAC_DT_AC_HEADER_SIZE(1), .bDescriptorType = USB_DT_CS_INTERFACE, .bDescriptorSubtype = USB_MS_HEADER, -- cgit v1.2.2 From 63cf28ac3e3166a02a4e0db6168cf403ed66e3a5 Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Tue, 23 Feb 2010 17:40:00 +0200 Subject: OMAP: DSS2: fix get_dsi/dispc_clk_source() usage After changing the selection of DSI and DISPC clock source the users of get_dsi/dispc_clk_source() functions were left unchanged. Signed-off-by: Tomi Valkeinen --- drivers/video/omap2/dss/dispc.c | 4 ++-- drivers/video/omap2/dss/dsi.c | 10 ++++++---- 2 files changed, 8 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c index 7781c65bbeba..212cb800a5d2 100644 --- a/drivers/video/omap2/dss/dispc.c +++ b/drivers/video/omap2/dss/dispc.c @@ -2198,7 +2198,7 @@ unsigned long dispc_fclk_rate(void) { unsigned long r = 0; - if (dss_get_dispc_clk_source() == 0) + if (dss_get_dispc_clk_source() == DSS_SRC_DSS1_ALWON_FCLK) r = dss_clk_get_rate(DSS_CLK_FCK1); else #ifdef CONFIG_OMAP2_DSS_DSI @@ -2251,7 +2251,7 @@ void dispc_dump_clocks(struct seq_file *s) seq_printf(s, "- DISPC -\n"); seq_printf(s, "dispc fclk source = %s\n", - dss_get_dispc_clk_source() == 0 ? + dss_get_dispc_clk_source() == DSS_SRC_DSS1_ALWON_FCLK ? "dss1_alwon_fclk" : "dsi1_pll_fclk"); seq_printf(s, "fck\t\t%-16lu\n", dispc_fclk_rate()); diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c index 4b85ed202d50..928b5e44a3dd 100644 --- a/drivers/video/omap2/dss/dsi.c +++ b/drivers/video/omap2/dss/dsi.c @@ -778,7 +778,7 @@ static unsigned long dsi_fclk_rate(void) { unsigned long r; - if (dss_get_dsi_clk_source() == 0) { + if (dss_get_dsi_clk_source() == DSS_SRC_DSS1_ALWON_FCLK) { /* DSI FCLK source is DSS1_ALWON_FCK, which is dss1_fck */ r = dss_clk_get_rate(DSS_CLK_FCK1); } else { @@ -1231,17 +1231,19 @@ void dsi_dump_clocks(struct seq_file *s) seq_printf(s, "dsi1_pll_fck\t%-16luregm3 %u\t(%s)\n", cinfo->dsi1_pll_fclk, cinfo->regm3, - dss_get_dispc_clk_source() == 0 ? "off" : "on"); + dss_get_dispc_clk_source() == DSS_SRC_DSS1_ALWON_FCLK ? + "off" : "on"); seq_printf(s, "dsi2_pll_fck\t%-16luregm4 %u\t(%s)\n", cinfo->dsi2_pll_fclk, cinfo->regm4, - dss_get_dsi_clk_source() == 0 ? "off" : "on"); + dss_get_dsi_clk_source() == DSS_SRC_DSS1_ALWON_FCLK ? + "off" : "on"); seq_printf(s, "- DSI -\n"); seq_printf(s, "dsi fclk source = %s\n", - dss_get_dsi_clk_source() == 0 ? + dss_get_dsi_clk_source() == DSS_SRC_DSS1_ALWON_FCLK ? "dss1_alwon_fclk" : "dsi2_pll_fclk"); seq_printf(s, "DSI_FCLK\t%lu\n", dsi_fclk_rate()); -- cgit v1.2.2 From c5ecc484c528ff50bdbb16fbfbac758ee368b329 Mon Sep 17 00:00:00 2001 From: Akinobu Mita Date: Wed, 24 Feb 2010 08:30:08 +0100 Subject: pktcdvd: use BIO list management functions Now that the bio list management stuff is generic, convert pktcdvd to use bio lists instead of its own private bio list implementation. Signed-off-by: Akinobu Mita Acked-by: Peter Osterlund Cc: Christoph Hellwig Signed-off-by: Jens Axboe --- drivers/block/pktcdvd.c | 89 ++++++++++++------------------------------------- 1 file changed, 21 insertions(+), 68 deletions(-) (limited to 'drivers') diff --git a/drivers/block/pktcdvd.c b/drivers/block/pktcdvd.c index 68b5957f107c..7cd2973ebb7b 100644 --- a/drivers/block/pktcdvd.c +++ b/drivers/block/pktcdvd.c @@ -569,6 +569,7 @@ static struct packet_data *pkt_alloc_packet_data(int frames) } spin_lock_init(&pkt->lock); + bio_list_init(&pkt->orig_bios); for (i = 0; i < frames; i++) { struct bio *bio = pkt_bio_alloc(1); @@ -720,43 +721,6 @@ static void pkt_rbtree_insert(struct pktcdvd_device *pd, struct pkt_rb_node *nod pd->bio_queue_size++; } -/* - * Add a bio to a single linked list defined by its head and tail pointers. - */ -static void pkt_add_list_last(struct bio *bio, struct bio **list_head, struct bio **list_tail) -{ - bio->bi_next = NULL; - if (*list_tail) { - BUG_ON((*list_head) == NULL); - (*list_tail)->bi_next = bio; - (*list_tail) = bio; - } else { - BUG_ON((*list_head) != NULL); - (*list_head) = bio; - (*list_tail) = bio; - } -} - -/* - * Remove and return the first bio from a single linked list defined by its - * head and tail pointers. - */ -static inline struct bio *pkt_get_list_first(struct bio **list_head, struct bio **list_tail) -{ - struct bio *bio; - - if (*list_head == NULL) - return NULL; - - bio = *list_head; - *list_head = bio->bi_next; - if (*list_head == NULL) - *list_tail = NULL; - - bio->bi_next = NULL; - return bio; -} - /* * Send a packet_command to the underlying block device and * wait for completion. @@ -876,13 +840,10 @@ static noinline_for_stack int pkt_set_speed(struct pktcdvd_device *pd, static void pkt_queue_bio(struct pktcdvd_device *pd, struct bio *bio) { spin_lock(&pd->iosched.lock); - if (bio_data_dir(bio) == READ) { - pkt_add_list_last(bio, &pd->iosched.read_queue, - &pd->iosched.read_queue_tail); - } else { - pkt_add_list_last(bio, &pd->iosched.write_queue, - &pd->iosched.write_queue_tail); - } + if (bio_data_dir(bio) == READ) + bio_list_add(&pd->iosched.read_queue, bio); + else + bio_list_add(&pd->iosched.write_queue, bio); spin_unlock(&pd->iosched.lock); atomic_set(&pd->iosched.attention, 1); @@ -917,8 +878,8 @@ static void pkt_iosched_process_queue(struct pktcdvd_device *pd) int reads_queued, writes_queued; spin_lock(&pd->iosched.lock); - reads_queued = (pd->iosched.read_queue != NULL); - writes_queued = (pd->iosched.write_queue != NULL); + reads_queued = !bio_list_empty(&pd->iosched.read_queue); + writes_queued = !bio_list_empty(&pd->iosched.write_queue); spin_unlock(&pd->iosched.lock); if (!reads_queued && !writes_queued) @@ -927,7 +888,7 @@ static void pkt_iosched_process_queue(struct pktcdvd_device *pd) if (pd->iosched.writing) { int need_write_seek = 1; spin_lock(&pd->iosched.lock); - bio = pd->iosched.write_queue; + bio = bio_list_peek(&pd->iosched.write_queue); spin_unlock(&pd->iosched.lock); if (bio && (bio->bi_sector == pd->iosched.last_write)) need_write_seek = 0; @@ -950,13 +911,10 @@ static void pkt_iosched_process_queue(struct pktcdvd_device *pd) } spin_lock(&pd->iosched.lock); - if (pd->iosched.writing) { - bio = pkt_get_list_first(&pd->iosched.write_queue, - &pd->iosched.write_queue_tail); - } else { - bio = pkt_get_list_first(&pd->iosched.read_queue, - &pd->iosched.read_queue_tail); - } + if (pd->iosched.writing) + bio = bio_list_pop(&pd->iosched.write_queue); + else + bio = bio_list_pop(&pd->iosched.read_queue); spin_unlock(&pd->iosched.lock); if (!bio) @@ -1114,7 +1072,7 @@ static void pkt_gather_data(struct pktcdvd_device *pd, struct packet_data *pkt) int f; char written[PACKET_MAX_SIZE]; - BUG_ON(!pkt->orig_bios); + BUG_ON(bio_list_empty(&pkt->orig_bios)); atomic_set(&pkt->io_wait, 0); atomic_set(&pkt->io_errors, 0); @@ -1124,7 +1082,7 @@ static void pkt_gather_data(struct pktcdvd_device *pd, struct packet_data *pkt) */ memset(written, 0, sizeof(written)); spin_lock(&pkt->lock); - for (bio = pkt->orig_bios; bio; bio = bio->bi_next) { + bio_list_for_each(bio, &pkt->orig_bios) { int first_frame = (bio->bi_sector - pkt->sector) / (CD_FRAMESIZE >> 9); int num_frames = bio->bi_size / CD_FRAMESIZE; pd->stats.secs_w += num_frames * (CD_FRAMESIZE >> 9); @@ -1363,7 +1321,7 @@ try_next_bio: break; pkt_rbtree_erase(pd, node); spin_lock(&pkt->lock); - pkt_add_list_last(bio, &pkt->orig_bios, &pkt->orig_bios_tail); + bio_list_add(&pkt->orig_bios, bio); pkt->write_size += bio->bi_size / CD_FRAMESIZE; spin_unlock(&pkt->lock); } @@ -1409,7 +1367,7 @@ static void pkt_start_write(struct pktcdvd_device *pd, struct packet_data *pkt) */ frames_write = 0; spin_lock(&pkt->lock); - for (bio = pkt->orig_bios; bio; bio = bio->bi_next) { + bio_list_for_each(bio, &pkt->orig_bios) { int segment = bio->bi_idx; int src_offs = 0; int first_frame = (bio->bi_sector - pkt->sector) / (CD_FRAMESIZE >> 9); @@ -1472,20 +1430,14 @@ static void pkt_start_write(struct pktcdvd_device *pd, struct packet_data *pkt) static void pkt_finish_packet(struct packet_data *pkt, int uptodate) { - struct bio *bio, *next; + struct bio *bio; if (!uptodate) pkt->cache_valid = 0; /* Finish all bios corresponding to this packet */ - bio = pkt->orig_bios; - while (bio) { - next = bio->bi_next; - bio->bi_next = NULL; + while ((bio = bio_list_pop(&pkt->orig_bios))) bio_endio(bio, uptodate ? 0 : -EIO); - bio = next; - } - pkt->orig_bios = pkt->orig_bios_tail = NULL; } static void pkt_run_state_machine(struct pktcdvd_device *pd, struct packet_data *pkt) @@ -2567,8 +2519,7 @@ static int pkt_make_request(struct request_queue *q, struct bio *bio) spin_lock(&pkt->lock); if ((pkt->state == PACKET_WAITING_STATE) || (pkt->state == PACKET_READ_WAIT_STATE)) { - pkt_add_list_last(bio, &pkt->orig_bios, - &pkt->orig_bios_tail); + bio_list_add(&pkt->orig_bios, bio); pkt->write_size += bio->bi_size / CD_FRAMESIZE; if ((pkt->write_size >= pkt->frames) && (pkt->state == PACKET_WAITING_STATE)) { @@ -2898,6 +2849,8 @@ static int pkt_setup_dev(dev_t dev, dev_t* pkt_dev) spin_lock_init(&pd->lock); spin_lock_init(&pd->iosched.lock); + bio_list_init(&pd->iosched.read_queue); + bio_list_init(&pd->iosched.write_queue); sprintf(pd->name, DRIVER_NAME"%d", idx); init_waitqueue_head(&pd->wqueue); pd->bio_queue = RB_ROOT; -- cgit v1.2.2 From 197d4db752e67160d79fed09968c2140376a80a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20H=C3=A4rdeman?= 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') 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.2 From b9eb5d7d0b9bf7c6430374333e4b9dae73bbba20 Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Mon, 11 Jan 2010 16:33:56 +0200 Subject: OMAP: DSS2: DSI: change DSI bus_lock to semaphore Physical DSI bus is protected by a mutex. This patch changed the mutex to a semaphore, so that we can lock and unlock the bus_lock from different threads. This is needed as the update process is started by user space program, and thus the lock is acquired in that context, but the lock can be released in different context, a work thread via irq. Signed-off-by: Tomi Valkeinen --- drivers/video/omap2/dss/dsi.c | 20 ++++++-------------- 1 file changed, 6 insertions(+), 14 deletions(-) (limited to 'drivers') diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c index 928b5e44a3dd..53fc0f8cb1a0 100644 --- a/drivers/video/omap2/dss/dsi.c +++ b/drivers/video/omap2/dss/dsi.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #include #include @@ -227,7 +228,7 @@ static struct } vc[4]; struct mutex lock; - struct mutex bus_lock; + struct semaphore bus_lock; unsigned pll_locked; @@ -298,19 +299,19 @@ void dsi_restore_context(void) void dsi_bus_lock(void) { - mutex_lock(&dsi.bus_lock); + down(&dsi.bus_lock); } EXPORT_SYMBOL(dsi_bus_lock); void dsi_bus_unlock(void) { - mutex_unlock(&dsi.bus_lock); + up(&dsi.bus_lock); } EXPORT_SYMBOL(dsi_bus_unlock); static bool dsi_bus_is_locked(void) { - return mutex_is_locked(&dsi.bus_lock); + return dsi.bus_lock.count == 0; } static inline int wait_for_bit_change(const struct dsi_reg idx, int bitnum, @@ -3002,8 +3003,6 @@ static int dsi_update_thread(void *data) u16 x, y, w, h; while (1) { - bool sched; - wait_event_interruptible(dsi.waitqueue, dsi.update_mode == OMAP_DSS_UPDATE_AUTO || (dsi.update_mode == OMAP_DSS_UPDATE_MANUAL && @@ -3089,16 +3088,9 @@ static int dsi_update_thread(void *data) dsi_perf_show("L4"); } - sched = atomic_read(&dsi.bus_lock.count) < 0; - complete_all(&dsi.update_completion); dsi_bus_unlock(); - - /* XXX We need to give others chance to get the bus lock. Is - * there a better way for this? */ - if (dsi.update_mode == OMAP_DSS_UPDATE_AUTO && sched) - schedule_timeout_interruptible(1); } DSSDBG("update thread exiting\n"); @@ -3798,7 +3790,7 @@ int dsi_init(struct platform_device *pdev) spin_lock_init(&dsi.update_lock); mutex_init(&dsi.lock); - mutex_init(&dsi.bus_lock); + sema_init(&dsi.bus_lock, 1); #ifdef DSI_CATCH_MISSING_TE init_timer(&dsi.te_timer); -- cgit v1.2.2 From 1bbb275e261eb204795d4a48b3e485f2ad3d627c Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Mon, 11 Jan 2010 16:41:10 +0200 Subject: OMAP: DSS2: DSI: remove auto-update perf measurement Remove performance measurement for auto-update. Auto-update and thus performance measurement cannot be supported after the driver change where the control is moved to display drivers. This is part of a larger patch-set, which moves the control from omapdss driver to the display driver. Signed-off-by: Tomi Valkeinen --- drivers/video/omap2/dss/dsi.c | 81 +++++-------------------------------------- 1 file changed, 9 insertions(+), 72 deletions(-) (limited to 'drivers') diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c index 53fc0f8cb1a0..65c062f2862c 100644 --- a/drivers/video/omap2/dss/dsi.c +++ b/drivers/video/omap2/dss/dsi.c @@ -261,8 +261,6 @@ static struct #ifdef DEBUG ktime_t perf_setup_time; ktime_t perf_start_time; - ktime_t perf_start_time_auto; - int perf_measure_frames; #endif int debug_read; int debug_write; @@ -338,12 +336,6 @@ static void dsi_perf_mark_start(void) dsi.perf_start_time = ktime_get(); } -static void dsi_perf_mark_start_auto(void) -{ - dsi.perf_measure_frames = 0; - dsi.perf_start_time_auto = ktime_get(); -} - static void dsi_perf_show(const char *name) { ktime_t t, setup_time, trans_time; @@ -374,72 +366,19 @@ static void dsi_perf_show(const char *name) dsi.active_update_region.h * dsi.active_update_region.device->ctrl.pixel_size / 8; - if (dsi.update_mode == OMAP_DSS_UPDATE_AUTO) { - static u32 s_total_trans_us, s_total_setup_us; - static u32 s_min_trans_us = 0xffffffff, s_min_setup_us; - static u32 s_max_trans_us, s_max_setup_us; - const int numframes = 100; - ktime_t total_time_auto; - u32 total_time_auto_us; - - dsi.perf_measure_frames++; - - if (setup_us < s_min_setup_us) - s_min_setup_us = setup_us; - - if (setup_us > s_max_setup_us) - s_max_setup_us = setup_us; - - s_total_setup_us += setup_us; - - if (trans_us < s_min_trans_us) - s_min_trans_us = trans_us; - - if (trans_us > s_max_trans_us) - s_max_trans_us = trans_us; - - s_total_trans_us += trans_us; - - if (dsi.perf_measure_frames < numframes) - return; - - total_time_auto = ktime_sub(t, dsi.perf_start_time_auto); - total_time_auto_us = (u32)ktime_to_us(total_time_auto); - - printk(KERN_INFO "DSI(%s): %u fps, setup %u/%u/%u, " - "trans %u/%u/%u\n", - name, - 1000 * 1000 * numframes / total_time_auto_us, - s_min_setup_us, - s_max_setup_us, - s_total_setup_us / numframes, - s_min_trans_us, - s_max_trans_us, - s_total_trans_us / numframes); - - s_total_setup_us = 0; - s_min_setup_us = 0xffffffff; - s_max_setup_us = 0; - s_total_trans_us = 0; - s_min_trans_us = 0xffffffff; - s_max_trans_us = 0; - dsi_perf_mark_start_auto(); - } else { - printk(KERN_INFO "DSI(%s): %u us + %u us = %u us (%uHz), " - "%u bytes, %u kbytes/sec\n", - name, - setup_us, - trans_us, - total_us, - 1000*1000 / total_us, - total_bytes, - total_bytes * 1000 / total_us); - } + printk(KERN_INFO "DSI(%s): %u us + %u us = %u us (%uHz), " + "%u bytes, %u kbytes/sec\n", + name, + setup_us, + trans_us, + total_us, + 1000*1000 / total_us, + total_bytes, + total_bytes * 1000 / total_us); } #else #define dsi_perf_mark_setup() #define dsi_perf_mark_start() -#define dsi_perf_mark_start_auto() #define dsi_perf_show(x) #endif @@ -2933,8 +2872,6 @@ static int dsi_set_update_mode(struct omap_dss_device *dssdev, dsi_set_update_region(dssdev, 0, 0, w, h); - dsi_perf_mark_start_auto(); - wake_up(&dsi.waitqueue); } } -- cgit v1.2.2 From 1a75ef422d0d1319bc0fab66b0bf339069519d8c Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Fri, 8 Jan 2010 16:21:28 +0200 Subject: OMAP: DSS2: move run_test() Move run_test() from omap_dss_device to omap_dss_driver. This is part of a larger patch-set, which moves the control from omapdss driver to the display driver. Signed-off-by: Tomi Valkeinen --- drivers/video/omap2/displays/panel-taal.c | 12 +++++++--- drivers/video/omap2/dss/dsi.c | 38 ------------------------------- drivers/video/omap2/omapfb/omapfb-ioctl.c | 8 +++---- 3 files changed, 13 insertions(+), 45 deletions(-) (limited to 'drivers') diff --git a/drivers/video/omap2/displays/panel-taal.c b/drivers/video/omap2/displays/panel-taal.c index 0aaaa8a8e0f5..e6d0954f459f 100644 --- a/drivers/video/omap2/displays/panel-taal.c +++ b/drivers/video/omap2/displays/panel-taal.c @@ -820,17 +820,23 @@ static int taal_run_test(struct omap_dss_device *dssdev, int test_num) u8 id1, id2, id3; int r; + dsi_bus_lock(); + r = taal_dcs_read_1(DCS_GET_ID1, &id1); if (r) - return r; + goto err; r = taal_dcs_read_1(DCS_GET_ID2, &id2); if (r) - return r; + goto err; r = taal_dcs_read_1(DCS_GET_ID3, &id3); if (r) - return r; + goto err; + dsi_bus_unlock(); return 0; +err: + dsi_bus_unlock(); + return r; } static int taal_memory_read(struct omap_dss_device *dssdev, diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c index 65c062f2862c..f01c9ca0fa5f 100644 --- a/drivers/video/omap2/dss/dsi.c +++ b/drivers/video/omap2/dss/dsi.c @@ -3584,43 +3584,6 @@ static bool dsi_display_get_mirror(struct omap_dss_device *dssdev) return dssdev->driver->get_mirror(dssdev); } -static int dsi_display_run_test(struct omap_dss_device *dssdev, int test_num) -{ - int r; - - if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE) - return -EIO; - - DSSDBGF("%d", test_num); - - dsi_bus_lock(); - - /* run test first in low speed mode */ - omapdss_dsi_vc_enable_hs(0, 0); - - if (dssdev->driver->run_test) { - r = dssdev->driver->run_test(dssdev, test_num); - if (r) - goto end; - } - - /* then in high speed */ - omapdss_dsi_vc_enable_hs(0, 1); - - if (dssdev->driver->run_test) { - r = dssdev->driver->run_test(dssdev, test_num); - if (r) - goto end; - } - -end: - omapdss_dsi_vc_enable_hs(0, 1); - - dsi_bus_unlock(); - - return r; -} - static int dsi_display_memory_read(struct omap_dss_device *dssdev, void *buf, size_t size, u16 x, u16 y, u16 w, u16 h) @@ -3683,7 +3646,6 @@ int dsi_init_display(struct omap_dss_device *dssdev) dssdev->get_mirror = dsi_display_get_mirror; dssdev->set_mirror = dsi_display_set_mirror; - dssdev->run_test = dsi_display_run_test; dssdev->memory_read = dsi_display_memory_read; /* XXX these should be figured out dynamically */ diff --git a/drivers/video/omap2/omapfb/omapfb-ioctl.c b/drivers/video/omap2/omapfb/omapfb-ioctl.c index 33fc1459a7c9..6dc9b5c587a5 100644 --- a/drivers/video/omap2/omapfb/omapfb-ioctl.c +++ b/drivers/video/omap2/omapfb/omapfb-ioctl.c @@ -670,12 +670,12 @@ int omapfb_ioctl(struct fb_info *fbi, unsigned int cmd, unsigned long arg) r = -EFAULT; break; } - if (!display || !display->run_test) { + if (!display || !display->driver->run_test) { r = -EINVAL; break; } - r = display->run_test(display, p.test_num); + r = display->driver->run_test(display, p.test_num); break; @@ -685,12 +685,12 @@ int omapfb_ioctl(struct fb_info *fbi, unsigned int cmd, unsigned long arg) r = -EFAULT; break; } - if (!display || !display->run_test) { + if (!display || !display->driver->run_test) { r = -EINVAL; break; } - r = display->run_test(display, p.test_num); + r = display->driver->run_test(display, p.test_num); break; -- cgit v1.2.2 From c75d9464c1fa315796e78468bfaf32f2ce676fed Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Fri, 8 Jan 2010 16:56:44 +0200 Subject: OMAP: DSS2: move memory_read() Move memory_read() from omap_dss_device to omap_dss_driver. This is part of a larger patch-set, which moves the control from omapdss driver to the display driver. Signed-off-by: Tomi Valkeinen --- drivers/video/omap2/displays/panel-taal.c | 13 ++++++++++--- drivers/video/omap2/dss/dsi.c | 30 ------------------------------ drivers/video/omap2/omapfb/omapfb-ioctl.c | 4 ++-- 3 files changed, 12 insertions(+), 35 deletions(-) (limited to 'drivers') diff --git a/drivers/video/omap2/displays/panel-taal.c b/drivers/video/omap2/displays/panel-taal.c index e6d0954f459f..5f78d3851d91 100644 --- a/drivers/video/omap2/displays/panel-taal.c +++ b/drivers/video/omap2/displays/panel-taal.c @@ -847,6 +847,10 @@ static int taal_memory_read(struct omap_dss_device *dssdev, int first = 1; int plen; unsigned buf_used = 0; + struct taal_data *td = dev_get_drvdata(&dssdev->dev); + + if (!td->enabled) + return -ENODEV; if (size < w * h * 3) return -ENOMEM; @@ -855,6 +859,8 @@ static int taal_memory_read(struct omap_dss_device *dssdev, dssdev->panel.timings.x_res * dssdev->panel.timings.y_res * 3); + dsi_bus_lock(); + /* plen 1 or 2 goes into short packet. until checksum error is fixed, * use short packets. plen 32 works, but bigger packets seem to cause * an error. */ @@ -863,11 +869,11 @@ static int taal_memory_read(struct omap_dss_device *dssdev, else plen = 2; - taal_setup_update(dssdev, x, y, w, h); + taal_set_update_window(x, y, w, h); r = dsi_vc_set_max_rx_packet_size(TCH, plen); if (r) - return r; + goto err0; while (buf_used < size) { u8 dcs_cmd = first ? 0x2e : 0x3e; @@ -900,7 +906,8 @@ static int taal_memory_read(struct omap_dss_device *dssdev, err: dsi_vc_set_max_rx_packet_size(TCH, 1); - +err0: + dsi_bus_unlock(); return r; } diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c index f01c9ca0fa5f..638d8c29e9d9 100644 --- a/drivers/video/omap2/dss/dsi.c +++ b/drivers/video/omap2/dss/dsi.c @@ -3584,34 +3584,6 @@ static bool dsi_display_get_mirror(struct omap_dss_device *dssdev) return dssdev->driver->get_mirror(dssdev); } -static int dsi_display_memory_read(struct omap_dss_device *dssdev, - void *buf, size_t size, - u16 x, u16 y, u16 w, u16 h) -{ - int r; - - DSSDBGF(""); - - if (!dssdev->driver->memory_read) - return -EINVAL; - - if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE) - return -EIO; - - dsi_bus_lock(); - - r = dssdev->driver->memory_read(dssdev, buf, size, - x, y, w, h); - - /* Memory read usually changes the update area. This will - * force the next update to re-set the update area */ - dsi.active_update_region.dirty = true; - - dsi_bus_unlock(); - - return r; -} - void dsi_get_overlay_fifo_thresholds(enum omap_plane plane, u32 fifo_size, enum omap_burst_size *burst_size, u32 *fifo_low, u32 *fifo_high) @@ -3646,8 +3618,6 @@ int dsi_init_display(struct omap_dss_device *dssdev) dssdev->get_mirror = dsi_display_get_mirror; dssdev->set_mirror = dsi_display_set_mirror; - dssdev->memory_read = dsi_display_memory_read; - /* XXX these should be figured out dynamically */ dssdev->caps = OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE | OMAP_DSS_DISPLAY_CAP_TEAR_ELIM; diff --git a/drivers/video/omap2/omapfb/omapfb-ioctl.c b/drivers/video/omap2/omapfb/omapfb-ioctl.c index 6dc9b5c587a5..6e0186edc7da 100644 --- a/drivers/video/omap2/omapfb/omapfb-ioctl.c +++ b/drivers/video/omap2/omapfb/omapfb-ioctl.c @@ -374,7 +374,7 @@ static int omapfb_memory_read(struct fb_info *fbi, void *buf; int r; - if (!display || !display->memory_read) + if (!display || !display->driver->memory_read) return -ENOENT; if (!access_ok(VERIFY_WRITE, mr->buffer, mr->buffer_size)) @@ -389,7 +389,7 @@ static int omapfb_memory_read(struct fb_info *fbi, return -ENOMEM; } - r = display->memory_read(display, buf, mr->buffer_size, + r = display->driver->memory_read(display, buf, mr->buffer_size, mr->x, mr->y, mr->w, mr->h); if (r > 0) { -- cgit v1.2.2 From 8d8aa61dcf8721021cd5c0c86a14ef944535fa54 Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Fri, 8 Jan 2010 16:30:33 +0200 Subject: OMAP: DSS2: move set/get_mirror() Move set/get_mirror() from omap_dss_device to omap_dss_driver. This is part of a larger patch-set, which moves the control from omapdss driver to the display driver. Signed-off-by: Tomi Valkeinen --- drivers/video/omap2/displays/panel-taal.c | 8 ++++++-- drivers/video/omap2/dss/display.c | 8 ++++---- drivers/video/omap2/dss/dsi.c | 25 ------------------------- 3 files changed, 10 insertions(+), 31 deletions(-) (limited to 'drivers') diff --git a/drivers/video/omap2/displays/panel-taal.c b/drivers/video/omap2/displays/panel-taal.c index 5f78d3851d91..4d644497431d 100644 --- a/drivers/video/omap2/displays/panel-taal.c +++ b/drivers/video/omap2/displays/panel-taal.c @@ -797,16 +797,20 @@ static int taal_mirror(struct omap_dss_device *dssdev, bool enable) dev_dbg(&dssdev->dev, "mirror %d\n", enable); + dsi_bus_lock(); if (td->enabled) { r = taal_set_addr_mode(td->rotate, enable); - if (r) - return r; + goto err; } td->mirror = enable; + dsi_bus_unlock(); return 0; +err: + dsi_bus_unlock(); + return r; } static bool taal_get_mirror(struct omap_dss_device *dssdev) diff --git a/drivers/video/omap2/dss/display.c b/drivers/video/omap2/dss/display.c index 3f345b8cbcb0..8b9179668f48 100644 --- a/drivers/video/omap2/dss/display.c +++ b/drivers/video/omap2/dss/display.c @@ -215,9 +215,9 @@ static ssize_t display_mirror_show(struct device *dev, { struct omap_dss_device *dssdev = to_dss_device(dev); int mirror; - if (!dssdev->get_mirror) + if (!dssdev->driver->get_mirror) return -ENOENT; - mirror = dssdev->get_mirror(dssdev); + mirror = dssdev->driver->get_mirror(dssdev); return snprintf(buf, PAGE_SIZE, "%u\n", mirror); } @@ -228,12 +228,12 @@ static ssize_t display_mirror_store(struct device *dev, unsigned long mirror; int r; - if (!dssdev->set_mirror || !dssdev->get_mirror) + if (!dssdev->driver->set_mirror || !dssdev->driver->get_mirror) return -ENOENT; mirror = simple_strtoul(buf, NULL, 0); - r = dssdev->set_mirror(dssdev, mirror); + r = dssdev->driver->set_mirror(dssdev, mirror); if (r) return r; diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c index 638d8c29e9d9..2f356d471b0e 100644 --- a/drivers/video/omap2/dss/dsi.c +++ b/drivers/video/omap2/dss/dsi.c @@ -3562,28 +3562,6 @@ static u8 dsi_display_get_rotate(struct omap_dss_device *dssdev) return dssdev->driver->get_rotate(dssdev); } -static int dsi_display_set_mirror(struct omap_dss_device *dssdev, bool mirror) -{ - DSSDBGF("%d", mirror); - - if (!dssdev->driver->set_mirror || !dssdev->driver->get_mirror) - return -EINVAL; - - dsi_bus_lock(); - dssdev->driver->set_mirror(dssdev, mirror); - dsi_bus_unlock(); - - return 0; -} - -static bool dsi_display_get_mirror(struct omap_dss_device *dssdev) -{ - if (!dssdev->driver->set_mirror || !dssdev->driver->get_mirror) - return 0; - - return dssdev->driver->get_mirror(dssdev); -} - void dsi_get_overlay_fifo_thresholds(enum omap_plane plane, u32 fifo_size, enum omap_burst_size *burst_size, u32 *fifo_low, u32 *fifo_high) @@ -3615,9 +3593,6 @@ int dsi_init_display(struct omap_dss_device *dssdev) dssdev->get_rotate = dsi_display_get_rotate; dssdev->set_rotate = dsi_display_set_rotate; - dssdev->get_mirror = dsi_display_get_mirror; - dssdev->set_mirror = dsi_display_set_mirror; - /* XXX these should be figured out dynamically */ dssdev->caps = OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE | OMAP_DSS_DISPLAY_CAP_TEAR_ELIM; -- cgit v1.2.2 From 87424e1bffeaea7bf9e2b8afc16fe584a8641e5e Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Fri, 8 Jan 2010 16:52:48 +0200 Subject: OMAP: DSS2: move get/set_rotate() Move get/set_rotate() from omap_dss_device to omap_dss_driver. This is part of a larger patch-set, which moves the control from omapdss driver to the display driver. Signed-off-by: Tomi Valkeinen --- drivers/video/omap2/displays/panel-taal.c | 9 +++++++-- drivers/video/omap2/dss/display.c | 8 ++++---- drivers/video/omap2/dss/dsi.c | 33 ------------------------------- 3 files changed, 11 insertions(+), 39 deletions(-) (limited to 'drivers') diff --git a/drivers/video/omap2/displays/panel-taal.c b/drivers/video/omap2/displays/panel-taal.c index 4d644497431d..8f90de0d2b4b 100644 --- a/drivers/video/omap2/displays/panel-taal.c +++ b/drivers/video/omap2/displays/panel-taal.c @@ -772,16 +772,21 @@ static int taal_rotate(struct omap_dss_device *dssdev, u8 rotate) dev_dbg(&dssdev->dev, "rotate %d\n", rotate); + dsi_bus_lock(); + if (td->enabled) { r = taal_set_addr_mode(rotate, td->mirror); - if (r) - return r; + goto err; } td->rotate = rotate; + dsi_bus_unlock(); return 0; +err: + dsi_bus_unlock(); + return r; } static u8 taal_get_rotate(struct omap_dss_device *dssdev) diff --git a/drivers/video/omap2/dss/display.c b/drivers/video/omap2/dss/display.c index 8b9179668f48..263d2fd93bac 100644 --- a/drivers/video/omap2/dss/display.c +++ b/drivers/video/omap2/dss/display.c @@ -185,9 +185,9 @@ static ssize_t display_rotate_show(struct device *dev, { struct omap_dss_device *dssdev = to_dss_device(dev); int rotate; - if (!dssdev->get_rotate) + if (!dssdev->driver->get_rotate) return -ENOENT; - rotate = dssdev->get_rotate(dssdev); + rotate = dssdev->driver->get_rotate(dssdev); return snprintf(buf, PAGE_SIZE, "%u\n", rotate); } @@ -198,12 +198,12 @@ static ssize_t display_rotate_store(struct device *dev, unsigned long rot; int r; - if (!dssdev->set_rotate || !dssdev->get_rotate) + if (!dssdev->driver->set_rotate || !dssdev->driver->get_rotate) return -ENOENT; rot = simple_strtoul(buf, NULL, 0); - r = dssdev->set_rotate(dssdev, rot); + r = dssdev->driver->set_rotate(dssdev, rot); if (r) return r; diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c index 2f356d471b0e..82733d18c0ac 100644 --- a/drivers/video/omap2/dss/dsi.c +++ b/drivers/video/omap2/dss/dsi.c @@ -3532,36 +3532,6 @@ static int dsi_display_get_te(struct omap_dss_device *dssdev) return dsi.te_enabled; } -static int dsi_display_set_rotate(struct omap_dss_device *dssdev, u8 rotate) -{ - - DSSDBGF("%d", rotate); - - if (!dssdev->driver->set_rotate || !dssdev->driver->get_rotate) - return -EINVAL; - - dsi_bus_lock(); - dssdev->driver->set_rotate(dssdev, rotate); - if (dsi.update_mode == OMAP_DSS_UPDATE_AUTO) { - u16 w, h; - /* the display dimensions may have changed, so set a new - * update region */ - dssdev->get_resolution(dssdev, &w, &h); - dsi_set_update_region(dssdev, 0, 0, w, h); - } - dsi_bus_unlock(); - - return 0; -} - -static u8 dsi_display_get_rotate(struct omap_dss_device *dssdev) -{ - if (!dssdev->driver->set_rotate || !dssdev->driver->get_rotate) - return 0; - - return dssdev->driver->get_rotate(dssdev); -} - void dsi_get_overlay_fifo_thresholds(enum omap_plane plane, u32 fifo_size, enum omap_burst_size *burst_size, u32 *fifo_low, u32 *fifo_high) @@ -3590,9 +3560,6 @@ int dsi_init_display(struct omap_dss_device *dssdev) dssdev->enable_te = dsi_display_enable_te; dssdev->get_te = dsi_display_get_te; - dssdev->get_rotate = dsi_display_get_rotate; - dssdev->set_rotate = dsi_display_set_rotate; - /* XXX these should be figured out dynamically */ dssdev->caps = OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE | OMAP_DSS_DISPLAY_CAP_TEAR_ELIM; -- cgit v1.2.2 From 3f71cbe736e7e9909559fcc4463f43e4b4b348a8 Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Fri, 8 Jan 2010 17:06:04 +0200 Subject: OMAP: DSS2: move wait_vsync() Move wait_vsync() from omap_dss_device to overlay manager. This is part of a larger patch-set, which moves the control from omapdss driver to the display driver. Signed-off-by: Tomi Valkeinen --- drivers/video/omap2/dss/display.c | 14 -------------- drivers/video/omap2/dss/manager.c | 14 ++++++++++++++ drivers/video/omap2/omapfb/omapfb-ioctl.c | 2 +- 3 files changed, 15 insertions(+), 15 deletions(-) (limited to 'drivers') diff --git a/drivers/video/omap2/dss/display.c b/drivers/video/omap2/dss/display.c index 263d2fd93bac..80b67d1c9d03 100644 --- a/drivers/video/omap2/dss/display.c +++ b/drivers/video/omap2/dss/display.c @@ -323,19 +323,6 @@ void default_get_overlay_fifo_thresholds(enum omap_plane plane, *fifo_low = fifo_size - burst_size_bytes; } -static int default_wait_vsync(struct omap_dss_device *dssdev) -{ - unsigned long timeout = msecs_to_jiffies(500); - u32 irq; - - if (dssdev->type == OMAP_DISPLAY_TYPE_VENC) - irq = DISPC_IRQ_EVSYNC_ODD; - else - irq = DISPC_IRQ_VSYNC; - - return omap_dispc_wait_for_irq_interruptible_timeout(irq, timeout); -} - static int default_get_recommended_bpp(struct omap_dss_device *dssdev) { if (dssdev->panel.recommended_bpp) @@ -427,7 +414,6 @@ void dss_init_device(struct platform_device *pdev, dssdev->get_resolution = default_get_resolution; dssdev->get_recommended_bpp = default_get_recommended_bpp; - dssdev->wait_vsync = default_wait_vsync; switch (dssdev->type) { case OMAP_DISPLAY_TYPE_DPI: diff --git a/drivers/video/omap2/dss/manager.c b/drivers/video/omap2/dss/manager.c index 27d9c465c851..486cd4aec652 100644 --- a/drivers/video/omap2/dss/manager.c +++ b/drivers/video/omap2/dss/manager.c @@ -501,6 +501,19 @@ static int omap_dss_unset_device(struct omap_overlay_manager *mgr) return 0; } +static int dss_mgr_wait_for_vsync(struct omap_overlay_manager *mgr) +{ + unsigned long timeout = msecs_to_jiffies(500); + u32 irq; + + if (mgr->device->type == OMAP_DISPLAY_TYPE_VENC) + irq = DISPC_IRQ_EVSYNC_ODD; + else + irq = DISPC_IRQ_VSYNC; + + return omap_dispc_wait_for_irq_interruptible_timeout(irq, timeout); +} + static int dss_mgr_wait_for_go(struct omap_overlay_manager *mgr) { unsigned long timeout = msecs_to_jiffies(500); @@ -1394,6 +1407,7 @@ int dss_init_overlay_managers(struct platform_device *pdev) mgr->set_manager_info = &omap_dss_mgr_set_info; mgr->get_manager_info = &omap_dss_mgr_get_info; mgr->wait_for_go = &dss_mgr_wait_for_go; + mgr->wait_for_vsync = &dss_mgr_wait_for_vsync; mgr->caps = OMAP_DSS_OVL_MGR_CAP_DISPC; diff --git a/drivers/video/omap2/omapfb/omapfb-ioctl.c b/drivers/video/omap2/omapfb/omapfb-ioctl.c index 6e0186edc7da..36afab30921e 100644 --- a/drivers/video/omap2/omapfb/omapfb-ioctl.c +++ b/drivers/video/omap2/omapfb/omapfb-ioctl.c @@ -649,7 +649,7 @@ int omapfb_ioctl(struct fb_info *fbi, unsigned int cmd, unsigned long arg) break; } - r = display->wait_vsync(display); + r = display->manager->wait_for_vsync(display->manager); break; case OMAPFB_WAITFORGO: -- cgit v1.2.2 From a2faee84f6d8e35150d60514c6638d223509fa13 Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Fri, 8 Jan 2010 17:14:53 +0200 Subject: OMAP: DSS2: move enable/disable_channel to overlay manager Move enable/disable_channel() from omap_dss_device to overlay manager. This is part of a larger patch-set, which moves the control from omapdss driver to the display driver. Signed-off-by: Tomi Valkeinen --- drivers/video/omap2/dss/dispc.c | 24 ++++++++++++++++++++++-- drivers/video/omap2/dss/dpi.c | 14 +++++++------- drivers/video/omap2/dss/dsi.c | 2 +- drivers/video/omap2/dss/dss.h | 4 ++-- drivers/video/omap2/dss/manager.c | 17 ++++++++++++++++- drivers/video/omap2/dss/rfbi.c | 2 +- drivers/video/omap2/dss/sdi.c | 14 +++++++------- drivers/video/omap2/dss/venc.c | 4 ++-- 8 files changed, 58 insertions(+), 23 deletions(-) (limited to 'drivers') diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c index 212cb800a5d2..5a5c31c163c7 100644 --- a/drivers/video/omap2/dss/dispc.c +++ b/drivers/video/omap2/dss/dispc.c @@ -1725,7 +1725,7 @@ static void _enable_lcd_out(bool enable) REG_FLD_MOD(DISPC_CONTROL, enable ? 1 : 0, 0, 0); } -void dispc_enable_lcd_out(bool enable) +static void dispc_enable_lcd_out(bool enable) { struct completion frame_done_completion; bool is_on; @@ -1772,7 +1772,7 @@ static void _enable_digit_out(bool enable) REG_FLD_MOD(DISPC_CONTROL, enable ? 1 : 0, 1, 1); } -void dispc_enable_digit_out(bool enable) +static void dispc_enable_digit_out(bool enable) { struct completion frame_done_completion; int r; @@ -1836,6 +1836,26 @@ void dispc_enable_digit_out(bool enable) enable_clocks(0); } +bool dispc_is_channel_enabled(enum omap_channel channel) +{ + if (channel == OMAP_DSS_CHANNEL_LCD) + return !!REG_GET(DISPC_CONTROL, 0, 0); + else if (channel == OMAP_DSS_CHANNEL_DIGIT) + return !!REG_GET(DISPC_CONTROL, 1, 1); + else + BUG(); +} + +void dispc_enable_channel(enum omap_channel channel, bool enable) +{ + if (channel == OMAP_DSS_CHANNEL_LCD) + dispc_enable_lcd_out(enable); + else if (channel == OMAP_DSS_CHANNEL_DIGIT) + dispc_enable_digit_out(enable); + else + BUG(); +} + void dispc_lcd_enable_signal_polarity(bool act_high) { enable_clocks(1); diff --git a/drivers/video/omap2/dss/dpi.c b/drivers/video/omap2/dss/dpi.c index c5091ed12a7d..77b95577ab30 100644 --- a/drivers/video/omap2/dss/dpi.c +++ b/drivers/video/omap2/dss/dpi.c @@ -194,7 +194,7 @@ static int dpi_display_enable(struct omap_dss_device *dssdev) mdelay(2); - dispc_enable_lcd_out(1); + dssdev->manager->enable(dssdev->manager); r = dssdev->driver->enable(dssdev); if (r) @@ -205,7 +205,7 @@ static int dpi_display_enable(struct omap_dss_device *dssdev) return 0; err6: - dispc_enable_lcd_out(0); + dssdev->manager->disable(dssdev->manager); err5: #ifdef CONFIG_OMAP2_DSS_USE_DSI_PLL dsi_pll_uninit(); @@ -235,7 +235,7 @@ static void dpi_display_disable(struct omap_dss_device *dssdev) dssdev->driver->disable(dssdev); - dispc_enable_lcd_out(0); + dssdev->manager->disable(dssdev->manager); #ifdef CONFIG_OMAP2_DSS_USE_DSI_PLL dss_select_dispc_clk_source(DSS_SRC_DSS1_ALWON_FCLK); @@ -263,7 +263,7 @@ static int dpi_display_suspend(struct omap_dss_device *dssdev) if (dssdev->driver->suspend) dssdev->driver->suspend(dssdev); - dispc_enable_lcd_out(0); + dssdev->manager->disable(dssdev->manager); dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1); @@ -292,7 +292,7 @@ static int dpi_display_resume(struct omap_dss_device *dssdev) dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1); - dispc_enable_lcd_out(1); + dssdev->manager->enable(dssdev->manager); if (dssdev->driver->resume) dssdev->driver->resume(dssdev); @@ -383,10 +383,10 @@ static int dpi_display_set_update_mode(struct omap_dss_device *dssdev, return -EINVAL; if (mode == OMAP_DSS_UPDATE_DISABLED) { - dispc_enable_lcd_out(0); + dssdev->manager->disable(dssdev->manager); dpi.update_enabled = 0; } else { - dispc_enable_lcd_out(1); + dssdev->manager->enable(dssdev->manager); dpi.update_enabled = 1; } diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c index 82733d18c0ac..b478a506e038 100644 --- a/drivers/video/omap2/dss/dsi.c +++ b/drivers/video/omap2/dss/dsi.c @@ -3013,7 +3013,7 @@ static int dsi_update_thread(void *data) x, y, w, h); dispc_enable_sidle(); - dispc_enable_lcd_out(0); + device->manager->disable(device->manager); dsi_reset_tx_fifo(0); } else { diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h index 3713dc698259..24326a5fd292 100644 --- a/drivers/video/omap2/dss/dss.h +++ b/drivers/video/omap2/dss/dss.h @@ -324,8 +324,8 @@ int dispc_setup_plane(enum omap_plane plane, bool dispc_go_busy(enum omap_channel channel); void dispc_go(enum omap_channel channel); -void dispc_enable_lcd_out(bool enable); -void dispc_enable_digit_out(bool enable); +void dispc_enable_channel(enum omap_channel channel, bool enable); +bool dispc_is_channel_enabled(enum omap_channel channel); int dispc_enable_plane(enum omap_plane plane, bool enable); void dispc_enable_replication(enum omap_plane plane, bool enable); diff --git a/drivers/video/omap2/dss/manager.c b/drivers/video/omap2/dss/manager.c index 486cd4aec652..4ede519c0a31 100644 --- a/drivers/video/omap2/dss/manager.c +++ b/drivers/video/omap2/dss/manager.c @@ -1077,7 +1077,7 @@ void dss_start_update(struct omap_dss_device *dssdev) mc->shadow_dirty = false; } - dispc_enable_lcd_out(1); + dssdev->manager->enable(dssdev->manager); } static void dss_apply_irq_handler(void *data, u32 mask) @@ -1364,6 +1364,18 @@ static void omap_dss_mgr_get_info(struct omap_overlay_manager *mgr, *info = mgr->info; } +static int dss_mgr_enable(struct omap_overlay_manager *mgr) +{ + dispc_enable_channel(mgr->id, 1); + return 0; +} + +static int dss_mgr_disable(struct omap_overlay_manager *mgr) +{ + dispc_enable_channel(mgr->id, 0); + return 0; +} + static void omap_dss_add_overlay_manager(struct omap_overlay_manager *manager) { ++num_managers; @@ -1409,6 +1421,9 @@ int dss_init_overlay_managers(struct platform_device *pdev) mgr->wait_for_go = &dss_mgr_wait_for_go; mgr->wait_for_vsync = &dss_mgr_wait_for_vsync; + mgr->enable = &dss_mgr_enable; + mgr->disable = &dss_mgr_disable; + mgr->caps = OMAP_DSS_OVL_MGR_CAP_DISPC; dss_overlay_setup_dispc_manager(mgr); diff --git a/drivers/video/omap2/dss/rfbi.c b/drivers/video/omap2/dss/rfbi.c index b936495c065d..6b9cd767c7c1 100644 --- a/drivers/video/omap2/dss/rfbi.c +++ b/drivers/video/omap2/dss/rfbi.c @@ -382,7 +382,7 @@ void rfbi_transfer_area(u16 width, u16 height, dispc_set_lcd_size(width, height); - dispc_enable_lcd_out(1); + dispc_enable_channel(OMAP_DSS_CHANNEL_LCD, true); rfbi.framedone_callback = callback; rfbi.framedone_callback_data = data; diff --git a/drivers/video/omap2/dss/sdi.c b/drivers/video/omap2/dss/sdi.c index c24f307d3da1..5f852edd4cbc 100644 --- a/drivers/video/omap2/dss/sdi.c +++ b/drivers/video/omap2/dss/sdi.c @@ -119,7 +119,7 @@ static int sdi_display_enable(struct omap_dss_device *dssdev) mdelay(2); } - dispc_enable_lcd_out(1); + dssdev->manager->enable(dssdev->manager); if (dssdev->driver->enable) { r = dssdev->driver->enable(dssdev); @@ -133,7 +133,7 @@ static int sdi_display_enable(struct omap_dss_device *dssdev) return 0; err3: - dispc_enable_lcd_out(0); + dssdev->manager->disable(dssdev->manager); err2: dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1); err1: @@ -156,7 +156,7 @@ static void sdi_display_disable(struct omap_dss_device *dssdev) if (dssdev->driver->disable) dssdev->driver->disable(dssdev); - dispc_enable_lcd_out(0); + dssdev->manager->disable(dssdev->manager); dss_sdi_disable(); @@ -175,7 +175,7 @@ static int sdi_display_suspend(struct omap_dss_device *dssdev) if (dssdev->driver->suspend) dssdev->driver->suspend(dssdev); - dispc_enable_lcd_out(0); + dssdev->manager->disable(dssdev->manager); dss_sdi_disable(); @@ -200,7 +200,7 @@ static int sdi_display_resume(struct omap_dss_device *dssdev) goto err; mdelay(2); - dispc_enable_lcd_out(1); + dssdev->manager->enable(dssdev->manager); if (dssdev->driver->resume) dssdev->driver->resume(dssdev); @@ -220,10 +220,10 @@ static int sdi_display_set_update_mode(struct omap_dss_device *dssdev, return -EINVAL; if (mode == OMAP_DSS_UPDATE_DISABLED) { - dispc_enable_lcd_out(0); + dssdev->manager->disable(dssdev->manager); sdi.update_enabled = 0; } else { - dispc_enable_lcd_out(1); + dssdev->manager->enable(dssdev->manager); sdi.update_enabled = 1; } diff --git a/drivers/video/omap2/dss/venc.c b/drivers/video/omap2/dss/venc.c index 44b4998c2052..4e6bd1dc8021 100644 --- a/drivers/video/omap2/dss/venc.c +++ b/drivers/video/omap2/dss/venc.c @@ -538,7 +538,7 @@ static void venc_power_on(struct omap_dss_device *dssdev) if (dssdev->platform_enable) dssdev->platform_enable(dssdev); - dispc_enable_digit_out(1); + dssdev->manager->enable(dssdev->manager); } static void venc_power_off(struct omap_dss_device *dssdev) @@ -546,7 +546,7 @@ static void venc_power_off(struct omap_dss_device *dssdev) venc_write_reg(VENC_OUTPUT_CONTROL, 0); dss_set_dac_pwrdn_bgz(0); - dispc_enable_digit_out(0); + dssdev->manager->disable(dssdev->manager); if (dssdev->platform_disable) dssdev->platform_disable(dssdev); -- cgit v1.2.2 From 96adceceedefff9b849d25ff582bc6f516903994 Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Mon, 11 Jan 2010 13:54:33 +0200 Subject: OMAP: DSS2: move get_resolution() Move get_resolution() from omap_dss_device to omap_dss_driver. This is part of a larger patch-set, which moves the control from omapdss driver to the display driver. Signed-off-by: Tomi Valkeinen --- drivers/video/omap2/displays/panel-taal.c | 2 +- drivers/video/omap2/dss/core.c | 4 ++++ drivers/video/omap2/dss/display.c | 4 ++-- drivers/video/omap2/dss/dsi.c | 4 ++-- drivers/video/omap2/dss/overlay.c | 2 +- drivers/video/omap2/dss/venc.c | 2 ++ drivers/video/omap2/omapfb/omapfb-ioctl.c | 4 ++-- drivers/video/omap2/omapfb/omapfb-main.c | 9 +++++---- 8 files changed, 19 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/video/omap2/displays/panel-taal.c b/drivers/video/omap2/displays/panel-taal.c index 8f90de0d2b4b..11d69b67a903 100644 --- a/drivers/video/omap2/displays/panel-taal.c +++ b/drivers/video/omap2/displays/panel-taal.c @@ -517,7 +517,6 @@ static int taal_probe(struct omap_dss_device *dssdev) dev_set_drvdata(&dssdev->dev, td); dssdev->get_timings = taal_get_timings; - dssdev->get_resolution = taal_get_resolution; /* if no platform set_backlight() defined, presume DSI backlight * control */ @@ -990,6 +989,7 @@ static struct omap_dss_driver taal_driver = { .resume = taal_resume, .setup_update = taal_setup_update, + .get_resolution = taal_get_resolution, .enable_te = taal_enable_te, .wait_for_te = taal_wait_te, .set_rotate = taal_rotate, diff --git a/drivers/video/omap2/dss/core.c b/drivers/video/omap2/dss/core.c index 39b1a20a298c..2e6ce835ae5c 100644 --- a/drivers/video/omap2/dss/core.c +++ b/drivers/video/omap2/dss/core.c @@ -811,6 +811,10 @@ int omap_dss_register_driver(struct omap_dss_driver *dssdriver) dssdriver->driver.bus = &dss_bus_type; dssdriver->driver.probe = dss_driver_probe; dssdriver->driver.remove = dss_driver_remove; + + if (dssdriver->get_resolution == NULL) + dssdriver->get_resolution = omapdss_default_get_resolution; + return driver_register(&dssdriver->driver); } EXPORT_SYMBOL(omap_dss_register_driver); diff --git a/drivers/video/omap2/dss/display.c b/drivers/video/omap2/dss/display.c index 80b67d1c9d03..3888c191c8a7 100644 --- a/drivers/video/omap2/dss/display.c +++ b/drivers/video/omap2/dss/display.c @@ -303,12 +303,13 @@ static struct device_attribute *display_sysfs_attrs[] = { NULL }; -static void default_get_resolution(struct omap_dss_device *dssdev, +void omapdss_default_get_resolution(struct omap_dss_device *dssdev, u16 *xres, u16 *yres) { *xres = dssdev->panel.timings.x_res; *yres = dssdev->panel.timings.y_res; } +EXPORT_SYMBOL(omapdss_default_get_resolution); void default_get_overlay_fifo_thresholds(enum omap_plane plane, u32 fifo_size, enum omap_burst_size *burst_size, @@ -412,7 +413,6 @@ void dss_init_device(struct platform_device *pdev, return; } - dssdev->get_resolution = default_get_resolution; dssdev->get_recommended_bpp = default_get_recommended_bpp; switch (dssdev->type) { diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c index b478a506e038..abc66f2c0705 100644 --- a/drivers/video/omap2/dss/dsi.c +++ b/drivers/video/omap2/dss/dsi.c @@ -2868,7 +2868,7 @@ static int dsi_set_update_mode(struct omap_dss_device *dssdev, DSSDBG("starting auto update\n"); - dssdev->get_resolution(dssdev, &w, &h); + dssdev->driver->get_resolution(dssdev, &w, &h); dsi_set_update_region(dssdev, 0, 0, w, h); @@ -3422,7 +3422,7 @@ static int dsi_display_update(struct omap_dss_device *dssdev, if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE) goto end; - dssdev->get_resolution(dssdev, &dw, &dh); + dssdev->driver->get_resolution(dssdev, &dw, &dh); if (x > dw || y > dh) goto end; diff --git a/drivers/video/omap2/dss/overlay.c b/drivers/video/omap2/dss/overlay.c index b7f9a7339842..0c5bea263ac6 100644 --- a/drivers/video/omap2/dss/overlay.c +++ b/drivers/video/omap2/dss/overlay.c @@ -350,7 +350,7 @@ int dss_check_overlay(struct omap_overlay *ovl, struct omap_dss_device *dssdev) return -EINVAL; } - dssdev->get_resolution(dssdev, &dw, &dh); + dssdev->driver->get_resolution(dssdev, &dw, &dh); DSSDBG("check_overlay %d: (%d,%d %dx%d -> %dx%d) disp (%dx%d)\n", ovl->id, diff --git a/drivers/video/omap2/dss/venc.c b/drivers/video/omap2/dss/venc.c index 4e6bd1dc8021..65514f0f52fd 100644 --- a/drivers/video/omap2/dss/venc.c +++ b/drivers/video/omap2/dss/venc.c @@ -459,6 +459,8 @@ static struct omap_dss_driver venc_driver = { .suspend = venc_panel_suspend, .resume = venc_panel_resume, + .get_resolution = omapdss_default_get_resolution, + .driver = { .name = "venc", .owner = THIS_MODULE, diff --git a/drivers/video/omap2/omapfb/omapfb-ioctl.c b/drivers/video/omap2/omapfb/omapfb-ioctl.c index 36afab30921e..6deabb94fd31 100644 --- a/drivers/video/omap2/omapfb/omapfb-ioctl.c +++ b/drivers/video/omap2/omapfb/omapfb-ioctl.c @@ -167,7 +167,7 @@ static int omapfb_update_window_nolock(struct fb_info *fbi, if (w == 0 || h == 0) return 0; - display->get_resolution(display, &dw, &dh); + display->driver->get_resolution(display, &dw, &dh); if (x + w > dw || y + h > dh) return -EINVAL; @@ -752,7 +752,7 @@ int omapfb_ioctl(struct fb_info *fbi, unsigned int cmd, unsigned long arg) break; } - display->get_resolution(display, &xres, &yres); + display->driver->get_resolution(display, &xres, &yres); p.display_info.xres = xres; p.display_info.yres = yres; diff --git a/drivers/video/omap2/omapfb/omapfb-main.c b/drivers/video/omap2/omapfb/omapfb-main.c index 6a383ab2bef2..212d2efb380c 100644 --- a/drivers/video/omap2/omapfb/omapfb-main.c +++ b/drivers/video/omap2/omapfb/omapfb-main.c @@ -1254,7 +1254,7 @@ exit: if (r == 0 && do_update && display->update) { u16 w, h; - display->get_resolution(display, &w, &h); + display->driver->get_resolution(display, &w, &h); r = display->update(display, 0, 0, w, h); } @@ -1427,7 +1427,7 @@ static int omapfb_alloc_fbmem_display(struct fb_info *fbi, unsigned long size, if (!size) { u16 w, h; - display->get_resolution(display, &w, &h); + display->driver->get_resolution(display, &w, &h); if (ofbi->rotation_type == OMAP_DSS_ROT_VRFB) { size = max(omap_vrfb_min_phys_size(w, h, bytespp), @@ -1745,7 +1745,7 @@ static int omapfb_fb_init(struct omapfb2_device *fbdev, struct fb_info *fbi) u16 w, h; int rotation = (var->rotate + ofbi->rotation[0]) % 4; - display->get_resolution(display, &w, &h); + display->driver->get_resolution(display, &w, &h); if (rotation == FB_ROTATE_CW || rotation == FB_ROTATE_CCW) { @@ -2197,7 +2197,8 @@ static int omapfb_probe(struct platform_device *pdev) def_display->set_update_mode(def_display, OMAP_DSS_UPDATE_MANUAL); - def_display->get_resolution(def_display, &w, &h); + def_display->driver->get_resolution(def_display, + &w, &h); def_display->update(def_display, 0, 0, w, h); #endif } else { -- cgit v1.2.2 From a269950405ab17ce3a604ddcd939709a4a7a747c Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Mon, 11 Jan 2010 14:33:40 +0200 Subject: OMAP: DSS2: move get_recommended_bpp() Move get_recommended_bpp() from omap_dss_device to omap_dss_driver. This is part of a larger patch-set, which moves the control from omapdss driver to the display driver. Signed-off-by: Tomi Valkeinen --- drivers/video/omap2/displays/panel-taal.c | 2 ++ drivers/video/omap2/dss/core.c | 3 +++ drivers/video/omap2/dss/display.c | 8 ++------ drivers/video/omap2/dss/venc.c | 1 + drivers/video/omap2/omapfb/omapfb-main.c | 31 ++++++++++++++++++++++++++----- drivers/video/omap2/omapfb/omapfb.h | 6 ++++++ 6 files changed, 40 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/video/omap2/displays/panel-taal.c b/drivers/video/omap2/displays/panel-taal.c index 11d69b67a903..e00502ea46e5 100644 --- a/drivers/video/omap2/displays/panel-taal.c +++ b/drivers/video/omap2/displays/panel-taal.c @@ -990,6 +990,8 @@ static struct omap_dss_driver taal_driver = { .setup_update = taal_setup_update, .get_resolution = taal_get_resolution, + .get_recommended_bpp = omapdss_default_get_recommended_bpp, + .enable_te = taal_enable_te, .wait_for_te = taal_wait_te, .set_rotate = taal_rotate, diff --git a/drivers/video/omap2/dss/core.c b/drivers/video/omap2/dss/core.c index 2e6ce835ae5c..7ebe50b335ed 100644 --- a/drivers/video/omap2/dss/core.c +++ b/drivers/video/omap2/dss/core.c @@ -814,6 +814,9 @@ int omap_dss_register_driver(struct omap_dss_driver *dssdriver) if (dssdriver->get_resolution == NULL) dssdriver->get_resolution = omapdss_default_get_resolution; + if (dssdriver->get_recommended_bpp == NULL) + dssdriver->get_recommended_bpp = + omapdss_default_get_recommended_bpp; return driver_register(&dssdriver->driver); } diff --git a/drivers/video/omap2/dss/display.c b/drivers/video/omap2/dss/display.c index 3888c191c8a7..af8aae7ef814 100644 --- a/drivers/video/omap2/dss/display.c +++ b/drivers/video/omap2/dss/display.c @@ -324,11 +324,8 @@ void default_get_overlay_fifo_thresholds(enum omap_plane plane, *fifo_low = fifo_size - burst_size_bytes; } -static int default_get_recommended_bpp(struct omap_dss_device *dssdev) +int omapdss_default_get_recommended_bpp(struct omap_dss_device *dssdev) { - if (dssdev->panel.recommended_bpp) - return dssdev->panel.recommended_bpp; - switch (dssdev->type) { case OMAP_DISPLAY_TYPE_DPI: if (dssdev->phy.dpi.data_lines == 24) @@ -350,6 +347,7 @@ static int default_get_recommended_bpp(struct omap_dss_device *dssdev) BUG(); } } +EXPORT_SYMBOL(omapdss_default_get_recommended_bpp); /* Checks if replication logic should be used. Only use for active matrix, * when overlay is in RGB12U or RGB16 mode, and LCD interface is @@ -413,8 +411,6 @@ void dss_init_device(struct platform_device *pdev, return; } - dssdev->get_recommended_bpp = default_get_recommended_bpp; - switch (dssdev->type) { case OMAP_DISPLAY_TYPE_DPI: r = dpi_init_display(dssdev); diff --git a/drivers/video/omap2/dss/venc.c b/drivers/video/omap2/dss/venc.c index 65514f0f52fd..d13071dd46e5 100644 --- a/drivers/video/omap2/dss/venc.c +++ b/drivers/video/omap2/dss/venc.c @@ -460,6 +460,7 @@ static struct omap_dss_driver venc_driver = { .resume = venc_panel_resume, .get_resolution = omapdss_default_get_resolution, + .get_recommended_bpp = omapdss_default_get_recommended_bpp, .driver = { .name = "venc", diff --git a/drivers/video/omap2/omapfb/omapfb-main.c b/drivers/video/omap2/omapfb/omapfb-main.c index 212d2efb380c..216ed80293b8 100644 --- a/drivers/video/omap2/omapfb/omapfb-main.c +++ b/drivers/video/omap2/omapfb/omapfb-main.c @@ -54,6 +54,8 @@ module_param_named(test, omapfb_test_pattern, bool, 0644); #endif static int omapfb_fb_init(struct omapfb2_device *fbdev, struct fb_info *fbi); +static int omapfb_get_recommended_bpp(struct omapfb2_device *fbdev, + struct omap_dss_device *dssdev); #ifdef DEBUG static void draw_pixel(struct fb_info *fbi, int x, int y, unsigned color) @@ -1404,6 +1406,7 @@ static int omapfb_alloc_fbmem_display(struct fb_info *fbi, unsigned long size, unsigned long paddr) { struct omapfb_info *ofbi = FB2OFB(fbi); + struct omapfb2_device *fbdev = ofbi->fbdev; struct omap_dss_device *display; int bytespp; @@ -1412,7 +1415,7 @@ static int omapfb_alloc_fbmem_display(struct fb_info *fbi, unsigned long size, if (!display) return 0; - switch (display->get_recommended_bpp(display)) { + switch (omapfb_get_recommended_bpp(fbdev, display)) { case 16: bytespp = 2; break; @@ -1760,7 +1763,7 @@ static int omapfb_fb_init(struct omapfb2_device *fbdev, struct fb_info *fbi) var->yres_virtual = var->yres; if (!var->bits_per_pixel) { - switch (display->get_recommended_bpp(display)) { + switch (omapfb_get_recommended_bpp(fbdev, display)) { case 16: var->bits_per_pixel = 16; break; @@ -2011,7 +2014,8 @@ static int omapfb_mode_to_timings(const char *mode_str, } } -static int omapfb_set_def_mode(struct omap_dss_device *display, char *mode_str) +static int omapfb_set_def_mode(struct omapfb2_device *fbdev, + struct omap_dss_device *display, char *mode_str) { int r; u8 bpp; @@ -2021,7 +2025,9 @@ static int omapfb_set_def_mode(struct omap_dss_device *display, char *mode_str) if (r) return r; - display->panel.recommended_bpp = bpp; + fbdev->bpp_overrides[fbdev->num_bpp_overrides].dssdev = display; + fbdev->bpp_overrides[fbdev->num_bpp_overrides].bpp = bpp; + ++fbdev->num_bpp_overrides; if (!display->check_timings || !display->set_timings) return -EINVAL; @@ -2035,6 +2041,21 @@ static int omapfb_set_def_mode(struct omap_dss_device *display, char *mode_str) return 0; } +static int omapfb_get_recommended_bpp(struct omapfb2_device *fbdev, + struct omap_dss_device *dssdev) +{ + int i; + + BUG_ON(dssdev->driver->get_recommended_bpp == NULL); + + for (i = 0; i < fbdev->num_bpp_overrides; ++i) { + if (dssdev == fbdev->bpp_overrides[i].dssdev) + return fbdev->bpp_overrides[i].bpp; + } + + return dssdev->driver->get_recommended_bpp(dssdev); +} + static int omapfb_parse_def_modes(struct omapfb2_device *fbdev) { char *str, *options, *this_opt; @@ -2073,7 +2094,7 @@ static int omapfb_parse_def_modes(struct omapfb2_device *fbdev) break; } - r = omapfb_set_def_mode(display, mode_str); + r = omapfb_set_def_mode(fbdev, display, mode_str); if (r) break; } diff --git a/drivers/video/omap2/omapfb/omapfb.h b/drivers/video/omap2/omapfb/omapfb.h index 4ae0b64b3f43..cd54fdbfd8bb 100644 --- a/drivers/video/omap2/omapfb/omapfb.h +++ b/drivers/video/omap2/omapfb/omapfb.h @@ -83,6 +83,12 @@ struct omapfb2_device { struct omap_overlay *overlays[10]; unsigned num_managers; struct omap_overlay_manager *managers[10]; + + unsigned num_bpp_overrides; + struct { + struct omap_dss_device *dssdev; + u8 bpp; + } bpp_overrides[10]; }; struct omapfb_colormode { -- cgit v1.2.2 From 225b650d41e7cdbf5cd322a461b04493caabed09 Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Mon, 11 Jan 2010 15:11:01 +0200 Subject: OMAP: DSS2: move enable/get_te() Move enable/get_te() from omap_dss_device to omap_dss_driver. This is part of a larger patch-set, which moves the control from omapdss driver to the display driver. Signed-off-by: Tomi Valkeinen --- drivers/video/omap2/displays/panel-taal.c | 18 +++++++++++ drivers/video/omap2/dss/display.c | 7 ++-- drivers/video/omap2/dss/dsi.c | 53 ++----------------------------- drivers/video/omap2/dss/rfbi.c | 7 ---- drivers/video/omap2/omapfb/omapfb-ioctl.c | 5 +-- drivers/video/omap2/omapfb/omapfb-main.c | 8 ++--- 6 files changed, 32 insertions(+), 66 deletions(-) (limited to 'drivers') diff --git a/drivers/video/omap2/displays/panel-taal.c b/drivers/video/omap2/displays/panel-taal.c index e00502ea46e5..af4b0b03b745 100644 --- a/drivers/video/omap2/displays/panel-taal.c +++ b/drivers/video/omap2/displays/panel-taal.c @@ -736,6 +736,8 @@ static int taal_enable_te(struct omap_dss_device *dssdev, bool enable) struct taal_data *td = dev_get_drvdata(&dssdev->dev); int r; + dsi_bus_lock(); + td->te_enabled = enable; if (enable) @@ -743,9 +745,23 @@ static int taal_enable_te(struct omap_dss_device *dssdev, bool enable) else r = taal_dcs_write_0(DCS_TEAR_OFF); + omapdss_dsi_enable_te(dssdev, enable); + + /* XXX for some reason, DSI TE breaks if we don't wait here. + * Panel bug? Needs more studying */ + msleep(100); + + dsi_bus_unlock(); + return r; } +static int taal_get_te(struct omap_dss_device *dssdev) +{ + struct taal_data *td = dev_get_drvdata(&dssdev->dev); + return td->te_enabled; +} + static int taal_wait_te(struct omap_dss_device *dssdev) { struct taal_data *td = dev_get_drvdata(&dssdev->dev); @@ -993,7 +1009,9 @@ static struct omap_dss_driver taal_driver = { .get_recommended_bpp = omapdss_default_get_recommended_bpp, .enable_te = taal_enable_te, + .get_te = taal_get_te, .wait_for_te = taal_wait_te, + .set_rotate = taal_rotate, .get_rotate = taal_get_rotate, .set_mirror = taal_mirror, diff --git a/drivers/video/omap2/dss/display.c b/drivers/video/omap2/dss/display.c index af8aae7ef814..383a8c82dae8 100644 --- a/drivers/video/omap2/dss/display.c +++ b/drivers/video/omap2/dss/display.c @@ -106,7 +106,8 @@ static ssize_t display_tear_show(struct device *dev, { struct omap_dss_device *dssdev = to_dss_device(dev); return snprintf(buf, PAGE_SIZE, "%d\n", - dssdev->get_te ? dssdev->get_te(dssdev) : 0); + dssdev->driver->get_te ? + dssdev->driver->get_te(dssdev) : 0); } static ssize_t display_tear_store(struct device *dev, @@ -116,12 +117,12 @@ static ssize_t display_tear_store(struct device *dev, unsigned long te; int r; - if (!dssdev->enable_te || !dssdev->get_te) + if (!dssdev->driver->enable_te || !dssdev->driver->get_te) return -ENOENT; te = simple_strtoul(buf, NULL, 0); - r = dssdev->enable_te(dssdev, te); + r = dssdev->driver->enable_te(dssdev, te); if (r) return r; diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c index abc66f2c0705..697a78b85807 100644 --- a/drivers/video/omap2/dss/dsi.c +++ b/drivers/video/omap2/dss/dsi.c @@ -2879,20 +2879,6 @@ static int dsi_set_update_mode(struct omap_dss_device *dssdev, return r; } -static int dsi_set_te(struct omap_dss_device *dssdev, bool enable) -{ - int r = 0; - - if (dssdev->driver->enable_te) { - r = dssdev->driver->enable_te(dssdev, enable); - /* XXX for some reason, DSI TE breaks if we don't wait here. - * Panel bug? Needs more studying */ - msleep(100); - } - - return r; -} - static void dsi_handle_framedone(void) { int r; @@ -3267,9 +3253,6 @@ static int dsi_display_enable(struct omap_dss_device *dssdev) dssdev->state = OMAP_DSS_DISPLAY_ACTIVE; dsi.use_ext_te = dssdev->phy.dsi.ext_te; - r = dsi_set_te(dssdev, dsi.te_enabled); - if (r) - goto err4; dsi_set_update_mode(dssdev, dsi.user_update_mode); @@ -3278,9 +3261,6 @@ static int dsi_display_enable(struct omap_dss_device *dssdev) return 0; -err4: - - dsi_display_uninit_dsi(dssdev); err3: dsi_display_uninit_dispc(dssdev); err2: @@ -3383,10 +3363,6 @@ static int dsi_display_resume(struct omap_dss_device *dssdev) dssdev->state = OMAP_DSS_DISPLAY_ACTIVE; - r = dsi_set_te(dssdev, dsi.te_enabled); - if (r) - goto err2; - dsi_set_update_mode(dssdev, dsi.user_update_mode); dsi_bus_unlock(); @@ -3504,33 +3480,12 @@ static enum omap_dss_update_mode dsi_display_get_update_mode( } -static int dsi_display_enable_te(struct omap_dss_device *dssdev, bool enable) +int omapdss_dsi_enable_te(struct omap_dss_device *dssdev, bool enable) { - int r = 0; - - DSSDBGF("%d", enable); - - if (!dssdev->driver->enable_te) - return -ENOENT; - - dsi_bus_lock(); - dsi.te_enabled = enable; - - if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE) - goto end; - - r = dsi_set_te(dssdev, enable); -end: - dsi_bus_unlock(); - - return r; -} - -static int dsi_display_get_te(struct omap_dss_device *dssdev) -{ - return dsi.te_enabled; + return 0; } +EXPORT_SYMBOL(omapdss_dsi_enable_te); void dsi_get_overlay_fifo_thresholds(enum omap_plane plane, u32 fifo_size, enum omap_burst_size *burst_size, @@ -3557,8 +3512,6 @@ int dsi_init_display(struct omap_dss_device *dssdev) dssdev->sync = dsi_display_sync; dssdev->set_update_mode = dsi_display_set_update_mode; dssdev->get_update_mode = dsi_display_get_update_mode; - dssdev->enable_te = dsi_display_enable_te; - dssdev->get_te = dsi_display_get_te; /* XXX these should be figured out dynamically */ dssdev->caps = OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE | diff --git a/drivers/video/omap2/dss/rfbi.c b/drivers/video/omap2/dss/rfbi.c index 6b9cd767c7c1..71293876fed1 100644 --- a/drivers/video/omap2/dss/rfbi.c +++ b/drivers/video/omap2/dss/rfbi.c @@ -1232,12 +1232,6 @@ static int rfbi_display_sync(struct omap_dss_device *dssdev) return 0; } -static int rfbi_display_enable_te(struct omap_dss_device *dssdev, bool enable) -{ - dssdev->driver->enable_te(dssdev, enable); - return 0; -} - static int rfbi_display_enable(struct omap_dss_device *dssdev) { int r; @@ -1299,7 +1293,6 @@ int rfbi_init_display(struct omap_dss_device *dssdev) dssdev->disable = rfbi_display_disable; dssdev->update = rfbi_display_update; dssdev->sync = rfbi_display_sync; - dssdev->enable_te = rfbi_display_enable_te; rfbi.dssdev[dssdev->phy.rfbi.channel] = dssdev; diff --git a/drivers/video/omap2/omapfb/omapfb-ioctl.c b/drivers/video/omap2/omapfb/omapfb-ioctl.c index 6deabb94fd31..cb2e3432618d 100644 --- a/drivers/video/omap2/omapfb/omapfb-ioctl.c +++ b/drivers/video/omap2/omapfb/omapfb-ioctl.c @@ -732,12 +732,13 @@ int omapfb_ioctl(struct fb_info *fbi, unsigned int cmd, unsigned long arg) break; } - if (!display->enable_te) { + if (!display->driver->enable_te) { r = -ENODEV; break; } - r = display->enable_te(display, !!p.tearsync_info.enabled); + r = display->driver->enable_te(display, + !!p.tearsync_info.enabled); break; } diff --git a/drivers/video/omap2/omapfb/omapfb-main.c b/drivers/video/omap2/omapfb/omapfb-main.c index 216ed80293b8..b0adfb5915c8 100644 --- a/drivers/video/omap2/omapfb/omapfb-main.c +++ b/drivers/video/omap2/omapfb/omapfb-main.c @@ -2206,14 +2206,14 @@ static int omapfb_probe(struct platform_device *pdev) /* set the update mode */ if (def_display->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE) { #ifdef CONFIG_FB_OMAP2_FORCE_AUTO_UPDATE - if (def_display->enable_te) - def_display->enable_te(def_display, 1); + if (def_display->driver->enable_te) + def_display->driver->enable_te(def_display, 1); if (def_display->set_update_mode) def_display->set_update_mode(def_display, OMAP_DSS_UPDATE_AUTO); #else /* MANUAL_UPDATE */ - if (def_display->enable_te) - def_display->enable_te(def_display, 0); + if (def_display->driver->enable_te) + def_display->driver->enable_te(def_display, 0); if (def_display->set_update_mode) def_display->set_update_mode(def_display, OMAP_DSS_UPDATE_MANUAL); -- cgit v1.2.2 From 446f7bff703f5f82560afde90fb22b7a1d366bbc Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Mon, 11 Jan 2010 16:12:31 +0200 Subject: OMAP: DSS2: move set/get_update_mode() Move set/get_update_mode() from omap_dss_device to omap_dss_driver. This is part of a larger patch-set, which moves the control from omapdss driver to the display driver. Signed-off-by: Tomi Valkeinen --- drivers/video/omap2/displays/panel-taal.c | 16 +++++ drivers/video/omap2/dss/display.c | 6 +- drivers/video/omap2/dss/dpi.c | 27 ------- drivers/video/omap2/dss/dsi.c | 115 +++--------------------------- drivers/video/omap2/dss/manager.c | 17 +++-- drivers/video/omap2/dss/sdi.c | 26 ------- drivers/video/omap2/dss/venc.c | 27 ++++--- drivers/video/omap2/omapfb/omapfb-ioctl.c | 13 ++-- drivers/video/omap2/omapfb/omapfb-main.c | 27 +++---- 9 files changed, 80 insertions(+), 194 deletions(-) (limited to 'drivers') diff --git a/drivers/video/omap2/displays/panel-taal.c b/drivers/video/omap2/displays/panel-taal.c index af4b0b03b745..4ccb583b7b67 100644 --- a/drivers/video/omap2/displays/panel-taal.c +++ b/drivers/video/omap2/displays/panel-taal.c @@ -995,6 +995,20 @@ err: queue_delayed_work(td->esd_wq, &td->esd_work, TAAL_ESD_CHECK_PERIOD); } +static int taal_set_update_mode(struct omap_dss_device *dssdev, + enum omap_dss_update_mode mode) +{ + if (mode != OMAP_DSS_UPDATE_MANUAL) + return -EINVAL; + return 0; +} + +static enum omap_dss_update_mode taal_get_update_mode( + struct omap_dss_device *dssdev) +{ + return OMAP_DSS_UPDATE_MANUAL; +} + static struct omap_dss_driver taal_driver = { .probe = taal_probe, .remove = taal_remove, @@ -1005,6 +1019,8 @@ static struct omap_dss_driver taal_driver = { .resume = taal_resume, .setup_update = taal_setup_update, + .set_update_mode = taal_set_update_mode, + .get_update_mode = taal_get_update_mode, .get_resolution = taal_get_resolution, .get_recommended_bpp = omapdss_default_get_recommended_bpp, diff --git a/drivers/video/omap2/dss/display.c b/drivers/video/omap2/dss/display.c index 383a8c82dae8..86996d8d65be 100644 --- a/drivers/video/omap2/dss/display.c +++ b/drivers/video/omap2/dss/display.c @@ -69,8 +69,8 @@ static ssize_t display_upd_mode_show(struct device *dev, { struct omap_dss_device *dssdev = to_dss_device(dev); enum omap_dss_update_mode mode = OMAP_DSS_UPDATE_AUTO; - if (dssdev->get_update_mode) - mode = dssdev->get_update_mode(dssdev); + if (dssdev->driver->get_update_mode) + mode = dssdev->driver->get_update_mode(dssdev); return snprintf(buf, PAGE_SIZE, "%d\n", mode); } @@ -94,7 +94,7 @@ static ssize_t display_upd_mode_store(struct device *dev, return -EINVAL; } - r = dssdev->set_update_mode(dssdev, mode); + r = dssdev->driver->set_update_mode(dssdev, mode); if (r) return r; diff --git a/drivers/video/omap2/dss/dpi.c b/drivers/video/omap2/dss/dpi.c index 77b95577ab30..48ff7ea470aa 100644 --- a/drivers/video/omap2/dss/dpi.c +++ b/drivers/video/omap2/dss/dpi.c @@ -36,7 +36,6 @@ #include "dss.h" static struct { - int update_enabled; struct regulator *vdds_dsi_reg; } dpi; @@ -376,30 +375,6 @@ static void dpi_get_timings(struct omap_dss_device *dssdev, *timings = dssdev->panel.timings; } -static int dpi_display_set_update_mode(struct omap_dss_device *dssdev, - enum omap_dss_update_mode mode) -{ - if (mode == OMAP_DSS_UPDATE_MANUAL) - return -EINVAL; - - if (mode == OMAP_DSS_UPDATE_DISABLED) { - dssdev->manager->disable(dssdev->manager); - dpi.update_enabled = 0; - } else { - dssdev->manager->enable(dssdev->manager); - dpi.update_enabled = 1; - } - - return 0; -} - -static enum omap_dss_update_mode dpi_display_get_update_mode( - struct omap_dss_device *dssdev) -{ - return dpi.update_enabled ? OMAP_DSS_UPDATE_AUTO : - OMAP_DSS_UPDATE_DISABLED; -} - int dpi_init_display(struct omap_dss_device *dssdev) { DSSDBG("init_display\n"); @@ -411,8 +386,6 @@ int dpi_init_display(struct omap_dss_device *dssdev) dssdev->set_timings = dpi_set_timings; dssdev->check_timings = dpi_check_timings; dssdev->get_timings = dpi_get_timings; - dssdev->set_update_mode = dpi_display_set_update_mode; - dssdev->get_update_mode = dpi_display_get_update_mode; return 0; } diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c index 697a78b85807..b9fa62027f67 100644 --- a/drivers/video/omap2/dss/dsi.c +++ b/drivers/video/omap2/dss/dsi.c @@ -243,8 +243,6 @@ static struct struct dsi_update_region active_update_region; struct completion update_completion; - enum omap_dss_update_mode user_update_mode; - enum omap_dss_update_mode update_mode; bool te_enabled; bool use_ext_te; @@ -345,9 +343,6 @@ static void dsi_perf_show(const char *name) if (!dsi_perf) return; - if (dsi.update_mode == OMAP_DSS_UPDATE_DISABLED) - return; - t = ktime_get(); setup_time = ktime_sub(dsi.perf_start_time, dsi.perf_setup_time); @@ -1704,9 +1699,8 @@ static int dsi_force_tx_stop_mode_io(void) static int dsi_vc_enable(int channel, bool enable) { - if (dsi.update_mode != OMAP_DSS_UPDATE_AUTO) - DSSDBG("dsi_vc_enable channel %d, enable %d\n", - channel, enable); + DSSDBG("dsi_vc_enable channel %d, enable %d\n", + channel, enable); enable = enable ? 1 : 0; @@ -1886,8 +1880,7 @@ static u16 dsi_vc_flush_receive_data(int channel) static int dsi_vc_send_bta(int channel) { - if (dsi.update_mode != OMAP_DSS_UPDATE_AUTO && - (dsi.debug_write || dsi.debug_read)) + if (dsi.debug_write || dsi.debug_read) DSSDBG("dsi_vc_send_bta %d\n", channel); WARN_ON(!dsi_bus_is_locked()); @@ -2740,9 +2733,8 @@ static void dsi_update_screen_dispc(struct omap_dss_device *dssdev, use_te_trigger = dsi.te_enabled && !dsi.use_ext_te; - if (dsi.update_mode != OMAP_DSS_UPDATE_AUTO) - DSSDBG("dsi_update_screen_dispc(%d,%d %dx%d)\n", - x, y, w, h); + DSSDBG("dsi_update_screen_dispc(%d,%d %dx%d)\n", + x, y, w, h); bytespp = dssdev->ctrl.pixel_size / 8; bytespl = w * bytespp; @@ -2840,45 +2832,6 @@ static void dsi_set_update_region(struct omap_dss_device *dssdev, } -static int dsi_set_update_mode(struct omap_dss_device *dssdev, - enum omap_dss_update_mode mode) -{ - int r = 0; - int i; - - WARN_ON(!dsi_bus_is_locked()); - - if (dsi.update_mode != mode) { - dsi.update_mode = mode; - - /* Mark the overlays dirty, and do apply(), so that we get the - * overlays configured properly after update mode change. */ - for (i = 0; i < omap_dss_get_num_overlays(); ++i) { - struct omap_overlay *ovl; - ovl = omap_dss_get_overlay(i); - if (ovl->manager == dssdev->manager) - ovl->info_dirty = true; - } - - r = dssdev->manager->apply(dssdev->manager); - - if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE && - mode == OMAP_DSS_UPDATE_AUTO) { - u16 w, h; - - DSSDBG("starting auto update\n"); - - dssdev->driver->get_resolution(dssdev, &w, &h); - - dsi_set_update_region(dssdev, 0, 0, w, h); - - wake_up(&dsi.waitqueue); - } - } - - return r; -} - static void dsi_handle_framedone(void) { int r; @@ -2887,8 +2840,7 @@ static void dsi_handle_framedone(void) use_te_trigger = dsi.te_enabled && !dsi.use_ext_te; - if (dsi.update_mode != OMAP_DSS_UPDATE_AUTO) - DSSDBG("FRAMEDONE\n"); + DSSDBG("FRAMEDONE\n"); if (use_te_trigger) { /* enable LP_RX_TO again after the TE */ @@ -2927,9 +2879,7 @@ static int dsi_update_thread(void *data) while (1) { wait_event_interruptible(dsi.waitqueue, - dsi.update_mode == OMAP_DSS_UPDATE_AUTO || - (dsi.update_mode == OMAP_DSS_UPDATE_MANUAL && - dsi.update_region.dirty == true) || + dsi.update_region.dirty == true || kthread_should_stop()); if (kthread_should_stop()) @@ -2937,8 +2887,7 @@ static int dsi_update_thread(void *data) dsi_bus_lock(); - if (dsi.update_mode == OMAP_DSS_UPDATE_DISABLED || - kthread_should_stop()) { + if (kthread_should_stop()) { dsi_bus_unlock(); break; } @@ -2960,9 +2909,8 @@ static int dsi_update_thread(void *data) if (device->manager->caps & OMAP_DSS_OVL_MGR_CAP_DISPC) { - if (dsi.update_mode == OMAP_DSS_UPDATE_MANUAL) - dss_setup_partial_planes(device, - &x, &y, &w, &h); + dss_setup_partial_planes(device, + &x, &y, &w, &h); dispc_set_lcd_size(w, h); } @@ -3254,8 +3202,6 @@ static int dsi_display_enable(struct omap_dss_device *dssdev) dsi.use_ext_te = dssdev->phy.dsi.ext_te; - dsi_set_update_mode(dssdev, dsi.user_update_mode); - dsi_bus_unlock(); mutex_unlock(&dsi.lock); @@ -3286,7 +3232,6 @@ static void dsi_display_disable(struct omap_dss_device *dssdev) dssdev->state == OMAP_DSS_DISPLAY_SUSPENDED) goto end; - dsi.update_mode = OMAP_DSS_UPDATE_DISABLED; dssdev->state = OMAP_DSS_DISPLAY_DISABLED; dsi_display_uninit_dispc(dssdev); @@ -3313,7 +3258,6 @@ static int dsi_display_suspend(struct omap_dss_device *dssdev) dssdev->state == OMAP_DSS_DISPLAY_SUSPENDED) goto end; - dsi.update_mode = OMAP_DSS_UPDATE_DISABLED; dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED; dsi_display_uninit_dispc(dssdev); @@ -3363,8 +3307,6 @@ static int dsi_display_resume(struct omap_dss_device *dssdev) dssdev->state = OMAP_DSS_DISPLAY_ACTIVE; - dsi_set_update_mode(dssdev, dsi.user_update_mode); - dsi_bus_unlock(); mutex_unlock(&dsi.lock); @@ -3392,9 +3334,6 @@ static int dsi_display_update(struct omap_dss_device *dssdev, mutex_lock(&dsi.lock); - if (dsi.update_mode != OMAP_DSS_UPDATE_MANUAL) - goto end; - if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE) goto end; @@ -3436,8 +3375,7 @@ static int dsi_display_sync(struct omap_dss_device *dssdev) mutex_lock(&dsi.lock); dsi_bus_lock(); - if (dsi.update_mode == OMAP_DSS_UPDATE_MANUAL && - dsi.update_region.dirty) { + if (dsi.update_region.dirty) { INIT_COMPLETION(dsi.update_completion); wait = true; } else { @@ -3454,32 +3392,6 @@ static int dsi_display_sync(struct omap_dss_device *dssdev) return 0; } -static int dsi_display_set_update_mode(struct omap_dss_device *dssdev, - enum omap_dss_update_mode mode) -{ - int r = 0; - - DSSDBGF("%d", mode); - - mutex_lock(&dsi.lock); - dsi_bus_lock(); - - dsi.user_update_mode = mode; - r = dsi_set_update_mode(dssdev, mode); - - dsi_bus_unlock(); - mutex_unlock(&dsi.lock); - - return r; -} - -static enum omap_dss_update_mode dsi_display_get_update_mode( - struct omap_dss_device *dssdev) -{ - return dsi.update_mode; -} - - int omapdss_dsi_enable_te(struct omap_dss_device *dssdev, bool enable) { dsi.te_enabled = enable; @@ -3510,8 +3422,6 @@ int dsi_init_display(struct omap_dss_device *dssdev) dssdev->resume = dsi_display_resume; dssdev->update = dsi_display_update; dssdev->sync = dsi_display_sync; - dssdev->set_update_mode = dsi_display_set_update_mode; - dssdev->get_update_mode = dsi_display_get_update_mode; /* XXX these should be figured out dynamically */ dssdev->caps = OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE | @@ -3562,9 +3472,6 @@ int dsi_init(struct platform_device *pdev) dsi.te_timer.data = 0; #endif - dsi.update_mode = OMAP_DSS_UPDATE_DISABLED; - dsi.user_update_mode = OMAP_DSS_UPDATE_DISABLED; - dsi.base = ioremap(DSI_BASE, DSI_SZ_REGS); if (!dsi.base) { DSSERR("can't ioremap DSI\n"); diff --git a/drivers/video/omap2/dss/manager.c b/drivers/video/omap2/dss/manager.c index 4ede519c0a31..913142d4cab1 100644 --- a/drivers/video/omap2/dss/manager.c +++ b/drivers/video/omap2/dss/manager.c @@ -522,17 +522,18 @@ static int dss_mgr_wait_for_go(struct omap_overlay_manager *mgr) u32 irq; int r; int i; + struct omap_dss_device *dssdev = mgr->device; - if (!mgr->device) + if (!dssdev) return 0; - if (mgr->device->type == OMAP_DISPLAY_TYPE_VENC) { + if (dssdev->type == OMAP_DISPLAY_TYPE_VENC) { irq = DISPC_IRQ_EVSYNC_ODD | DISPC_IRQ_EVSYNC_EVEN; channel = OMAP_DSS_CHANNEL_DIGIT; } else { - if (mgr->device->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE) { + if (dssdev->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE) { enum omap_dss_update_mode mode; - mode = mgr->device->get_update_mode(mgr->device); + mode = dssdev->driver->get_update_mode(dssdev); if (mode != OMAP_DSS_UPDATE_AUTO) return 0; @@ -605,7 +606,7 @@ int dss_mgr_wait_for_go_ovl(struct omap_overlay *ovl) } else { if (dssdev->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE) { enum omap_dss_update_mode mode; - mode = dssdev->get_update_mode(dssdev); + mode = dssdev->driver->get_update_mode(dssdev); if (mode != OMAP_DSS_UPDATE_AUTO) return 0; @@ -1209,7 +1210,8 @@ static int omap_dss_mgr_apply(struct omap_overlay_manager *mgr) oc->manual_update = dssdev->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE && - dssdev->get_update_mode(dssdev) != OMAP_DSS_UPDATE_AUTO; + dssdev->driver->get_update_mode(dssdev) != + OMAP_DSS_UPDATE_AUTO; ++num_planes_enabled; } @@ -1250,7 +1252,8 @@ static int omap_dss_mgr_apply(struct omap_overlay_manager *mgr) mc->manual_update = dssdev->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE && - dssdev->get_update_mode(dssdev) != OMAP_DSS_UPDATE_AUTO; + dssdev->driver->get_update_mode(dssdev) != + OMAP_DSS_UPDATE_AUTO; } /* XXX TODO: Try to get fifomerge working. The problem is that it diff --git a/drivers/video/omap2/dss/sdi.c b/drivers/video/omap2/dss/sdi.c index 5f852edd4cbc..6bd9b0cf76a8 100644 --- a/drivers/video/omap2/dss/sdi.c +++ b/drivers/video/omap2/dss/sdi.c @@ -213,30 +213,6 @@ err: return r; } -static int sdi_display_set_update_mode(struct omap_dss_device *dssdev, - enum omap_dss_update_mode mode) -{ - if (mode == OMAP_DSS_UPDATE_MANUAL) - return -EINVAL; - - if (mode == OMAP_DSS_UPDATE_DISABLED) { - dssdev->manager->disable(dssdev->manager); - sdi.update_enabled = 0; - } else { - dssdev->manager->enable(dssdev->manager); - sdi.update_enabled = 1; - } - - return 0; -} - -static enum omap_dss_update_mode sdi_display_get_update_mode( - struct omap_dss_device *dssdev) -{ - return sdi.update_enabled ? OMAP_DSS_UPDATE_AUTO : - OMAP_DSS_UPDATE_DISABLED; -} - static void sdi_get_timings(struct omap_dss_device *dssdev, struct omap_video_timings *timings) { @@ -251,8 +227,6 @@ int sdi_init_display(struct omap_dss_device *dssdev) dssdev->disable = sdi_display_disable; dssdev->suspend = sdi_display_suspend; dssdev->resume = sdi_display_resume; - dssdev->set_update_mode = sdi_display_set_update_mode; - dssdev->get_update_mode = sdi_display_get_update_mode; dssdev->get_timings = sdi_get_timings; return 0; diff --git a/drivers/video/omap2/dss/venc.c b/drivers/video/omap2/dss/venc.c index d13071dd46e5..0d0dc94417fc 100644 --- a/drivers/video/omap2/dss/venc.c +++ b/drivers/video/omap2/dss/venc.c @@ -450,6 +450,20 @@ static int venc_panel_resume(struct omap_dss_device *dssdev) return venc_panel_enable(dssdev); } +static enum omap_dss_update_mode venc_get_update_mode( + struct omap_dss_device *dssdev) +{ + return OMAP_DSS_UPDATE_AUTO; +} + +static int venc_set_update_mode(struct omap_dss_device *dssdev, + enum omap_dss_update_mode mode) +{ + if (mode != OMAP_DSS_UPDATE_AUTO) + return -EINVAL; + return 0; +} + static struct omap_dss_driver venc_driver = { .probe = venc_panel_probe, .remove = venc_panel_remove, @@ -462,6 +476,9 @@ static struct omap_dss_driver venc_driver = { .get_resolution = omapdss_default_get_resolution, .get_recommended_bpp = omapdss_default_get_recommended_bpp, + .set_update_mode = venc_set_update_mode, + .get_update_mode = venc_get_update_mode, + .driver = { .name = "venc", .owner = THIS_MODULE, @@ -717,15 +734,6 @@ static int venc_set_wss(struct omap_dss_device *dssdev, u32 wss) return 0; } -static enum omap_dss_update_mode venc_display_get_update_mode( - struct omap_dss_device *dssdev) -{ - if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) - return OMAP_DSS_UPDATE_AUTO; - else - return OMAP_DSS_UPDATE_DISABLED; -} - int venc_init_display(struct omap_dss_device *dssdev) { DSSDBG("init_display\n"); @@ -739,7 +747,6 @@ int venc_init_display(struct omap_dss_device *dssdev) dssdev->check_timings = venc_check_timings; dssdev->get_wss = venc_get_wss; dssdev->set_wss = venc_set_wss; - dssdev->get_update_mode = venc_display_get_update_mode; return 0; } diff --git a/drivers/video/omap2/omapfb/omapfb-ioctl.c b/drivers/video/omap2/omapfb/omapfb-ioctl.c index cb2e3432618d..4f68cb0d59de 100644 --- a/drivers/video/omap2/omapfb/omapfb-ioctl.c +++ b/drivers/video/omap2/omapfb/omapfb-ioctl.c @@ -202,7 +202,7 @@ static int omapfb_set_update_mode(struct fb_info *fbi, enum omap_dss_update_mode um; int r; - if (!display || !display->set_update_mode) + if (!display || !display->driver->set_update_mode) return -EINVAL; switch (mode) { @@ -222,7 +222,7 @@ static int omapfb_set_update_mode(struct fb_info *fbi, return -EINVAL; } - r = display->set_update_mode(display, um); + r = display->driver->set_update_mode(display, um); return r; } @@ -233,10 +233,15 @@ static int omapfb_get_update_mode(struct fb_info *fbi, struct omap_dss_device *display = fb2display(fbi); enum omap_dss_update_mode m; - if (!display || !display->get_update_mode) + if (!display) return -EINVAL; - m = display->get_update_mode(display); + if (!display->driver->get_update_mode) { + *mode = OMAPFB_AUTO_UPDATE; + return 0; + } + + m = display->driver->get_update_mode(display); switch (m) { case OMAP_DSS_UPDATE_DISABLED: diff --git a/drivers/video/omap2/omapfb/omapfb-main.c b/drivers/video/omap2/omapfb/omapfb-main.c index b0adfb5915c8..c720842341b2 100644 --- a/drivers/video/omap2/omapfb/omapfb-main.c +++ b/drivers/video/omap2/omapfb/omapfb-main.c @@ -1226,8 +1226,8 @@ static int omapfb_blank(int blank, struct fb_info *fbi) if (display->resume) r = display->resume(display); - if (r == 0 && display->get_update_mode && - display->get_update_mode(display) == + if (r == 0 && display->driver->get_update_mode && + display->driver->get_update_mode(display) == OMAP_DSS_UPDATE_MANUAL) do_update = 1; @@ -2193,6 +2193,7 @@ static int omapfb_probe(struct platform_device *pdev) } if (def_display) { + struct omap_dss_driver *dssdrv = def_display->driver; #ifndef CONFIG_FB_OMAP2_FORCE_AUTO_UPDATE u16 w, h; #endif @@ -2206,25 +2207,25 @@ static int omapfb_probe(struct platform_device *pdev) /* set the update mode */ if (def_display->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE) { #ifdef CONFIG_FB_OMAP2_FORCE_AUTO_UPDATE - if (def_display->driver->enable_te) - def_display->driver->enable_te(def_display, 1); - if (def_display->set_update_mode) - def_display->set_update_mode(def_display, + if (dssdrv->enable_te) + dssdrv->enable_te(def_display, 1); + if (dssdrv->set_update_mode) + dssdrv->set_update_mode(def_display, OMAP_DSS_UPDATE_AUTO); #else /* MANUAL_UPDATE */ - if (def_display->driver->enable_te) - def_display->driver->enable_te(def_display, 0); - if (def_display->set_update_mode) - def_display->set_update_mode(def_display, + if (dssdrv->enable_te) + dssdrv->enable_te(def_display, 0); + if (dssdrv->set_update_mode) + dssdrv->set_update_mode(def_display, OMAP_DSS_UPDATE_MANUAL); - def_display->driver->get_resolution(def_display, + dssdrv->get_resolution(def_display, &w, &h); def_display->update(def_display, 0, 0, w, h); #endif } else { - if (def_display->set_update_mode) - def_display->set_update_mode(def_display, + if (dssdrv->set_update_mode) + dssdrv->set_update_mode(def_display, OMAP_DSS_UPDATE_AUTO); } } -- cgit v1.2.2 From 18946f62c6cc8cf051bafca8b7fa72309e8a1067 Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Tue, 12 Jan 2010 14:16:41 +0200 Subject: OMAP: DSS2: move update() and sync() Move update() and sync() from omap_dss_device to omap_dss_driver. Also, update was hardcoded to use virtual channel 0. This patch adds a parameter that specifies the VC. This is part of a larger patch-set, which moves the control from omapdss driver to the display driver. Signed-off-by: Tomi Valkeinen --- drivers/video/omap2/displays/panel-taal.c | 76 +++++-- drivers/video/omap2/dss/dsi.c | 322 +++++++++++------------------- drivers/video/omap2/dss/rfbi.c | 290 +++------------------------ drivers/video/omap2/omapfb/omapfb-ioctl.c | 10 +- drivers/video/omap2/omapfb/omapfb-main.c | 10 +- 5 files changed, 208 insertions(+), 500 deletions(-) (limited to 'drivers') diff --git a/drivers/video/omap2/displays/panel-taal.c b/drivers/video/omap2/displays/panel-taal.c index 4ccb583b7b67..58293203fc05 100644 --- a/drivers/video/omap2/displays/panel-taal.c +++ b/drivers/video/omap2/displays/panel-taal.c @@ -725,10 +725,58 @@ static int taal_resume(struct omap_dss_device *dssdev) return 0; } -static void taal_setup_update(struct omap_dss_device *dssdev, +static void taal_framedone_cb(int err, void *data) +{ + struct omap_dss_device *dssdev = data; + dev_dbg(&dssdev->dev, "framedone, err %d\n", err); + dsi_bus_unlock(); +} + +static int taal_update(struct omap_dss_device *dssdev, u16 x, u16 y, u16 w, u16 h) { - taal_set_update_window(x, y, w, h); + struct taal_data *td = dev_get_drvdata(&dssdev->dev); + int r; + + dev_dbg(&dssdev->dev, "update %d, %d, %d x %d\n", x, y, w, h); + + dsi_bus_lock(); + + if (!td->enabled) { + r = 0; + goto err; + } + + r = omap_dsi_prepare_update(dssdev, &x, &y, &w, &h); + if (r) + goto err; + + r = taal_set_update_window(x, y, w, h); + if (r) + goto err; + + r = omap_dsi_update(dssdev, TCH, x, y, w, h, + taal_framedone_cb, dssdev); + if (r) + goto err; + + /* note: no bus_unlock here. unlock is in framedone_cb */ + return 0; +err: + dsi_bus_unlock(); + return r; +} + +static int taal_sync(struct omap_dss_device *dssdev) +{ + dev_dbg(&dssdev->dev, "sync\n"); + + dsi_bus_lock(); + dsi_bus_unlock(); + + dev_dbg(&dssdev->dev, "sync done\n"); + + return 0; } static int taal_enable_te(struct omap_dss_device *dssdev, bool enable) @@ -762,24 +810,6 @@ static int taal_get_te(struct omap_dss_device *dssdev) return td->te_enabled; } -static int taal_wait_te(struct omap_dss_device *dssdev) -{ - struct taal_data *td = dev_get_drvdata(&dssdev->dev); - long wait = msecs_to_jiffies(500); - - if (!td->use_ext_te || !td->te_enabled) - return 0; - - INIT_COMPLETION(td->te_completion); - wait = wait_for_completion_timeout(&td->te_completion, wait); - if (wait == 0) { - dev_err(&dssdev->dev, "timeout waiting TE\n"); - return -ETIME; - } - - return 0; -} - static int taal_rotate(struct omap_dss_device *dssdev, u8 rotate) { struct taal_data *td = dev_get_drvdata(&dssdev->dev); @@ -1018,15 +1048,17 @@ static struct omap_dss_driver taal_driver = { .suspend = taal_suspend, .resume = taal_resume, - .setup_update = taal_setup_update, .set_update_mode = taal_set_update_mode, .get_update_mode = taal_get_update_mode, + + .update = taal_update, + .sync = taal_sync, + .get_resolution = taal_get_resolution, .get_recommended_bpp = omapdss_default_get_recommended_bpp, .enable_te = taal_enable_te, .get_te = taal_get_te, - .wait_for_te = taal_wait_te, .set_rotate = taal_rotate, .get_rotate = taal_get_rotate, diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c index b9fa62027f67..203b18bbddae 100644 --- a/drivers/video/omap2/dss/dsi.c +++ b/drivers/video/omap2/dss/dsi.c @@ -31,8 +31,8 @@ #include #include #include -#include #include +#include #include #include @@ -200,7 +200,6 @@ enum dsi_vc_mode { }; struct dsi_update_region { - bool dirty; u16 x, y, w, h; struct omap_dss_device *device; }; @@ -234,18 +233,18 @@ static struct struct completion bta_completion; - struct task_struct *thread; - wait_queue_head_t waitqueue; - - spinlock_t update_lock; - bool framedone_received; + int update_channel; struct dsi_update_region update_region; - struct dsi_update_region active_update_region; - struct completion update_completion; bool te_enabled; bool use_ext_te; + struct work_struct framedone_work; + void (*framedone_callback)(int, void *); + void *framedone_data; + + struct delayed_work framedone_timeout_work; + #ifdef DSI_CATCH_MISSING_TE struct timer_list te_timer; #endif @@ -357,9 +356,9 @@ static void dsi_perf_show(const char *name) total_us = setup_us + trans_us; - total_bytes = dsi.active_update_region.w * - dsi.active_update_region.h * - dsi.active_update_region.device->ctrl.pixel_size / 8; + total_bytes = dsi.update_region.w * + dsi.update_region.h * + dsi.update_region.device->ctrl.pixel_size / 8; printk(KERN_INFO "DSI(%s): %u us + %u us = %u us (%uHz), " "%u bytes, %u kbytes/sec\n", @@ -2725,7 +2724,7 @@ static void dsi_update_screen_dispc(struct omap_dss_device *dssdev, unsigned packet_len; u32 l; bool use_te_trigger; - const unsigned channel = 0; + const unsigned channel = dsi.update_channel; /* line buffer is 1024 x 24bits */ /* XXX: for some reason using full buffer size causes considerable TX * slowdown with update sizes that fill the whole buffer */ @@ -2736,6 +2735,8 @@ static void dsi_update_screen_dispc(struct omap_dss_device *dssdev, DSSDBG("dsi_update_screen_dispc(%d,%d %dx%d)\n", x, y, w, h); + dsi_vc_config_vp(channel); + bytespp = dssdev->ctrl.pixel_size / 8; bytespl = w * bytespp; bytespf = bytespl * h; @@ -2773,6 +2774,11 @@ static void dsi_update_screen_dispc(struct omap_dss_device *dssdev, */ dispc_disable_sidle(); + dsi_perf_mark_start(); + + schedule_delayed_work(&dsi.framedone_timeout_work, + msecs_to_jiffies(250)); + dss_start_update(dssdev); if (use_te_trigger) { @@ -2795,47 +2801,63 @@ static void dsi_te_timeout(unsigned long arg) } #endif -static void dsi_framedone_irq_callback(void *data, u32 mask) +static void dsi_framedone_timeout_work_callback(struct work_struct *work) { - /* Note: We get FRAMEDONE when DISPC has finished sending pixels and - * turns itself off. However, DSI still has the pixels in its buffers, - * and is sending the data. - */ + int r; + const int channel = dsi.update_channel; + bool use_te_trigger; + + DSSERR("Framedone not received for 250ms!\n"); /* SIDLEMODE back to smart-idle */ dispc_enable_sidle(); - dsi.framedone_received = true; - wake_up(&dsi.waitqueue); -} + use_te_trigger = dsi.te_enabled && !dsi.use_ext_te; -static void dsi_set_update_region(struct omap_dss_device *dssdev, - u16 x, u16 y, u16 w, u16 h) -{ - spin_lock(&dsi.update_lock); - if (dsi.update_region.dirty) { - dsi.update_region.x = min(x, dsi.update_region.x); - dsi.update_region.y = min(y, dsi.update_region.y); - dsi.update_region.w = max(w, dsi.update_region.w); - dsi.update_region.h = max(h, dsi.update_region.h); - } else { - dsi.update_region.x = x; - dsi.update_region.y = y; - dsi.update_region.w = w; - dsi.update_region.h = h; + if (use_te_trigger) { + /* enable LP_RX_TO again after the TE */ + REG_FLD_MOD(DSI_TIMING2, 1, 15, 15); /* LP_RX_TO */ } - dsi.update_region.device = dssdev; - dsi.update_region.dirty = true; + /* Send BTA after the frame. We need this for the TE to work, as TE + * trigger is only sent for BTAs without preceding packet. Thus we need + * to BTA after the pixel packets so that next BTA will cause TE + * trigger. + * + * This is not needed when TE is not in use, but we do it anyway to + * make sure that the transfer has been completed. It would be more + * optimal, but more complex, to wait only just before starting next + * transfer. */ + r = dsi_vc_send_bta_sync(channel); + if (r) + DSSERR("BTA after framedone failed\n"); + + /* RX_FIFO_NOT_EMPTY */ + if (REG_GET(DSI_VC_CTRL(channel), 20, 20)) { + DSSERR("Received error during frame transfer:\n"); + dsi_vc_flush_receive_data(channel); + } + + dsi.framedone_callback(-ETIMEDOUT, dsi.framedone_data); +} - spin_unlock(&dsi.update_lock); +static void dsi_framedone_irq_callback(void *data, u32 mask) +{ + /* Note: We get FRAMEDONE when DISPC has finished sending pixels and + * turns itself off. However, DSI still has the pixels in its buffers, + * and is sending the data. + */ + + /* SIDLEMODE back to smart-idle */ + dispc_enable_sidle(); + schedule_work(&dsi.framedone_work); } static void dsi_handle_framedone(void) { int r; - const int channel = 0; + const int channel = dsi.update_channel; bool use_te_trigger; use_te_trigger = dsi.te_enabled && !dsi.use_ext_te; @@ -2871,105 +2893,79 @@ static void dsi_handle_framedone(void) #endif } -static int dsi_update_thread(void *data) +static void dsi_framedone_work_callback(struct work_struct *work) { - unsigned long timeout; - struct omap_dss_device *device; - u16 x, y, w, h; - - while (1) { - wait_event_interruptible(dsi.waitqueue, - dsi.update_region.dirty == true || - kthread_should_stop()); - - if (kthread_should_stop()) - break; - - dsi_bus_lock(); - - if (kthread_should_stop()) { - dsi_bus_unlock(); - break; - } + DSSDBGF(); - dsi_perf_mark_setup(); + cancel_delayed_work_sync(&dsi.framedone_timeout_work); - if (dsi.update_region.dirty) { - spin_lock(&dsi.update_lock); - dsi.active_update_region = dsi.update_region; - dsi.update_region.dirty = false; - spin_unlock(&dsi.update_lock); - } + dsi_handle_framedone(); - device = dsi.active_update_region.device; - x = dsi.active_update_region.x; - y = dsi.active_update_region.y; - w = dsi.active_update_region.w; - h = dsi.active_update_region.h; + dsi_perf_show("DISPC"); - if (device->manager->caps & OMAP_DSS_OVL_MGR_CAP_DISPC) { + dsi.framedone_callback(0, dsi.framedone_data); +} - dss_setup_partial_planes(device, - &x, &y, &w, &h); +int omap_dsi_prepare_update(struct omap_dss_device *dssdev, + u16 *x, u16 *y, u16 *w, u16 *h) +{ + u16 dw, dh; - dispc_set_lcd_size(w, h); - } + dssdev->driver->get_resolution(dssdev, &dw, &dh); - if (dsi.active_update_region.dirty) { - dsi.active_update_region.dirty = false; - /* XXX TODO we don't need to send the coords, if they - * are the same that are already programmed to the - * panel. That should speed up manual update a bit */ - device->driver->setup_update(device, x, y, w, h); - } + if (*x > dw || *y > dh) + return -EINVAL; - dsi_perf_mark_start(); + if (*x + *w > dw) + return -EINVAL; - if (device->manager->caps & OMAP_DSS_OVL_MGR_CAP_DISPC) { - dsi_vc_config_vp(0); + if (*y + *h > dh) + return -EINVAL; - if (dsi.te_enabled && dsi.use_ext_te) - device->driver->wait_for_te(device); + if (*w == 1) + return -EINVAL; - dsi.framedone_received = false; + if (*w == 0 || *h == 0) + return -EINVAL; - dsi_update_screen_dispc(device, x, y, w, h); + dsi_perf_mark_setup(); - /* wait for framedone */ - timeout = msecs_to_jiffies(1000); - wait_event_timeout(dsi.waitqueue, - dsi.framedone_received == true, - timeout); + if (dssdev->manager->caps & OMAP_DSS_OVL_MGR_CAP_DISPC) { + dss_setup_partial_planes(dssdev, x, y, w, h); + dispc_set_lcd_size(*w, *h); + } - if (!dsi.framedone_received) { - DSSERR("framedone timeout\n"); - DSSERR("failed update %d,%d %dx%d\n", - x, y, w, h); + return 0; +} +EXPORT_SYMBOL(omap_dsi_prepare_update); - dispc_enable_sidle(); - device->manager->disable(device->manager); +int omap_dsi_update(struct omap_dss_device *dssdev, + int channel, + u16 x, u16 y, u16 w, u16 h, + void (*callback)(int, void *), void *data) +{ + dsi.update_channel = channel; - dsi_reset_tx_fifo(0); - } else { - dsi_handle_framedone(); - dsi_perf_show("DISPC"); - } - } else { - dsi_update_screen_l4(device, x, y, w, h); - dsi_perf_show("L4"); - } + if (dssdev->manager->caps & OMAP_DSS_OVL_MGR_CAP_DISPC) { + dsi.framedone_callback = callback; + dsi.framedone_data = data; - complete_all(&dsi.update_completion); + dsi.update_region.x = x; + dsi.update_region.y = y; + dsi.update_region.w = w; + dsi.update_region.h = h; + dsi.update_region.device = dssdev; - dsi_bus_unlock(); + dsi_update_screen_dispc(dssdev, x, y, w, h); + } else { + dsi_update_screen_l4(dssdev, x, y, w, h); + dsi_perf_show("L4"); + callback(0, data); } - DSSDBG("update thread exiting\n"); - return 0; } - - +EXPORT_SYMBOL(omap_dsi_update); /* Display funcs */ @@ -3324,74 +3320,6 @@ err0: return r; } -static int dsi_display_update(struct omap_dss_device *dssdev, - u16 x, u16 y, u16 w, u16 h) -{ - int r = 0; - u16 dw, dh; - - DSSDBG("dsi_display_update(%d,%d %dx%d)\n", x, y, w, h); - - mutex_lock(&dsi.lock); - - if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE) - goto end; - - dssdev->driver->get_resolution(dssdev, &dw, &dh); - - if (x > dw || y > dh) - goto end; - - if (x + w > dw) - w = dw - x; - - if (y + h > dh) - h = dh - y; - - if (w == 0 || h == 0) - goto end; - - if (w == 1) { - r = -EINVAL; - goto end; - } - - dsi_set_update_region(dssdev, x, y, w, h); - - wake_up(&dsi.waitqueue); - -end: - mutex_unlock(&dsi.lock); - - return r; -} - -static int dsi_display_sync(struct omap_dss_device *dssdev) -{ - bool wait; - - DSSDBG("dsi_display_sync()\n"); - - mutex_lock(&dsi.lock); - dsi_bus_lock(); - - if (dsi.update_region.dirty) { - INIT_COMPLETION(dsi.update_completion); - wait = true; - } else { - wait = false; - } - - dsi_bus_unlock(); - mutex_unlock(&dsi.lock); - - if (wait) - wait_for_completion_interruptible(&dsi.update_completion); - - DSSDBG("dsi_display_sync() done\n"); - return 0; -} - int omapdss_dsi_enable_te(struct omap_dss_device *dssdev, bool enable) { dsi.te_enabled = enable; @@ -3420,8 +3348,6 @@ int dsi_init_display(struct omap_dss_device *dssdev) dssdev->disable = dsi_display_disable; dssdev->suspend = dsi_display_suspend; dssdev->resume = dsi_display_resume; - dssdev->update = dsi_display_update; - dssdev->sync = dsi_display_sync; /* XXX these should be figured out dynamically */ dssdev->caps = OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE | @@ -3437,9 +3363,6 @@ int dsi_init(struct platform_device *pdev) { u32 rev; int r; - struct sched_param param = { - .sched_priority = MAX_USER_RT_PRIO-1 - }; spin_lock_init(&dsi.errors_lock); dsi.errors = 0; @@ -3450,28 +3373,19 @@ int dsi_init(struct platform_device *pdev) #endif init_completion(&dsi.bta_completion); - init_completion(&dsi.update_completion); - - dsi.thread = kthread_create(dsi_update_thread, NULL, "dsi"); - if (IS_ERR(dsi.thread)) { - DSSERR("cannot create kthread\n"); - r = PTR_ERR(dsi.thread); - goto err0; - } - sched_setscheduler(dsi.thread, SCHED_FIFO, ¶m); - - init_waitqueue_head(&dsi.waitqueue); - spin_lock_init(&dsi.update_lock); mutex_init(&dsi.lock); sema_init(&dsi.bus_lock, 1); + INIT_WORK(&dsi.framedone_work, dsi_framedone_work_callback); + INIT_DELAYED_WORK_DEFERRABLE(&dsi.framedone_timeout_work, + dsi_framedone_timeout_work_callback); + #ifdef DSI_CATCH_MISSING_TE init_timer(&dsi.te_timer); dsi.te_timer.function = dsi_te_timeout; dsi.te_timer.data = 0; #endif - dsi.base = ioremap(DSI_BASE, DSI_SZ_REGS); if (!dsi.base) { DSSERR("can't ioremap DSI\n"); @@ -3495,21 +3409,15 @@ int dsi_init(struct platform_device *pdev) enable_clocks(0); - wake_up_process(dsi.thread); - return 0; err2: iounmap(dsi.base); err1: - kthread_stop(dsi.thread); -err0: return r; } void dsi_exit(void) { - kthread_stop(dsi.thread); - iounmap(dsi.base); DSSDBG("omap_dsi_exit\n"); diff --git a/drivers/video/omap2/dss/rfbi.c b/drivers/video/omap2/dss/rfbi.c index 71293876fed1..a6b33160666a 100644 --- a/drivers/video/omap2/dss/rfbi.c +++ b/drivers/video/omap2/dss/rfbi.c @@ -36,8 +36,6 @@ #include #include "dss.h" -/*#define MEASURE_PERF*/ - #define RFBI_BASE 0x48050800 struct rfbi_reg { u16 idx; }; @@ -66,8 +64,6 @@ struct rfbi_reg { u16 idx; }; #define RFBI_VSYNC_WIDTH RFBI_REG(0x0090) #define RFBI_HSYNC_WIDTH RFBI_REG(0x0094) -#define RFBI_CMD_FIFO_LEN_BYTES (16 * sizeof(struct update_param)) - #define REG_FLD_MOD(idx, val, start, end) \ rfbi_write_reg(idx, FLD_MOD(rfbi_read_reg(idx), val, start, end)) @@ -102,7 +98,6 @@ enum update_cmd { static int rfbi_convert_timings(struct rfbi_timings *t); static void rfbi_get_clk_info(u32 *clk_period, u32 *max_clk_div); -static void process_cmd_fifo(void); static struct { void __iomem *base; @@ -125,11 +120,6 @@ static struct { struct completion cmd_done; atomic_t cmd_fifo_full; atomic_t cmd_pending; -#ifdef MEASURE_PERF - unsigned perf_bytes; - ktime_t perf_setup_time; - ktime_t perf_start_time; -#endif } rfbi; struct update_region { @@ -139,16 +129,6 @@ struct update_region { u16 h; }; -struct update_param { - u8 rfbi_module; - u8 cmd; - - union { - struct update_region r; - struct completion *sync; - } par; -}; - static inline void rfbi_write_reg(const struct rfbi_reg idx, u32 val) { __raw_writel(val, rfbi.base + idx.idx); @@ -321,55 +301,6 @@ void omap_rfbi_write_pixels(const void __iomem *buf, int scr_width, } EXPORT_SYMBOL(omap_rfbi_write_pixels); -#ifdef MEASURE_PERF -static void perf_mark_setup(void) -{ - rfbi.perf_setup_time = ktime_get(); -} - -static void perf_mark_start(void) -{ - rfbi.perf_start_time = ktime_get(); -} - -static void perf_show(const char *name) -{ - ktime_t t, setup_time, trans_time; - u32 total_bytes; - u32 setup_us, trans_us, total_us; - - t = ktime_get(); - - setup_time = ktime_sub(rfbi.perf_start_time, rfbi.perf_setup_time); - setup_us = (u32)ktime_to_us(setup_time); - if (setup_us == 0) - setup_us = 1; - - trans_time = ktime_sub(t, rfbi.perf_start_time); - trans_us = (u32)ktime_to_us(trans_time); - if (trans_us == 0) - trans_us = 1; - - total_us = setup_us + trans_us; - - total_bytes = rfbi.perf_bytes; - - DSSINFO("%s update %u us + %u us = %u us (%uHz), %u bytes, " - "%u kbytes/sec\n", - name, - setup_us, - trans_us, - total_us, - 1000*1000 / total_us, - total_bytes, - total_bytes * 1000 / total_us); -} -#else -#define perf_mark_setup() -#define perf_mark_start() -#define perf_show(x) -#endif - void rfbi_transfer_area(u16 width, u16 height, void (callback)(void *data), void *data) { @@ -396,8 +327,6 @@ void rfbi_transfer_area(u16 width, u16 height, if (!rfbi.te_enabled) l = FLD_MOD(l, 1, 4, 4); /* ITE */ - perf_mark_start(); - rfbi_write_reg(RFBI_CONTROL, l); } @@ -407,8 +336,6 @@ static void framedone_callback(void *data, u32 mask) DSSDBG("FRAMEDONE\n"); - perf_show("DISPC"); - REG_FLD_MOD(RFBI_CONTROL, 0, 0, 0); rfbi_enable_clocks(0); @@ -416,11 +343,10 @@ static void framedone_callback(void *data, u32 mask) callback = rfbi.framedone_callback; rfbi.framedone_callback = NULL; - /*callback(rfbi.framedone_callback_data);*/ + if (callback != NULL) + callback(rfbi.framedone_callback_data); atomic_set(&rfbi.cmd_pending, 0); - - process_cmd_fifo(); } #if 1 /* VERBOSE */ @@ -937,52 +863,43 @@ int rfbi_configure(int rfbi_module, int bpp, int lines) } EXPORT_SYMBOL(rfbi_configure); -static int rfbi_find_display(struct omap_dss_device *dssdev) +int omap_rfbi_prepare_update(struct omap_dss_device *dssdev, + u16 *x, u16 *y, u16 *w, u16 *h) { - if (dssdev == rfbi.dssdev[0]) - return 0; + u16 dw, dh; - if (dssdev == rfbi.dssdev[1]) - return 1; + dssdev->driver->get_resolution(dssdev, &dw, &dh); - BUG(); - return -1; -} + if (*x > dw || *y > dh) + return -EINVAL; + if (*x + *w > dw) + return -EINVAL; -static void signal_fifo_waiters(void) -{ - if (atomic_read(&rfbi.cmd_fifo_full) > 0) { - /* DSSDBG("SIGNALING: Fifo not full for waiter!\n"); */ - complete(&rfbi.cmd_done); - atomic_dec(&rfbi.cmd_fifo_full); - } -} + if (*y + *h > dh) + return -EINVAL; -/* returns 1 for async op, and 0 for sync op */ -static int do_update(struct omap_dss_device *dssdev, struct update_region *upd) -{ - u16 x = upd->x; - u16 y = upd->y; - u16 w = upd->w; - u16 h = upd->h; + if (*w == 1) + return -EINVAL; - perf_mark_setup(); + if (*w == 0 || *h == 0) + return -EINVAL; if (dssdev->manager->caps & OMAP_DSS_OVL_MGR_CAP_DISPC) { - /*dssdev->driver->enable_te(dssdev, 1); */ - dss_setup_partial_planes(dssdev, &x, &y, &w, &h); + dss_setup_partial_planes(dssdev, x, y, w, h); + dispc_set_lcd_size(*w, *h); } -#ifdef MEASURE_PERF - rfbi.perf_bytes = w * h * 2; /* XXX always 16bit */ -#endif - - dssdev->driver->setup_update(dssdev, x, y, w, h); + return 0; +} +EXPORT_SYMBOL(omap_rfbi_prepare_update); +int omap_rfbi_update(struct omap_dss_device *dssdev, + u16 x, u16 y, u16 w, u16 h, + void (*callback)(void *), void *data) +{ if (dssdev->manager->caps & OMAP_DSS_OVL_MGR_CAP_DISPC) { - rfbi_transfer_area(w, h, NULL, NULL); - return 1; + rfbi_transfer_area(w, h, callback, data); } else { struct omap_overlay *ovl; void __iomem *addr; @@ -994,123 +911,12 @@ static int do_update(struct omap_dss_device *dssdev, struct update_region *upd) omap_rfbi_write_pixels(addr, scr_width, x, y, w, h); - perf_show("L4"); - - return 0; - } -} - -static void process_cmd_fifo(void) -{ - int len; - struct update_param p; - struct omap_dss_device *dssdev; - unsigned long flags; - - if (atomic_inc_return(&rfbi.cmd_pending) != 1) - return; - - while (true) { - spin_lock_irqsave(&rfbi.cmd_lock, flags); - - len = kfifo_out(&rfbi.cmd_fifo, (unsigned char *)&p, - sizeof(struct update_param)); - if (len == 0) { - DSSDBG("nothing more in fifo\n"); - atomic_set(&rfbi.cmd_pending, 0); - spin_unlock_irqrestore(&rfbi.cmd_lock, flags); - break; - } - - /* DSSDBG("fifo full %d\n", rfbi.cmd_fifo_full.counter);*/ - - spin_unlock_irqrestore(&rfbi.cmd_lock, flags); - - BUG_ON(len != sizeof(struct update_param)); - BUG_ON(p.rfbi_module > 1); - - dssdev = rfbi.dssdev[p.rfbi_module]; - - if (p.cmd == RFBI_CMD_UPDATE) { - if (do_update(dssdev, &p.par.r)) - break; /* async op */ - } else if (p.cmd == RFBI_CMD_SYNC) { - DSSDBG("Signaling SYNC done!\n"); - complete(p.par.sync); - } else - BUG(); + callback(data); } - signal_fifo_waiters(); -} - -static void rfbi_push_cmd(struct update_param *p) -{ - int ret; - - while (1) { - unsigned long flags; - int available; - - spin_lock_irqsave(&rfbi.cmd_lock, flags); - available = RFBI_CMD_FIFO_LEN_BYTES - - kfifo_len(&rfbi.cmd_fifo); - -/* DSSDBG("%d bytes left in fifo\n", available); */ - if (available < sizeof(struct update_param)) { - DSSDBG("Going to wait because FIFO FULL..\n"); - spin_unlock_irqrestore(&rfbi.cmd_lock, flags); - atomic_inc(&rfbi.cmd_fifo_full); - wait_for_completion(&rfbi.cmd_done); - /*DSSDBG("Woke up because fifo not full anymore\n");*/ - continue; - } - - ret = kfifo_in(&rfbi.cmd_fifo, (unsigned char *)p, - sizeof(struct update_param)); -/* DSSDBG("pushed %d bytes\n", ret);*/ - - spin_unlock_irqrestore(&rfbi.cmd_lock, flags); - - BUG_ON(ret != sizeof(struct update_param)); - - break; - } -} - -static void rfbi_push_update(int rfbi_module, int x, int y, int w, int h) -{ - struct update_param p; - - p.rfbi_module = rfbi_module; - p.cmd = RFBI_CMD_UPDATE; - - p.par.r.x = x; - p.par.r.y = y; - p.par.r.w = w; - p.par.r.h = h; - - DSSDBG("RFBI pushed %d,%d %dx%d\n", x, y, w, h); - - rfbi_push_cmd(&p); - - process_cmd_fifo(); -} - -static void rfbi_push_sync(int rfbi_module, struct completion *sync_comp) -{ - struct update_param p; - - p.rfbi_module = rfbi_module; - p.cmd = RFBI_CMD_SYNC; - p.par.sync = sync_comp; - - rfbi_push_cmd(&p); - - DSSDBG("RFBI sync pushed to cmd fifo\n"); - - process_cmd_fifo(); + return 0; } +EXPORT_SYMBOL(omap_rfbi_update); void rfbi_dump_regs(struct seq_file *s) { @@ -1155,12 +961,8 @@ int rfbi_init(void) { u32 rev; u32 l; - int r; spin_lock_init(&rfbi.cmd_lock); - r = kfifo_alloc(&rfbi.cmd_fifo, RFBI_CMD_FIFO_LEN_BYTES, GFP_KERNEL); - if (r) - return r; init_completion(&rfbi.cmd_done); atomic_set(&rfbi.cmd_fifo_full, 0); @@ -1196,42 +998,10 @@ void rfbi_exit(void) { DSSDBG("rfbi_exit\n"); - kfifo_free(&rfbi.cmd_fifo); - iounmap(rfbi.base); } /* struct omap_display support */ -static int rfbi_display_update(struct omap_dss_device *dssdev, - u16 x, u16 y, u16 w, u16 h) -{ - int rfbi_module; - - if (w == 0 || h == 0) - return 0; - - rfbi_module = rfbi_find_display(dssdev); - - rfbi_push_update(rfbi_module, x, y, w, h); - - return 0; -} - -static int rfbi_display_sync(struct omap_dss_device *dssdev) -{ - struct completion sync_comp; - int rfbi_module; - - rfbi_module = rfbi_find_display(dssdev); - - init_completion(&sync_comp); - rfbi_push_sync(rfbi_module, &sync_comp); - DSSDBG("Waiting for SYNC to happen...\n"); - wait_for_completion(&sync_comp); - DSSDBG("Released from SYNC\n"); - return 0; -} - static int rfbi_display_enable(struct omap_dss_device *dssdev) { int r; @@ -1291,8 +1061,6 @@ int rfbi_init_display(struct omap_dss_device *dssdev) { dssdev->enable = rfbi_display_enable; dssdev->disable = rfbi_display_disable; - dssdev->update = rfbi_display_update; - dssdev->sync = rfbi_display_sync; rfbi.dssdev[dssdev->phy.rfbi.channel] = dssdev; diff --git a/drivers/video/omap2/omapfb/omapfb-ioctl.c b/drivers/video/omap2/omapfb/omapfb-ioctl.c index 4f68cb0d59de..1ffa760b8545 100644 --- a/drivers/video/omap2/omapfb/omapfb-ioctl.c +++ b/drivers/video/omap2/omapfb/omapfb-ioctl.c @@ -172,7 +172,7 @@ static int omapfb_update_window_nolock(struct fb_info *fbi, if (x + w > dw || y + h > dh) return -EINVAL; - return display->update(display, x, y, w, h); + return display->driver->update(display, x, y, w, h); } /* This function is exported for SGX driver use */ @@ -496,18 +496,18 @@ int omapfb_ioctl(struct fb_info *fbi, unsigned int cmd, unsigned long arg) switch (cmd) { case OMAPFB_SYNC_GFX: DBG("ioctl SYNC_GFX\n"); - if (!display || !display->sync) { + if (!display || !display->driver->sync) { /* DSS1 never returns an error here, so we neither */ /*r = -EINVAL;*/ break; } - r = display->sync(display); + r = display->driver->sync(display); break; case OMAPFB_UPDATE_WINDOW_OLD: DBG("ioctl UPDATE_WINDOW_OLD\n"); - if (!display || !display->update) { + if (!display || !display->driver->update) { r = -EINVAL; break; } @@ -525,7 +525,7 @@ int omapfb_ioctl(struct fb_info *fbi, unsigned int cmd, unsigned long arg) case OMAPFB_UPDATE_WINDOW: DBG("ioctl UPDATE_WINDOW\n"); - if (!display || !display->update) { + if (!display || !display->driver->update) { r = -EINVAL; break; } diff --git a/drivers/video/omap2/omapfb/omapfb-main.c b/drivers/video/omap2/omapfb/omapfb-main.c index c720842341b2..3dbbddc2d51e 100644 --- a/drivers/video/omap2/omapfb/omapfb-main.c +++ b/drivers/video/omap2/omapfb/omapfb-main.c @@ -1254,11 +1254,11 @@ static int omapfb_blank(int blank, struct fb_info *fbi) exit: omapfb_unlock(fbdev); - if (r == 0 && do_update && display->update) { + if (r == 0 && do_update && display->driver->update) { u16 w, h; display->driver->get_resolution(display, &w, &h); - r = display->update(display, 0, 0, w, h); + r = display->driver->update(display, 0, 0, w, h); } return r; @@ -1639,8 +1639,8 @@ int omapfb_realloc_fbmem(struct fb_info *fbi, unsigned long size, int type) if (old_size == size && old_type == type) return 0; - if (display && display->sync) - display->sync(display); + if (display && display->driver->sync) + display->driver->sync(display); omapfb_free_fbmem(fbi); @@ -2221,7 +2221,7 @@ static int omapfb_probe(struct platform_device *pdev) dssdrv->get_resolution(def_display, &w, &h); - def_display->update(def_display, 0, 0, w, h); + def_display->driver->update(def_display, 0, 0, w, h); #endif } else { if (dssdrv->set_update_mode) -- cgit v1.2.2 From 37ac60e414052f1d9301368437db8f0cb9e323fe Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Tue, 12 Jan 2010 15:12:07 +0200 Subject: OMAP: DSS2: move enable/disable/suspend/resume Move enable/disable/suspend/resume from omap_dss_device to omap_dss_driver. This is part of a larger patch-set, which moves the control from omapdss driver to the display driver. Signed-off-by: Tomi Valkeinen --- drivers/video/omap2/displays/panel-generic.c | 56 ++++- .../video/omap2/displays/panel-sharp-lq043t1dg01.c | 67 ++++-- .../video/omap2/displays/panel-sharp-ls037v7dw01.c | 42 +++- drivers/video/omap2/displays/panel-taal.c | 79 +++++-- .../video/omap2/displays/panel-toppoly-tdo35s.c | 56 ++++- .../video/omap2/displays/panel-tpo-td043mtea1.c | 61 ++++- drivers/video/omap2/dss/dispc.c | 12 +- drivers/video/omap2/dss/display.c | 14 +- drivers/video/omap2/dss/dpi.c | 102 +-------- drivers/video/omap2/dss/dsi.c | 136 ++--------- drivers/video/omap2/dss/rfbi.c | 22 +- drivers/video/omap2/dss/sdi.c | 75 +----- drivers/video/omap2/dss/venc.c | 251 ++++++++------------- drivers/video/omap2/omapfb/omapfb-main.c | 12 +- 14 files changed, 454 insertions(+), 531 deletions(-) (limited to 'drivers') diff --git a/drivers/video/omap2/displays/panel-generic.c b/drivers/video/omap2/displays/panel-generic.c index eb48d1afd800..c59e4baed8b2 100644 --- a/drivers/video/omap2/displays/panel-generic.c +++ b/drivers/video/omap2/displays/panel-generic.c @@ -35,6 +35,35 @@ static struct omap_video_timings generic_panel_timings = { .vbp = 7, }; +static int generic_panel_power_on(struct omap_dss_device *dssdev) +{ + int r; + + r = omapdss_dpi_display_enable(dssdev); + if (r) + goto err0; + + if (dssdev->platform_enable) { + r = dssdev->platform_enable(dssdev); + if (r) + goto err1; + } + + return 0; +err1: + omapdss_dpi_display_disable(dssdev); +err0: + return r; +} + +static void generic_panel_power_off(struct omap_dss_device *dssdev) +{ + if (dssdev->platform_disable) + dssdev->platform_disable(dssdev); + + omapdss_dpi_display_disable(dssdev); +} + static int generic_panel_probe(struct omap_dss_device *dssdev) { dssdev->panel.config = OMAP_DSS_LCD_TFT; @@ -51,27 +80,40 @@ static int generic_panel_enable(struct omap_dss_device *dssdev) { int r = 0; - if (dssdev->platform_enable) - r = dssdev->platform_enable(dssdev); + r = generic_panel_power_on(dssdev); + if (r) + return r; - return r; + dssdev->state = OMAP_DSS_DISPLAY_ACTIVE; + + return 0; } static void generic_panel_disable(struct omap_dss_device *dssdev) { - if (dssdev->platform_disable) - dssdev->platform_disable(dssdev); + generic_panel_power_off(dssdev); + + dssdev->state = OMAP_DSS_DISPLAY_DISABLED; } static int generic_panel_suspend(struct omap_dss_device *dssdev) { - generic_panel_disable(dssdev); + generic_panel_power_off(dssdev); + dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED; return 0; } static int generic_panel_resume(struct omap_dss_device *dssdev) { - return generic_panel_enable(dssdev); + int r = 0; + + r = generic_panel_power_on(dssdev); + if (r) + return r; + + dssdev->state = OMAP_DSS_DISPLAY_ACTIVE; + + return 0; } static struct omap_dss_driver generic_driver = { diff --git a/drivers/video/omap2/displays/panel-sharp-lq043t1dg01.c b/drivers/video/omap2/displays/panel-sharp-lq043t1dg01.c index e75798edbb59..10267461991c 100644 --- a/drivers/video/omap2/displays/panel-sharp-lq043t1dg01.c +++ b/drivers/video/omap2/displays/panel-sharp-lq043t1dg01.c @@ -39,6 +39,41 @@ static struct omap_video_timings sharp_lq_timings = { .vbp = 2, }; +static int sharp_lq_panel_power_on(struct omap_dss_device *dssdev) +{ + int r; + + r = omapdss_dpi_display_enable(dssdev); + if (r) + goto err0; + + /* wait couple of vsyncs until enabling the LCD */ + msleep(50); + + if (dssdev->platform_enable) { + r = dssdev->platform_enable(dssdev); + if (r) + goto err1; + } + + return 0; +err1: + omapdss_dpi_display_disable(dssdev); +err0: + return r; +} + +static void sharp_lq_panel_power_off(struct omap_dss_device *dssdev) +{ + if (dssdev->platform_disable) + dssdev->platform_disable(dssdev); + + /* wait at least 5 vsyncs after disabling the LCD */ + msleep(100); + + omapdss_dpi_display_disable(dssdev); +} + static int sharp_lq_panel_probe(struct omap_dss_device *dssdev) { @@ -58,36 +93,40 @@ static int sharp_lq_panel_enable(struct omap_dss_device *dssdev) { int r = 0; + r = sharp_lq_panel_power_on(dssdev); + if (r) + return r; - /* wait couple of vsyncs until enabling the LCD */ - msleep(50); - - if (dssdev->platform_enable) - r = dssdev->platform_enable(dssdev); + dssdev->state = OMAP_DSS_DISPLAY_ACTIVE; - return r; + return 0; } static void sharp_lq_panel_disable(struct omap_dss_device *dssdev) { + sharp_lq_panel_power_off(dssdev); - if (dssdev->platform_disable) - dssdev->platform_disable(dssdev); - - /* wait at least 5 vsyncs after disabling the LCD */ - - msleep(100); + dssdev->state = OMAP_DSS_DISPLAY_DISABLED; } static int sharp_lq_panel_suspend(struct omap_dss_device *dssdev) { - sharp_lq_panel_disable(dssdev); + sharp_lq_panel_power_off(dssdev); + dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED; return 0; } static int sharp_lq_panel_resume(struct omap_dss_device *dssdev) { - return sharp_lq_panel_enable(dssdev); + int r = 0; + + r = sharp_lq_panel_power_on(dssdev); + if (r) + return r; + + dssdev->state = OMAP_DSS_DISPLAY_ACTIVE; + + return 0; } static struct omap_dss_driver sharp_lq_driver = { diff --git a/drivers/video/omap2/displays/panel-sharp-ls037v7dw01.c b/drivers/video/omap2/displays/panel-sharp-ls037v7dw01.c index e207d66908d6..8d51a5e6341c 100644 --- a/drivers/video/omap2/displays/panel-sharp-ls037v7dw01.c +++ b/drivers/video/omap2/displays/panel-sharp-ls037v7dw01.c @@ -20,7 +20,6 @@ #include #include #include -#include #include #include @@ -54,20 +53,31 @@ static void sharp_ls_panel_remove(struct omap_dss_device *dssdev) { } -static int sharp_ls_panel_enable(struct omap_dss_device *dssdev) +static int sharp_ls_power_on(struct omap_dss_device *dssdev) { int r = 0; + r = omapdss_dpi_display_enable(dssdev); + if (r) + goto err0; + /* wait couple of vsyncs until enabling the LCD */ msleep(50); - if (dssdev->platform_enable) + if (dssdev->platform_enable) { r = dssdev->platform_enable(dssdev); + if (r) + goto err1; + } + return 0; +err1: + omapdss_dpi_display_disable(dssdev); +err0: return r; } -static void sharp_ls_panel_disable(struct omap_dss_device *dssdev) +static void sharp_ls_power_off(struct omap_dss_device *dssdev) { if (dssdev->platform_disable) dssdev->platform_disable(dssdev); @@ -75,17 +85,37 @@ static void sharp_ls_panel_disable(struct omap_dss_device *dssdev) /* wait at least 5 vsyncs after disabling the LCD */ msleep(100); + + omapdss_dpi_display_disable(dssdev); +} + +static int sharp_ls_panel_enable(struct omap_dss_device *dssdev) +{ + int r; + r = sharp_ls_power_on(dssdev); + dssdev->state = OMAP_DSS_DISPLAY_ACTIVE; + return r; +} + +static void sharp_ls_panel_disable(struct omap_dss_device *dssdev) +{ + sharp_ls_power_off(dssdev); + dssdev->state = OMAP_DSS_DISPLAY_DISABLED; } static int sharp_ls_panel_suspend(struct omap_dss_device *dssdev) { - sharp_ls_panel_disable(dssdev); + sharp_ls_power_off(dssdev); + dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED; return 0; } static int sharp_ls_panel_resume(struct omap_dss_device *dssdev) { - return sharp_ls_panel_enable(dssdev); + int r; + r = sharp_ls_power_on(dssdev); + dssdev->state = OMAP_DSS_DISPLAY_ACTIVE; + return r; } static struct omap_dss_driver sharp_ls_driver = { diff --git a/drivers/video/omap2/displays/panel-taal.c b/drivers/video/omap2/displays/panel-taal.c index 58293203fc05..484a61844763 100644 --- a/drivers/video/omap2/displays/panel-taal.c +++ b/drivers/video/omap2/displays/panel-taal.c @@ -620,14 +620,12 @@ static void taal_remove(struct omap_dss_device *dssdev) kfree(td); } -static int taal_enable(struct omap_dss_device *dssdev) +static int taal_power_on(struct omap_dss_device *dssdev) { struct taal_data *td = dev_get_drvdata(&dssdev->dev); u8 id1, id2, id3; int r; - dev_dbg(&dssdev->dev, "enable\n"); - if (dssdev->platform_enable) { r = dssdev->platform_enable(dssdev); if (r) @@ -637,6 +635,16 @@ static int taal_enable(struct omap_dss_device *dssdev) /* it seems we have to wait a bit until taal is ready */ msleep(5); + dsi_bus_lock(); + + r = omapdss_dsi_display_enable(dssdev); + if (r) { + dev_err(&dssdev->dev, "failed to enable DSI\n"); + goto err0; + } + + omapdss_dsi_vc_enable_hs(TCH, false); + r = taal_sleep_out(td); if (r) goto err; @@ -675,19 +683,27 @@ static int taal_enable(struct omap_dss_device *dssdev) td->intro_printed = true; } + omapdss_dsi_vc_enable_hs(TCH, true); + + dsi_bus_unlock(); + return 0; err: + dsi_bus_unlock(); + + omapdss_dsi_display_disable(dssdev); +err0: if (dssdev->platform_disable) dssdev->platform_disable(dssdev); return r; } -static void taal_disable(struct omap_dss_device *dssdev) +static void taal_power_off(struct omap_dss_device *dssdev) { struct taal_data *td = dev_get_drvdata(&dssdev->dev); - dev_dbg(&dssdev->dev, "disable\n"); + dsi_bus_lock(); cancel_delayed_work(&td->esd_work); @@ -697,32 +713,67 @@ static void taal_disable(struct omap_dss_device *dssdev) /* wait a bit so that the message goes through */ msleep(10); + omapdss_dsi_display_disable(dssdev); + if (dssdev->platform_disable) dssdev->platform_disable(dssdev); td->enabled = 0; + + dsi_bus_unlock(); +} + +static int taal_enable(struct omap_dss_device *dssdev) +{ + int r; + dev_dbg(&dssdev->dev, "enable\n"); + + if (dssdev->state != OMAP_DSS_DISPLAY_DISABLED) + return -EINVAL; + + r = taal_power_on(dssdev); + if (r) + return r; + + dssdev->state = OMAP_DSS_DISPLAY_ACTIVE; + + return r; +} + +static void taal_disable(struct omap_dss_device *dssdev) +{ + dev_dbg(&dssdev->dev, "disable\n"); + + if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) + taal_power_off(dssdev); + + dssdev->state = OMAP_DSS_DISPLAY_DISABLED; } static int taal_suspend(struct omap_dss_device *dssdev) { - struct taal_data *td = dev_get_drvdata(&dssdev->dev); - struct backlight_device *bldev = td->bldev; + dev_dbg(&dssdev->dev, "suspend\n"); - bldev->props.power = FB_BLANK_POWERDOWN; - taal_bl_update_status(bldev); + if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE) + return -EINVAL; + + taal_power_off(dssdev); + dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED; return 0; } static int taal_resume(struct omap_dss_device *dssdev) { - struct taal_data *td = dev_get_drvdata(&dssdev->dev); - struct backlight_device *bldev = td->bldev; + int r; + dev_dbg(&dssdev->dev, "resume\n"); - bldev->props.power = FB_BLANK_UNBLANK; - taal_bl_update_status(bldev); + if (dssdev->state != OMAP_DSS_DISPLAY_SUSPENDED) + return -EINVAL; - return 0; + r = taal_power_on(dssdev); + dssdev->state = OMAP_DSS_DISPLAY_ACTIVE; + return r; } static void taal_framedone_cb(int err, void *data) diff --git a/drivers/video/omap2/displays/panel-toppoly-tdo35s.c b/drivers/video/omap2/displays/panel-toppoly-tdo35s.c index e744b8c83817..fa434ca6e4b7 100644 --- a/drivers/video/omap2/displays/panel-toppoly-tdo35s.c +++ b/drivers/video/omap2/displays/panel-toppoly-tdo35s.c @@ -42,6 +42,35 @@ static struct omap_video_timings toppoly_tdo_panel_timings = { .vbp = 2, }; +static int toppoly_tdo_panel_power_on(struct omap_dss_device *dssdev) +{ + int r; + + r = omapdss_dpi_display_enable(dssdev); + if (r) + goto err0; + + if (dssdev->platform_enable) { + r = dssdev->platform_enable(dssdev); + if (r) + goto err1; + } + + return 0; +err1: + omapdss_dpi_display_disable(dssdev); +err0: + return r; +} + +static void toppoly_tdo_panel_power_off(struct omap_dss_device *dssdev) +{ + if (dssdev->platform_disable) + dssdev->platform_disable(dssdev); + + omapdss_dpi_display_disable(dssdev); +} + static int toppoly_tdo_panel_probe(struct omap_dss_device *dssdev) { dssdev->panel.config = OMAP_DSS_LCD_TFT | OMAP_DSS_LCD_IVS | @@ -59,27 +88,40 @@ static int toppoly_tdo_panel_enable(struct omap_dss_device *dssdev) { int r = 0; - if (dssdev->platform_enable) - r = dssdev->platform_enable(dssdev); + r = toppoly_tdo_panel_power_on(dssdev); + if (r) + return r; - return r; + dssdev->state = OMAP_DSS_DISPLAY_ACTIVE; + + return 0; } static void toppoly_tdo_panel_disable(struct omap_dss_device *dssdev) { - if (dssdev->platform_disable) - dssdev->platform_disable(dssdev); + toppoly_tdo_panel_power_off(dssdev); + + dssdev->state = OMAP_DSS_DISPLAY_DISABLED; } static int toppoly_tdo_panel_suspend(struct omap_dss_device *dssdev) { - toppoly_tdo_panel_disable(dssdev); + toppoly_tdo_panel_power_off(dssdev); + dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED; return 0; } static int toppoly_tdo_panel_resume(struct omap_dss_device *dssdev) { - return toppoly_tdo_panel_enable(dssdev); + int r = 0; + + r = toppoly_tdo_panel_power_on(dssdev); + if (r) + return r; + + dssdev->state = OMAP_DSS_DISPLAY_ACTIVE; + + return 0; } static struct omap_dss_driver generic_driver = { diff --git a/drivers/video/omap2/displays/panel-tpo-td043mtea1.c b/drivers/video/omap2/displays/panel-tpo-td043mtea1.c index f297a46f2b1a..c6e4a7e9f532 100644 --- a/drivers/video/omap2/displays/panel-tpo-td043mtea1.c +++ b/drivers/video/omap2/displays/panel-tpo-td043mtea1.c @@ -262,18 +262,20 @@ static const struct omap_video_timings tpo_td043_timings = { .vbp = 34, }; -static int tpo_td043_enable(struct omap_dss_device *dssdev) +static int generic_panel_power_on(struct omap_dss_device *dssdev) { struct tpo_td043_device *tpo_td043 = dev_get_drvdata(&dssdev->dev); int nreset_gpio = dssdev->reset_gpio; - int ret; + int r; - dev_dbg(&dssdev->dev, "enable\n"); + r = omapdss_dpi_display_enable(dssdev); + if (r) + goto err0; if (dssdev->platform_enable) { - ret = dssdev->platform_enable(dssdev); - if (ret) - return ret; + r = dssdev->platform_enable(dssdev); + if (r) + goto err1; } regulator_enable(tpo_td043->vcc_reg); @@ -294,15 +296,17 @@ static int tpo_td043_enable(struct omap_dss_device *dssdev) tpo_td043_write_gamma(tpo_td043->spi, tpo_td043->gamma); return 0; +err1: + omapdss_dpi_display_disable(dssdev); +err0: + return r; } -static void tpo_td043_disable(struct omap_dss_device *dssdev) +static void generic_panel_power_off(struct omap_dss_device *dssdev) { struct tpo_td043_device *tpo_td043 = dev_get_drvdata(&dssdev->dev); int nreset_gpio = dssdev->reset_gpio; - dev_dbg(&dssdev->dev, "disable\n"); - tpo_td043_write(tpo_td043->spi, 3, TPO_R03_VAL_STANDBY | TPO_R03_EN_PWM); @@ -318,17 +322,52 @@ static void tpo_td043_disable(struct omap_dss_device *dssdev) if (dssdev->platform_disable) dssdev->platform_disable(dssdev); + + omapdss_dpi_display_disable(dssdev); +} + +static int tpo_td043_enable(struct omap_dss_device *dssdev) +{ + int ret; + + dev_dbg(&dssdev->dev, "enable\n"); + + ret = generic_panel_power_on(dssdev); + if (ret) + return ret; + + dssdev->state = OMAP_DSS_DISPLAY_ACTIVE; + + return 0; +} + +static void tpo_td043_disable(struct omap_dss_device *dssdev) +{ + dev_dbg(&dssdev->dev, "disable\n"); + + generic_panel_power_off(dssdev); + + dssdev->state = OMAP_DSS_DISPLAY_DISABLED; } static int tpo_td043_suspend(struct omap_dss_device *dssdev) { - tpo_td043_disable(dssdev); + generic_panel_power_off(dssdev); + dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED; return 0; } static int tpo_td043_resume(struct omap_dss_device *dssdev) { - return tpo_td043_enable(dssdev); + int r = 0; + + r = generic_panel_power_on(dssdev); + if (r) + return r; + + dssdev->state = OMAP_DSS_DISPLAY_ACTIVE; + + return 0; } static int tpo_td043_probe(struct omap_dss_device *dssdev) diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c index 5a5c31c163c7..e777e352dbcd 100644 --- a/drivers/video/omap2/dss/dispc.c +++ b/drivers/video/omap2/dss/dispc.c @@ -2872,12 +2872,13 @@ static void dispc_error_worker(struct work_struct *work) manager = mgr; enable = mgr->device->state == OMAP_DSS_DISPLAY_ACTIVE; - mgr->device->disable(mgr->device); + mgr->device->driver->disable(mgr->device); break; } } if (manager) { + struct omap_dss_device *dssdev = manager->device; for (i = 0; i < omap_dss_get_num_overlays(); ++i) { struct omap_overlay *ovl; ovl = omap_dss_get_overlay(i); @@ -2892,7 +2893,7 @@ static void dispc_error_worker(struct work_struct *work) dispc_go(manager->id); mdelay(50); if (enable) - manager->device->enable(manager->device); + dssdev->driver->enable(dssdev); } } @@ -2910,12 +2911,13 @@ static void dispc_error_worker(struct work_struct *work) manager = mgr; enable = mgr->device->state == OMAP_DSS_DISPLAY_ACTIVE; - mgr->device->disable(mgr->device); + mgr->device->driver->disable(mgr->device); break; } } if (manager) { + struct omap_dss_device *dssdev = manager->device; for (i = 0; i < omap_dss_get_num_overlays(); ++i) { struct omap_overlay *ovl; ovl = omap_dss_get_overlay(i); @@ -2930,7 +2932,7 @@ static void dispc_error_worker(struct work_struct *work) dispc_go(manager->id); mdelay(50); if (enable) - manager->device->enable(manager->device); + dssdev->driver->enable(dssdev); } } @@ -2941,7 +2943,7 @@ static void dispc_error_worker(struct work_struct *work) mgr = omap_dss_get_overlay_manager(i); if (mgr->caps & OMAP_DSS_OVL_CAP_DISPC) - mgr->device->disable(mgr->device); + mgr->device->driver->disable(mgr->device); } } diff --git a/drivers/video/omap2/dss/display.c b/drivers/video/omap2/dss/display.c index 86996d8d65be..29ec5a4a46bc 100644 --- a/drivers/video/omap2/dss/display.c +++ b/drivers/video/omap2/dss/display.c @@ -53,11 +53,11 @@ static ssize_t display_enabled_store(struct device *dev, if (enabled != (dssdev->state != OMAP_DSS_DISPLAY_DISABLED)) { if (enabled) { - r = dssdev->enable(dssdev); + r = dssdev->driver->enable(dssdev); if (r) return r; } else { - dssdev->disable(dssdev); + dssdev->driver->disable(dssdev); } } @@ -485,13 +485,13 @@ static int dss_suspend_device(struct device *dev, void *data) return 0; } - if (!dssdev->suspend) { + if (!dssdev->driver->suspend) { DSSERR("display '%s' doesn't implement suspend\n", dssdev->name); return -ENOSYS; } - r = dssdev->suspend(dssdev); + r = dssdev->driver->suspend(dssdev); if (r) return r; @@ -520,8 +520,8 @@ static int dss_resume_device(struct device *dev, void *data) int r; struct omap_dss_device *dssdev = to_dss_device(dev); - if (dssdev->activate_after_resume && dssdev->resume) { - r = dssdev->resume(dssdev); + if (dssdev->activate_after_resume && dssdev->driver->resume) { + r = dssdev->driver->resume(dssdev); if (r) return r; } @@ -541,7 +541,7 @@ int dss_resume_all_devices(void) static int dss_disable_device(struct device *dev, void *data) { struct omap_dss_device *dssdev = to_dss_device(dev); - dssdev->disable(dssdev); + dssdev->driver->disable(dssdev); return 0; } diff --git a/drivers/video/omap2/dss/dpi.c b/drivers/video/omap2/dss/dpi.c index 48ff7ea470aa..1eef8b72dbb9 100644 --- a/drivers/video/omap2/dss/dpi.c +++ b/drivers/video/omap2/dss/dpi.c @@ -153,7 +153,7 @@ static int dpi_basic_init(struct omap_dss_device *dssdev) return 0; } -static int dpi_display_enable(struct omap_dss_device *dssdev) +int omapdss_dpi_display_enable(struct omap_dss_device *dssdev) { int r; @@ -163,57 +163,42 @@ static int dpi_display_enable(struct omap_dss_device *dssdev) goto err0; } - if (dssdev->state != OMAP_DSS_DISPLAY_DISABLED) { - DSSERR("display already enabled\n"); - r = -EINVAL; - goto err1; - } - if (cpu_is_omap34xx()) { r = regulator_enable(dpi.vdds_dsi_reg); if (r) - goto err2; + goto err1; } dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1); r = dpi_basic_init(dssdev); if (r) - goto err3; + goto err2; #ifdef CONFIG_OMAP2_DSS_USE_DSI_PLL dss_clk_enable(DSS_CLK_FCK2); r = dsi_pll_init(dssdev, 0, 1); if (r) - goto err4; + goto err3; #endif r = dpi_set_mode(dssdev); if (r) - goto err5; + goto err4; mdelay(2); dssdev->manager->enable(dssdev->manager); - r = dssdev->driver->enable(dssdev); - if (r) - goto err6; - - dssdev->state = OMAP_DSS_DISPLAY_ACTIVE; - return 0; -err6: - dssdev->manager->disable(dssdev->manager); -err5: +err4: #ifdef CONFIG_OMAP2_DSS_USE_DSI_PLL dsi_pll_uninit(); -err4: +err3: dss_clk_disable(DSS_CLK_FCK2); #endif -err3: - dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1); err2: + dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1); if (cpu_is_omap34xx()) regulator_disable(dpi.vdds_dsi_reg); err1: @@ -221,19 +206,10 @@ err1: err0: return r; } +EXPORT_SYMBOL(omapdss_dpi_display_enable); -static int dpi_display_resume(struct omap_dss_device *dssdev); - -static void dpi_display_disable(struct omap_dss_device *dssdev) +void omapdss_dpi_display_disable(struct omap_dss_device *dssdev) { - if (dssdev->state == OMAP_DSS_DISPLAY_DISABLED) - return; - - if (dssdev->state == OMAP_DSS_DISPLAY_SUSPENDED) - dpi_display_resume(dssdev); - - dssdev->driver->disable(dssdev); - dssdev->manager->disable(dssdev->manager); #ifdef CONFIG_OMAP2_DSS_USE_DSI_PLL @@ -247,61 +223,9 @@ static void dpi_display_disable(struct omap_dss_device *dssdev) if (cpu_is_omap34xx()) regulator_disable(dpi.vdds_dsi_reg); - dssdev->state = OMAP_DSS_DISPLAY_DISABLED; - omap_dss_stop_device(dssdev); } - -static int dpi_display_suspend(struct omap_dss_device *dssdev) -{ - if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE) - return -EINVAL; - - DSSDBG("dpi_display_suspend\n"); - - if (dssdev->driver->suspend) - dssdev->driver->suspend(dssdev); - - dssdev->manager->disable(dssdev->manager); - - dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1); - - if (cpu_is_omap34xx()) - regulator_disable(dpi.vdds_dsi_reg); - - dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED; - - return 0; -} - -static int dpi_display_resume(struct omap_dss_device *dssdev) -{ - int r; - - if (dssdev->state != OMAP_DSS_DISPLAY_SUSPENDED) - return -EINVAL; - - DSSDBG("dpi_display_resume\n"); - - if (cpu_is_omap34xx()) { - r = regulator_enable(dpi.vdds_dsi_reg); - if (r) - goto err0; - } - - dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1); - - dssdev->manager->enable(dssdev->manager); - - if (dssdev->driver->resume) - dssdev->driver->resume(dssdev); - - dssdev->state = OMAP_DSS_DISPLAY_ACTIVE; - - return 0; -err0: - return r; -} +EXPORT_SYMBOL(omapdss_dpi_display_disable); static void dpi_set_timings(struct omap_dss_device *dssdev, struct omap_video_timings *timings) @@ -379,10 +303,6 @@ int dpi_init_display(struct omap_dss_device *dssdev) { DSSDBG("init_display\n"); - dssdev->enable = dpi_display_enable; - dssdev->disable = dpi_display_disable; - dssdev->suspend = dpi_display_suspend; - dssdev->resume = dpi_display_resume; dssdev->set_timings = dpi_set_timings; dssdev->check_timings = dpi_check_timings; dssdev->get_timings = dpi_get_timings; diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c index 203b18bbddae..41cdefbaf7f3 100644 --- a/drivers/video/omap2/dss/dsi.c +++ b/drivers/video/omap2/dss/dsi.c @@ -3106,18 +3106,7 @@ static int dsi_display_init_dsi(struct omap_dss_device *dssdev) dsi_if_enable(1); dsi_force_tx_stop_mode_io(); - if (dssdev->driver->enable) { - r = dssdev->driver->enable(dssdev); - if (r) - goto err4; - } - - /* enable high-speed after initial config */ - omapdss_dsi_vc_enable_hs(0, 1); - return 0; -err4: - dsi_if_enable(0); err3: dsi_complexio_uninit(); err2: @@ -3131,9 +3120,6 @@ err0: static void dsi_display_uninit_dsi(struct omap_dss_device *dssdev) { - if (dssdev->driver->disable) - dssdev->driver->disable(dssdev); - dss_select_dispc_clk_source(DSS_SRC_DSS1_ALWON_FCLK); dss_select_dsi_clk_source(DSS_SRC_DSS1_ALWON_FCLK); dsi_complexio_uninit(); @@ -3156,14 +3142,15 @@ static int dsi_core_init(void) return 0; } -static int dsi_display_enable(struct omap_dss_device *dssdev) +int omapdss_dsi_display_enable(struct omap_dss_device *dssdev) { int r = 0; DSSDBG("dsi_display_enable\n"); + WARN_ON(!dsi_bus_is_locked()); + mutex_lock(&dsi.lock); - dsi_bus_lock(); r = omap_dss_start_device(dssdev); if (r) { @@ -3171,90 +3158,49 @@ static int dsi_display_enable(struct omap_dss_device *dssdev) goto err0; } - if (dssdev->state != OMAP_DSS_DISPLAY_DISABLED) { - DSSERR("dssdev already enabled\n"); - r = -EINVAL; - goto err1; - } - enable_clocks(1); dsi_enable_pll_clock(1); r = _dsi_reset(); if (r) - goto err2; + goto err1; dsi_core_init(); r = dsi_display_init_dispc(dssdev); if (r) - goto err2; + goto err1; r = dsi_display_init_dsi(dssdev); if (r) - goto err3; - - dssdev->state = OMAP_DSS_DISPLAY_ACTIVE; + goto err2; dsi.use_ext_te = dssdev->phy.dsi.ext_te; - dsi_bus_unlock(); mutex_unlock(&dsi.lock); return 0; -err3: - dsi_display_uninit_dispc(dssdev); err2: + dsi_display_uninit_dispc(dssdev); +err1: enable_clocks(0); dsi_enable_pll_clock(0); -err1: omap_dss_stop_device(dssdev); err0: - dsi_bus_unlock(); mutex_unlock(&dsi.lock); DSSDBG("dsi_display_enable FAILED\n"); return r; } +EXPORT_SYMBOL(omapdss_dsi_display_enable); -static void dsi_display_disable(struct omap_dss_device *dssdev) +void omapdss_dsi_display_disable(struct omap_dss_device *dssdev) { DSSDBG("dsi_display_disable\n"); - mutex_lock(&dsi.lock); - dsi_bus_lock(); - - if (dssdev->state == OMAP_DSS_DISPLAY_DISABLED || - dssdev->state == OMAP_DSS_DISPLAY_SUSPENDED) - goto end; - - dssdev->state = OMAP_DSS_DISPLAY_DISABLED; - - dsi_display_uninit_dispc(dssdev); - - dsi_display_uninit_dsi(dssdev); - - enable_clocks(0); - dsi_enable_pll_clock(0); - - omap_dss_stop_device(dssdev); -end: - dsi_bus_unlock(); - mutex_unlock(&dsi.lock); -} - -static int dsi_display_suspend(struct omap_dss_device *dssdev) -{ - DSSDBG("dsi_display_suspend\n"); + WARN_ON(!dsi_bus_is_locked()); mutex_lock(&dsi.lock); - dsi_bus_lock(); - - if (dssdev->state == OMAP_DSS_DISPLAY_DISABLED || - dssdev->state == OMAP_DSS_DISPLAY_SUSPENDED) - goto end; - - dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED; dsi_display_uninit_dispc(dssdev); @@ -3262,63 +3208,12 @@ static int dsi_display_suspend(struct omap_dss_device *dssdev) enable_clocks(0); dsi_enable_pll_clock(0); -end: - dsi_bus_unlock(); - mutex_unlock(&dsi.lock); - return 0; -} - -static int dsi_display_resume(struct omap_dss_device *dssdev) -{ - int r; - - DSSDBG("dsi_display_resume\n"); - - mutex_lock(&dsi.lock); - dsi_bus_lock(); - - if (dssdev->state != OMAP_DSS_DISPLAY_SUSPENDED) { - DSSERR("dssdev not suspended\n"); - r = -EINVAL; - goto err0; - } - - enable_clocks(1); - dsi_enable_pll_clock(1); - - r = _dsi_reset(); - if (r) - goto err1; - - dsi_core_init(); - - r = dsi_display_init_dispc(dssdev); - if (r) - goto err1; - - r = dsi_display_init_dsi(dssdev); - if (r) - goto err2; - - dssdev->state = OMAP_DSS_DISPLAY_ACTIVE; - - dsi_bus_unlock(); - mutex_unlock(&dsi.lock); - - return 0; + omap_dss_stop_device(dssdev); -err2: - dsi_display_uninit_dispc(dssdev); -err1: - enable_clocks(0); - dsi_enable_pll_clock(0); -err0: - dsi_bus_unlock(); mutex_unlock(&dsi.lock); - DSSDBG("dsi_display_resume FAILED\n"); - return r; } +EXPORT_SYMBOL(omapdss_dsi_display_disable); int omapdss_dsi_enable_te(struct omap_dss_device *dssdev, bool enable) { @@ -3344,11 +3239,6 @@ int dsi_init_display(struct omap_dss_device *dssdev) { DSSDBG("DSI init\n"); - dssdev->enable = dsi_display_enable; - dssdev->disable = dsi_display_disable; - dssdev->suspend = dsi_display_suspend; - dssdev->resume = dsi_display_resume; - /* XXX these should be figured out dynamically */ dssdev->caps = OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE | OMAP_DSS_DISPLAY_CAP_TEAR_ELIM; diff --git a/drivers/video/omap2/dss/rfbi.c b/drivers/video/omap2/dss/rfbi.c index a6b33160666a..cc23f53cc62d 100644 --- a/drivers/video/omap2/dss/rfbi.c +++ b/drivers/video/omap2/dss/rfbi.c @@ -1001,8 +1001,7 @@ void rfbi_exit(void) iounmap(rfbi.base); } -/* struct omap_display support */ -static int rfbi_display_enable(struct omap_dss_device *dssdev) +int omapdss_rfbi_display_enable(struct omap_dss_device *dssdev) { int r; @@ -1033,38 +1032,25 @@ static int rfbi_display_enable(struct omap_dss_device *dssdev) &dssdev->ctrl.rfbi_timings); - if (dssdev->driver->enable) { - r = dssdev->driver->enable(dssdev); - if (r) - goto err2; - } - return 0; -err2: - omap_dispc_unregister_isr(framedone_callback, NULL, - DISPC_IRQ_FRAMEDONE); err1: omap_dss_stop_device(dssdev); err0: return r; } +EXPORT_SYMBOL(omapdss_rfbi_display_enable); -static void rfbi_display_disable(struct omap_dss_device *dssdev) +void omapdss_rfbi_display_disable(struct omap_dss_device *dssdev) { - dssdev->driver->disable(dssdev); omap_dispc_unregister_isr(framedone_callback, NULL, DISPC_IRQ_FRAMEDONE); omap_dss_stop_device(dssdev); } +EXPORT_SYMBOL(omapdss_rfbi_display_disable); int rfbi_init_display(struct omap_dss_device *dssdev) { - dssdev->enable = rfbi_display_enable; - dssdev->disable = rfbi_display_disable; - rfbi.dssdev[dssdev->phy.rfbi.channel] = dssdev; - dssdev->caps = OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE; - return 0; } diff --git a/drivers/video/omap2/dss/sdi.c b/drivers/video/omap2/dss/sdi.c index 6bd9b0cf76a8..929ceb3ddd9d 100644 --- a/drivers/video/omap2/dss/sdi.c +++ b/drivers/video/omap2/dss/sdi.c @@ -41,7 +41,7 @@ static void sdi_basic_init(void) dispc_lcd_enable_signal_polarity(1); } -static int sdi_display_enable(struct omap_dss_device *dssdev) +int omapdss_sdi_display_enable(struct omap_dss_device *dssdev) { struct omap_video_timings *t = &dssdev->panel.timings; struct dss_clock_info dss_cinfo; @@ -57,12 +57,6 @@ static int sdi_display_enable(struct omap_dss_device *dssdev) goto err0; } - if (dssdev->state != OMAP_DSS_DISPLAY_DISABLED) { - DSSERR("dssdev already enabled\n"); - r = -EINVAL; - goto err1; - } - /* In case of skip_init sdi_init has already enabled the clocks */ if (!sdi.skip_init) dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1); @@ -127,8 +121,6 @@ static int sdi_display_enable(struct omap_dss_device *dssdev) goto err3; } - dssdev->state = OMAP_DSS_DISPLAY_ACTIVE; - sdi.skip_init = 0; return 0; @@ -141,18 +133,10 @@ err1: err0: return r; } +EXPORT_SYMBOL(omapdss_sdi_display_enable); -static int sdi_display_resume(struct omap_dss_device *dssdev); - -static void sdi_display_disable(struct omap_dss_device *dssdev) +void omapdss_sdi_display_disable(struct omap_dss_device *dssdev) { - if (dssdev->state == OMAP_DSS_DISPLAY_DISABLED) - return; - - if (dssdev->state == OMAP_DSS_DISPLAY_SUSPENDED) - if (sdi_display_resume(dssdev)) - return; - if (dssdev->driver->disable) dssdev->driver->disable(dssdev); @@ -162,56 +146,9 @@ static void sdi_display_disable(struct omap_dss_device *dssdev) dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1); - dssdev->state = OMAP_DSS_DISPLAY_DISABLED; - omap_dss_stop_device(dssdev); } - -static int sdi_display_suspend(struct omap_dss_device *dssdev) -{ - if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE) - return -EINVAL; - - if (dssdev->driver->suspend) - dssdev->driver->suspend(dssdev); - - dssdev->manager->disable(dssdev->manager); - - dss_sdi_disable(); - - dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1); - - dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED; - - return 0; -} - -static int sdi_display_resume(struct omap_dss_device *dssdev) -{ - int r; - - if (dssdev->state != OMAP_DSS_DISPLAY_SUSPENDED) - return -EINVAL; - - dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1); - - r = dss_sdi_enable(); - if (r) - goto err; - mdelay(2); - - dssdev->manager->enable(dssdev->manager); - - if (dssdev->driver->resume) - dssdev->driver->resume(dssdev); - - dssdev->state = OMAP_DSS_DISPLAY_ACTIVE; - - return 0; -err: - dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1); - return r; -} +EXPORT_SYMBOL(omapdss_sdi_display_disable); static void sdi_get_timings(struct omap_dss_device *dssdev, struct omap_video_timings *timings) @@ -223,10 +160,6 @@ int sdi_init_display(struct omap_dss_device *dssdev) { DSSDBG("SDI init\n"); - dssdev->enable = sdi_display_enable; - dssdev->disable = sdi_display_disable; - dssdev->suspend = sdi_display_suspend; - dssdev->resume = sdi_display_resume; dssdev->get_timings = sdi_get_timings; return 0; diff --git a/drivers/video/omap2/dss/venc.c b/drivers/video/omap2/dss/venc.c index 0d0dc94417fc..a0ab52c841ee 100644 --- a/drivers/video/omap2/dss/venc.c +++ b/drivers/video/omap2/dss/venc.c @@ -400,6 +400,56 @@ static const struct venc_config *venc_timings_to_config( BUG(); } +static void venc_power_on(struct omap_dss_device *dssdev) +{ + u32 l; + + venc_enable_clocks(1); + + venc_reset(); + venc_write_config(venc_timings_to_config(&dssdev->panel.timings)); + + dss_set_venc_output(dssdev->phy.venc.type); + dss_set_dac_pwrdn_bgz(1); + + l = 0; + + if (dssdev->phy.venc.type == OMAP_DSS_VENC_TYPE_COMPOSITE) + l |= 1 << 1; + else /* S-Video */ + l |= (1 << 0) | (1 << 2); + + if (dssdev->phy.venc.invert_polarity == false) + l |= 1 << 3; + + venc_write_reg(VENC_OUTPUT_CONTROL, l); + + dispc_set_digit_size(dssdev->panel.timings.x_res, + dssdev->panel.timings.y_res/2); + + regulator_enable(venc.vdda_dac_reg); + + if (dssdev->platform_enable) + dssdev->platform_enable(dssdev); + + dssdev->manager->enable(dssdev->manager); +} + +static void venc_power_off(struct omap_dss_device *dssdev) +{ + venc_write_reg(VENC_OUTPUT_CONTROL, 0); + dss_set_dac_pwrdn_bgz(0); + + dssdev->manager->disable(dssdev->manager); + + if (dssdev->platform_disable) + dssdev->platform_disable(dssdev); + + regulator_disable(venc.vdda_dac_reg); + + venc_enable_clocks(0); +} + @@ -420,23 +470,66 @@ static int venc_panel_enable(struct omap_dss_device *dssdev) { int r = 0; + DSSDBG("venc_enable_display\n"); + + mutex_lock(&venc.venc_lock); + + if (dssdev->state != OMAP_DSS_DISPLAY_DISABLED) { + r = -EINVAL; + goto err1; + } + + if (dssdev->platform_enable) { + r = dssdev->platform_enable(dssdev); + if (r) + goto err2; + } + + venc_power_on(dssdev); + + venc.wss_data = 0; + + dssdev->state = OMAP_DSS_DISPLAY_ACTIVE; + /* wait couple of vsyncs until enabling the LCD */ msleep(50); - if (dssdev->platform_enable) - r = dssdev->platform_enable(dssdev); + mutex_unlock(&venc.venc_lock); + return r; +err2: + venc_power_off(dssdev); +err1: + mutex_unlock(&venc.venc_lock); return r; } static void venc_panel_disable(struct omap_dss_device *dssdev) { - if (dssdev->platform_disable) - dssdev->platform_disable(dssdev); + DSSDBG("venc_disable_display\n"); - /* wait at least 5 vsyncs after disabling the LCD */ + mutex_lock(&venc.venc_lock); + + if (dssdev->state == OMAP_DSS_DISPLAY_DISABLED) + goto end; + if (dssdev->state == OMAP_DSS_DISPLAY_SUSPENDED) { + /* suspended is the same as disabled with venc */ + dssdev->state = OMAP_DSS_DISPLAY_DISABLED; + goto end; + } + + venc_power_off(dssdev); + + /* wait at least 5 vsyncs after disabling the LCD */ msleep(100); + + if (dssdev->platform_disable) + dssdev->platform_disable(dssdev); + + dssdev->state = OMAP_DSS_DISPLAY_DISABLED; +end: + mutex_unlock(&venc.venc_lock); } static int venc_panel_suspend(struct omap_dss_device *dssdev) @@ -526,146 +619,6 @@ void venc_exit(void) iounmap(venc.base); } -static void venc_power_on(struct omap_dss_device *dssdev) -{ - u32 l; - - venc_enable_clocks(1); - - venc_reset(); - venc_write_config(venc_timings_to_config(&dssdev->panel.timings)); - - dss_set_venc_output(dssdev->phy.venc.type); - dss_set_dac_pwrdn_bgz(1); - - l = 0; - - if (dssdev->phy.venc.type == OMAP_DSS_VENC_TYPE_COMPOSITE) - l |= 1 << 1; - else /* S-Video */ - l |= (1 << 0) | (1 << 2); - - if (dssdev->phy.venc.invert_polarity == false) - l |= 1 << 3; - - venc_write_reg(VENC_OUTPUT_CONTROL, l); - - dispc_set_digit_size(dssdev->panel.timings.x_res, - dssdev->panel.timings.y_res/2); - - regulator_enable(venc.vdda_dac_reg); - - if (dssdev->platform_enable) - dssdev->platform_enable(dssdev); - - dssdev->manager->enable(dssdev->manager); -} - -static void venc_power_off(struct omap_dss_device *dssdev) -{ - venc_write_reg(VENC_OUTPUT_CONTROL, 0); - dss_set_dac_pwrdn_bgz(0); - - dssdev->manager->disable(dssdev->manager); - - if (dssdev->platform_disable) - dssdev->platform_disable(dssdev); - - regulator_disable(venc.vdda_dac_reg); - - venc_enable_clocks(0); -} - -static int venc_enable_display(struct omap_dss_device *dssdev) -{ - int r = 0; - - DSSDBG("venc_enable_display\n"); - - mutex_lock(&venc.venc_lock); - - if (dssdev->state != OMAP_DSS_DISPLAY_DISABLED) { - r = -EINVAL; - goto err; - } - - venc_power_on(dssdev); - - venc.wss_data = 0; - - dssdev->state = OMAP_DSS_DISPLAY_ACTIVE; -err: - mutex_unlock(&venc.venc_lock); - - return r; -} - -static void venc_disable_display(struct omap_dss_device *dssdev) -{ - DSSDBG("venc_disable_display\n"); - - mutex_lock(&venc.venc_lock); - - if (dssdev->state == OMAP_DSS_DISPLAY_DISABLED) - goto end; - - if (dssdev->state == OMAP_DSS_DISPLAY_SUSPENDED) { - /* suspended is the same as disabled with venc */ - dssdev->state = OMAP_DSS_DISPLAY_DISABLED; - goto end; - } - - venc_power_off(dssdev); - - dssdev->state = OMAP_DSS_DISPLAY_DISABLED; -end: - mutex_unlock(&venc.venc_lock); -} - -static int venc_display_suspend(struct omap_dss_device *dssdev) -{ - int r = 0; - - DSSDBG("venc_display_suspend\n"); - - mutex_lock(&venc.venc_lock); - - if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE) { - r = -EINVAL; - goto err; - } - - venc_power_off(dssdev); - - dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED; -err: - mutex_unlock(&venc.venc_lock); - - return r; -} - -static int venc_display_resume(struct omap_dss_device *dssdev) -{ - int r = 0; - - DSSDBG("venc_display_resume\n"); - - mutex_lock(&venc.venc_lock); - - if (dssdev->state != OMAP_DSS_DISPLAY_SUSPENDED) { - r = -EINVAL; - goto err; - } - - venc_power_on(dssdev); - - dssdev->state = OMAP_DSS_DISPLAY_ACTIVE; -err: - mutex_unlock(&venc.venc_lock); - - return r; -} - static void venc_get_timings(struct omap_dss_device *dssdev, struct omap_video_timings *timings) { @@ -684,8 +637,8 @@ static void venc_set_timings(struct omap_dss_device *dssdev, dssdev->panel.timings = *timings; if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) { /* turn the venc off and on to get new timings to use */ - venc_disable_display(dssdev); - venc_enable_display(dssdev); + venc_panel_disable(dssdev); + venc_panel_enable(dssdev); } } @@ -738,10 +691,6 @@ int venc_init_display(struct omap_dss_device *dssdev) { DSSDBG("init_display\n"); - dssdev->enable = venc_enable_display; - dssdev->disable = venc_disable_display; - dssdev->suspend = venc_display_suspend; - dssdev->resume = venc_display_resume; dssdev->get_timings = venc_get_timings; dssdev->set_timings = venc_set_timings; dssdev->check_timings = venc_check_timings; diff --git a/drivers/video/omap2/omapfb/omapfb-main.c b/drivers/video/omap2/omapfb/omapfb-main.c index 3dbbddc2d51e..b327ee0e60d5 100644 --- a/drivers/video/omap2/omapfb/omapfb-main.c +++ b/drivers/video/omap2/omapfb/omapfb-main.c @@ -1223,8 +1223,8 @@ static int omapfb_blank(int blank, struct fb_info *fbi) if (display->state != OMAP_DSS_DISPLAY_SUSPENDED) goto exit; - if (display->resume) - r = display->resume(display); + if (display->driver->resume) + r = display->driver->resume(display); if (r == 0 && display->driver->get_update_mode && display->driver->get_update_mode(display) == @@ -1242,8 +1242,8 @@ static int omapfb_blank(int blank, struct fb_info *fbi) if (display->state != OMAP_DSS_DISPLAY_ACTIVE) goto exit; - if (display->suspend) - r = display->suspend(display); + if (display->driver->suspend) + r = display->driver->suspend(display); break; @@ -1831,7 +1831,7 @@ static void omapfb_free_resources(struct omapfb2_device *fbdev) for (i = 0; i < fbdev->num_displays; i++) { if (fbdev->displays[i]->state != OMAP_DSS_DISPLAY_DISABLED) - fbdev->displays[i]->disable(fbdev->displays[i]); + fbdev->displays[i]->driver->disable(fbdev->displays[i]); omap_dss_put_device(fbdev->displays[i]); } @@ -2197,7 +2197,7 @@ static int omapfb_probe(struct platform_device *pdev) #ifndef CONFIG_FB_OMAP2_FORCE_AUTO_UPDATE u16 w, h; #endif - r = def_display->enable(def_display); + r = def_display->driver->enable(def_display); if (r) { dev_warn(fbdev->dev, "Failed to enable display '%s'\n", def_display->name); -- cgit v1.2.2 From 3651131268d7eae63efdffe6fa4a361abd44d747 Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Tue, 19 Jan 2010 15:53:16 +0200 Subject: OMAP: DSS2: move set/get_wss() Move set/get_wss() from omap_dss_device to omap_dss_driver. This is part of a larger patch-set, which moves the control from omapdss driver to the display driver. Signed-off-by: Tomi Valkeinen --- drivers/video/omap2/dss/display.c | 8 ++--- drivers/video/omap2/dss/venc.c | 67 ++++++++++++++++++++------------------- 2 files changed, 38 insertions(+), 37 deletions(-) (limited to 'drivers') diff --git a/drivers/video/omap2/dss/display.c b/drivers/video/omap2/dss/display.c index 29ec5a4a46bc..351c8abae0b2 100644 --- a/drivers/video/omap2/dss/display.c +++ b/drivers/video/omap2/dss/display.c @@ -247,10 +247,10 @@ static ssize_t display_wss_show(struct device *dev, struct omap_dss_device *dssdev = to_dss_device(dev); unsigned int wss; - if (!dssdev->get_wss) + if (!dssdev->driver->get_wss) return -ENOENT; - wss = dssdev->get_wss(dssdev); + wss = dssdev->driver->get_wss(dssdev); return snprintf(buf, PAGE_SIZE, "0x%05x\n", wss); } @@ -262,7 +262,7 @@ static ssize_t display_wss_store(struct device *dev, unsigned long wss; int r; - if (!dssdev->get_wss || !dssdev->set_wss) + if (!dssdev->driver->get_wss || !dssdev->driver->set_wss) return -ENOENT; if (strict_strtoul(buf, 0, &wss)) @@ -271,7 +271,7 @@ static ssize_t display_wss_store(struct device *dev, if (wss > 0xfffff) return -EINVAL; - r = dssdev->set_wss(dssdev, wss); + r = dssdev->driver->set_wss(dssdev, wss); if (r) return r; diff --git a/drivers/video/omap2/dss/venc.c b/drivers/video/omap2/dss/venc.c index a0ab52c841ee..5c6e98bbb663 100644 --- a/drivers/video/omap2/dss/venc.c +++ b/drivers/video/omap2/dss/venc.c @@ -557,6 +557,37 @@ static int venc_set_update_mode(struct omap_dss_device *dssdev, return 0; } +static u32 venc_get_wss(struct omap_dss_device *dssdev) +{ + /* Invert due to VENC_L21_WC_CTL:INV=1 */ + return (venc.wss_data >> 8) ^ 0xfffff; +} + +static int venc_set_wss(struct omap_dss_device *dssdev, u32 wss) +{ + const struct venc_config *config; + + DSSDBG("venc_set_wss\n"); + + mutex_lock(&venc.venc_lock); + + config = venc_timings_to_config(&dssdev->panel.timings); + + /* Invert due to VENC_L21_WC_CTL:INV=1 */ + venc.wss_data = (wss ^ 0xfffff) << 8; + + venc_enable_clocks(1); + + venc_write_reg(VENC_BSTAMP_WSS_DATA, config->bstamp_wss_data | + venc.wss_data); + + venc_enable_clocks(0); + + mutex_unlock(&venc.venc_lock); + + return 0; +} + static struct omap_dss_driver venc_driver = { .probe = venc_panel_probe, .remove = venc_panel_remove, @@ -572,6 +603,9 @@ static struct omap_dss_driver venc_driver = { .set_update_mode = venc_set_update_mode, .get_update_mode = venc_get_update_mode, + .get_wss = venc_get_wss, + .set_wss = venc_set_wss, + .driver = { .name = "venc", .owner = THIS_MODULE, @@ -656,37 +690,6 @@ static int venc_check_timings(struct omap_dss_device *dssdev, return -EINVAL; } -static u32 venc_get_wss(struct omap_dss_device *dssdev) -{ - /* Invert due to VENC_L21_WC_CTL:INV=1 */ - return (venc.wss_data >> 8) ^ 0xfffff; -} - -static int venc_set_wss(struct omap_dss_device *dssdev, u32 wss) -{ - const struct venc_config *config; - - DSSDBG("venc_set_wss\n"); - - mutex_lock(&venc.venc_lock); - - config = venc_timings_to_config(&dssdev->panel.timings); - - /* Invert due to VENC_L21_WC_CTL:INV=1 */ - venc.wss_data = (wss ^ 0xfffff) << 8; - - venc_enable_clocks(1); - - venc_write_reg(VENC_BSTAMP_WSS_DATA, config->bstamp_wss_data | - venc.wss_data); - - venc_enable_clocks(0); - - mutex_unlock(&venc.venc_lock); - - return 0; -} - int venc_init_display(struct omap_dss_device *dssdev) { DSSDBG("init_display\n"); @@ -694,8 +697,6 @@ int venc_init_display(struct omap_dss_device *dssdev) dssdev->get_timings = venc_get_timings; dssdev->set_timings = venc_set_timings; dssdev->check_timings = venc_check_timings; - dssdev->get_wss = venc_get_wss; - dssdev->set_wss = venc_set_wss; return 0; } -- cgit v1.2.2 From 69b2048f44ead2d278e25d12adf0494b469ffb1c Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Wed, 20 Jan 2010 12:11:25 +0200 Subject: OMAP: DSS2: move timing functions Move check/set/get_timings() from omap_dss_device to omap_dss_driver. This is part of a larger patch-set, which moves the control from omapdss driver to the display driver. Signed-off-by: Tomi Valkeinen --- drivers/video/omap2/displays/panel-taal.c | 4 +- drivers/video/omap2/dss/display.c | 10 ++-- drivers/video/omap2/dss/dpi.c | 16 ++---- drivers/video/omap2/dss/sdi.c | 8 --- drivers/video/omap2/dss/venc.c | 82 +++++++++++++++---------------- drivers/video/omap2/omapfb/omapfb-main.c | 10 ++-- 6 files changed, 57 insertions(+), 73 deletions(-) (limited to 'drivers') diff --git a/drivers/video/omap2/displays/panel-taal.c b/drivers/video/omap2/displays/panel-taal.c index 484a61844763..a722733106b1 100644 --- a/drivers/video/omap2/displays/panel-taal.c +++ b/drivers/video/omap2/displays/panel-taal.c @@ -516,8 +516,6 @@ static int taal_probe(struct omap_dss_device *dssdev) dev_set_drvdata(&dssdev->dev, td); - dssdev->get_timings = taal_get_timings; - /* if no platform set_backlight() defined, presume DSI backlight * control */ if (!dssdev->set_backlight) @@ -1118,6 +1116,8 @@ static struct omap_dss_driver taal_driver = { .run_test = taal_run_test, .memory_read = taal_memory_read, + .get_timings = taal_get_timings, + .driver = { .name = "taal", .owner = THIS_MODULE, diff --git a/drivers/video/omap2/dss/display.c b/drivers/video/omap2/dss/display.c index 351c8abae0b2..6a74ea116d29 100644 --- a/drivers/video/omap2/dss/display.c +++ b/drivers/video/omap2/dss/display.c @@ -135,10 +135,10 @@ static ssize_t display_timings_show(struct device *dev, struct omap_dss_device *dssdev = to_dss_device(dev); struct omap_video_timings t; - if (!dssdev->get_timings) + if (!dssdev->driver->get_timings) return -ENOENT; - dssdev->get_timings(dssdev, &t); + dssdev->driver->get_timings(dssdev, &t); return snprintf(buf, PAGE_SIZE, "%u,%u/%u/%u/%u,%u/%u/%u/%u\n", t.pixel_clock, @@ -153,7 +153,7 @@ static ssize_t display_timings_store(struct device *dev, struct omap_video_timings t; int r, found; - if (!dssdev->set_timings || !dssdev->check_timings) + if (!dssdev->driver->set_timings || !dssdev->driver->check_timings) return -ENOENT; found = 0; @@ -172,11 +172,11 @@ static ssize_t display_timings_store(struct device *dev, &t.y_res, &t.vfp, &t.vbp, &t.vsw) != 9) return -EINVAL; - r = dssdev->check_timings(dssdev, &t); + r = dssdev->driver->check_timings(dssdev, &t); if (r) return r; - dssdev->set_timings(dssdev, &t); + dssdev->driver->set_timings(dssdev, &t); return size; } diff --git a/drivers/video/omap2/dss/dpi.c b/drivers/video/omap2/dss/dpi.c index 1eef8b72dbb9..960e977a8bf0 100644 --- a/drivers/video/omap2/dss/dpi.c +++ b/drivers/video/omap2/dss/dpi.c @@ -227,7 +227,7 @@ void omapdss_dpi_display_disable(struct omap_dss_device *dssdev) } EXPORT_SYMBOL(omapdss_dpi_display_disable); -static void dpi_set_timings(struct omap_dss_device *dssdev, +void dpi_set_timings(struct omap_dss_device *dssdev, struct omap_video_timings *timings) { DSSDBG("dpi_set_timings\n"); @@ -237,8 +237,9 @@ static void dpi_set_timings(struct omap_dss_device *dssdev, dispc_go(OMAP_DSS_CHANNEL_LCD); } } +EXPORT_SYMBOL(dpi_set_timings); -static int dpi_check_timings(struct omap_dss_device *dssdev, +int dpi_check_timings(struct omap_dss_device *dssdev, struct omap_video_timings *timings) { bool is_tft; @@ -292,21 +293,12 @@ static int dpi_check_timings(struct omap_dss_device *dssdev, return 0; } - -static void dpi_get_timings(struct omap_dss_device *dssdev, - struct omap_video_timings *timings) -{ - *timings = dssdev->panel.timings; -} +EXPORT_SYMBOL(dpi_check_timings); int dpi_init_display(struct omap_dss_device *dssdev) { DSSDBG("init_display\n"); - dssdev->set_timings = dpi_set_timings; - dssdev->check_timings = dpi_check_timings; - dssdev->get_timings = dpi_get_timings; - return 0; } diff --git a/drivers/video/omap2/dss/sdi.c b/drivers/video/omap2/dss/sdi.c index 929ceb3ddd9d..12eb4042dd82 100644 --- a/drivers/video/omap2/dss/sdi.c +++ b/drivers/video/omap2/dss/sdi.c @@ -150,18 +150,10 @@ void omapdss_sdi_display_disable(struct omap_dss_device *dssdev) } EXPORT_SYMBOL(omapdss_sdi_display_disable); -static void sdi_get_timings(struct omap_dss_device *dssdev, - struct omap_video_timings *timings) -{ - *timings = dssdev->panel.timings; -} - int sdi_init_display(struct omap_dss_device *dssdev) { DSSDBG("SDI init\n"); - dssdev->get_timings = sdi_get_timings; - return 0; } diff --git a/drivers/video/omap2/dss/venc.c b/drivers/video/omap2/dss/venc.c index 5c6e98bbb663..f0ba5732d84a 100644 --- a/drivers/video/omap2/dss/venc.c +++ b/drivers/video/omap2/dss/venc.c @@ -557,6 +557,43 @@ static int venc_set_update_mode(struct omap_dss_device *dssdev, return 0; } +static void venc_get_timings(struct omap_dss_device *dssdev, + struct omap_video_timings *timings) +{ + *timings = dssdev->panel.timings; +} + +static void venc_set_timings(struct omap_dss_device *dssdev, + struct omap_video_timings *timings) +{ + DSSDBG("venc_set_timings\n"); + + /* Reset WSS data when the TV standard changes. */ + if (memcmp(&dssdev->panel.timings, timings, sizeof(*timings))) + venc.wss_data = 0; + + dssdev->panel.timings = *timings; + if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) { + /* turn the venc off and on to get new timings to use */ + venc_panel_disable(dssdev); + venc_panel_enable(dssdev); + } +} + +static int venc_check_timings(struct omap_dss_device *dssdev, + struct omap_video_timings *timings) +{ + DSSDBG("venc_check_timings\n"); + + if (memcmp(&omap_dss_pal_timings, timings, sizeof(*timings)) == 0) + return 0; + + if (memcmp(&omap_dss_ntsc_timings, timings, sizeof(*timings)) == 0) + return 0; + + return -EINVAL; +} + static u32 venc_get_wss(struct omap_dss_device *dssdev) { /* Invert due to VENC_L21_WC_CTL:INV=1 */ @@ -603,6 +640,10 @@ static struct omap_dss_driver venc_driver = { .set_update_mode = venc_set_update_mode, .get_update_mode = venc_get_update_mode, + .get_timings = venc_get_timings, + .set_timings = venc_set_timings, + .check_timings = venc_check_timings, + .get_wss = venc_get_wss, .set_wss = venc_set_wss, @@ -653,51 +694,10 @@ void venc_exit(void) iounmap(venc.base); } -static void venc_get_timings(struct omap_dss_device *dssdev, - struct omap_video_timings *timings) -{ - *timings = dssdev->panel.timings; -} - -static void venc_set_timings(struct omap_dss_device *dssdev, - struct omap_video_timings *timings) -{ - DSSDBG("venc_set_timings\n"); - - /* Reset WSS data when the TV standard changes. */ - if (memcmp(&dssdev->panel.timings, timings, sizeof(*timings))) - venc.wss_data = 0; - - dssdev->panel.timings = *timings; - if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) { - /* turn the venc off and on to get new timings to use */ - venc_panel_disable(dssdev); - venc_panel_enable(dssdev); - } -} - -static int venc_check_timings(struct omap_dss_device *dssdev, - struct omap_video_timings *timings) -{ - DSSDBG("venc_check_timings\n"); - - if (memcmp(&omap_dss_pal_timings, timings, sizeof(*timings)) == 0) - return 0; - - if (memcmp(&omap_dss_ntsc_timings, timings, sizeof(*timings)) == 0) - return 0; - - return -EINVAL; -} - int venc_init_display(struct omap_dss_device *dssdev) { DSSDBG("init_display\n"); - dssdev->get_timings = venc_get_timings; - dssdev->set_timings = venc_set_timings; - dssdev->check_timings = venc_check_timings; - return 0; } diff --git a/drivers/video/omap2/omapfb/omapfb-main.c b/drivers/video/omap2/omapfb/omapfb-main.c index b327ee0e60d5..8aed12a1ce2f 100644 --- a/drivers/video/omap2/omapfb/omapfb-main.c +++ b/drivers/video/omap2/omapfb/omapfb-main.c @@ -705,9 +705,9 @@ int check_fb_var(struct fb_info *fbi, struct fb_var_screeninfo *var) var->width = -1; var->grayscale = 0; - if (display && display->get_timings) { + if (display && display->driver->get_timings) { struct omap_video_timings timings; - display->get_timings(display, &timings); + display->driver->get_timings(display, &timings); /* pixclock in ps, the rest in pixclock */ var->pixclock = timings.pixel_clock != 0 ? @@ -2029,14 +2029,14 @@ static int omapfb_set_def_mode(struct omapfb2_device *fbdev, fbdev->bpp_overrides[fbdev->num_bpp_overrides].bpp = bpp; ++fbdev->num_bpp_overrides; - if (!display->check_timings || !display->set_timings) + if (!display->driver->check_timings || !display->driver->set_timings) return -EINVAL; - r = display->check_timings(display, &timings); + r = display->driver->check_timings(display, &timings); if (r) return r; - display->set_timings(display, &timings); + display->driver->set_timings(display, &timings); return 0; } -- cgit v1.2.2 From 942a91a6e04e996c32252bc6c2177f74089d7a1d Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Wed, 10 Feb 2010 17:27:39 +0200 Subject: OMAP: DSS2: DSI: remove external TE support With the reworked model, DSI driver doesn't need to know anything about external TE lines. Thus we can remove ext_te support, and only leave the DSI TE trigger support. Signed-off-by: Tomi Valkeinen --- drivers/video/omap2/dss/dsi.c | 20 ++++---------------- 1 file changed, 4 insertions(+), 16 deletions(-) (limited to 'drivers') diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c index 41cdefbaf7f3..73bdb04e6814 100644 --- a/drivers/video/omap2/dss/dsi.c +++ b/drivers/video/omap2/dss/dsi.c @@ -237,7 +237,6 @@ static struct struct dsi_update_region update_region; bool te_enabled; - bool use_ext_te; struct work_struct framedone_work; void (*framedone_callback)(int, void *); @@ -2723,15 +2722,12 @@ static void dsi_update_screen_dispc(struct omap_dss_device *dssdev, unsigned packet_payload; unsigned packet_len; u32 l; - bool use_te_trigger; const unsigned channel = dsi.update_channel; /* line buffer is 1024 x 24bits */ /* XXX: for some reason using full buffer size causes considerable TX * slowdown with update sizes that fill the whole buffer */ const unsigned line_buf_size = 1023 * 3; - use_te_trigger = dsi.te_enabled && !dsi.use_ext_te; - DSSDBG("dsi_update_screen_dispc(%d,%d %dx%d)\n", x, y, w, h); @@ -2760,7 +2756,7 @@ static void dsi_update_screen_dispc(struct omap_dss_device *dssdev, dsi_vc_write_long_header(channel, DSI_DT_DCS_LONG_WRITE, packet_len, 0); - if (use_te_trigger) + if (dsi.te_enabled) l = FLD_MOD(l, 1, 30, 30); /* TE_EN */ else l = FLD_MOD(l, 1, 31, 31); /* TE_START */ @@ -2781,7 +2777,7 @@ static void dsi_update_screen_dispc(struct omap_dss_device *dssdev, dss_start_update(dssdev); - if (use_te_trigger) { + if (dsi.te_enabled) { /* disable LP_RX_TO, so that we can receive TE. Time to wait * for TE is longer than the timer allows */ REG_FLD_MOD(DSI_TIMING2, 0, 15, 15); /* LP_RX_TO */ @@ -2805,16 +2801,13 @@ static void dsi_framedone_timeout_work_callback(struct work_struct *work) { int r; const int channel = dsi.update_channel; - bool use_te_trigger; DSSERR("Framedone not received for 250ms!\n"); /* SIDLEMODE back to smart-idle */ dispc_enable_sidle(); - use_te_trigger = dsi.te_enabled && !dsi.use_ext_te; - - if (use_te_trigger) { + if (dsi.te_enabled) { /* enable LP_RX_TO again after the TE */ REG_FLD_MOD(DSI_TIMING2, 1, 15, 15); /* LP_RX_TO */ } @@ -2858,13 +2851,10 @@ static void dsi_handle_framedone(void) { int r; const int channel = dsi.update_channel; - bool use_te_trigger; - - use_te_trigger = dsi.te_enabled && !dsi.use_ext_te; DSSDBG("FRAMEDONE\n"); - if (use_te_trigger) { + if (dsi.te_enabled) { /* enable LP_RX_TO again after the TE */ REG_FLD_MOD(DSI_TIMING2, 1, 15, 15); /* LP_RX_TO */ } @@ -3175,8 +3165,6 @@ int omapdss_dsi_display_enable(struct omap_dss_device *dssdev) if (r) goto err2; - dsi.use_ext_te = dssdev->phy.dsi.ext_te; - mutex_unlock(&dsi.lock); return 0; -- cgit v1.2.2 From ddbfeb396eb085e17f5aa830a151d546f16cb868 Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Wed, 17 Feb 2010 15:01:50 +0200 Subject: OMAP: DSS2: OMAPFB: Remove FB_OMAP2_FORCE_AUTO_UPDATE Remove the option for forcing auto-update. Auto-update for manual update displays is no more a DSS feature, so if a particular display devices does have auto-update mode, it should be in display's custom settings. Signed-off-by: Tomi Valkeinen --- drivers/video/omap2/omapfb/Kconfig | 9 --------- drivers/video/omap2/omapfb/omapfb-main.c | 17 +++-------------- 2 files changed, 3 insertions(+), 23 deletions(-) (limited to 'drivers') diff --git a/drivers/video/omap2/omapfb/Kconfig b/drivers/video/omap2/omapfb/Kconfig index 5effa1d4d0e6..43496d6c377f 100644 --- a/drivers/video/omap2/omapfb/Kconfig +++ b/drivers/video/omap2/omapfb/Kconfig @@ -18,15 +18,6 @@ config FB_OMAP2_DEBUG_SUPPORT Support for debug output. You have to enable the actual printing with 'debug' module parameter. -config FB_OMAP2_FORCE_AUTO_UPDATE - bool "Force main display to automatic update mode" - depends on FB_OMAP2 - help - Forces main display to automatic update mode (if possible), - and also enables tearsync (if possible). By default - displays that support manual update are started in manual - update mode. - config FB_OMAP2_NUM_FBS int "Number of framebuffers" range 1 10 diff --git a/drivers/video/omap2/omapfb/omapfb-main.c b/drivers/video/omap2/omapfb/omapfb-main.c index 8aed12a1ce2f..e3a1730df5fd 100644 --- a/drivers/video/omap2/omapfb/omapfb-main.c +++ b/drivers/video/omap2/omapfb/omapfb-main.c @@ -2194,9 +2194,7 @@ static int omapfb_probe(struct platform_device *pdev) if (def_display) { struct omap_dss_driver *dssdrv = def_display->driver; -#ifndef CONFIG_FB_OMAP2_FORCE_AUTO_UPDATE - u16 w, h; -#endif + r = def_display->driver->enable(def_display); if (r) { dev_warn(fbdev->dev, "Failed to enable display '%s'\n", @@ -2204,25 +2202,16 @@ static int omapfb_probe(struct platform_device *pdev) goto cleanup; } - /* set the update mode */ if (def_display->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE) { -#ifdef CONFIG_FB_OMAP2_FORCE_AUTO_UPDATE + u16 w, h; if (dssdrv->enable_te) dssdrv->enable_te(def_display, 1); - if (dssdrv->set_update_mode) - dssdrv->set_update_mode(def_display, - OMAP_DSS_UPDATE_AUTO); -#else /* MANUAL_UPDATE */ - if (dssdrv->enable_te) - dssdrv->enable_te(def_display, 0); if (dssdrv->set_update_mode) dssdrv->set_update_mode(def_display, OMAP_DSS_UPDATE_MANUAL); - dssdrv->get_resolution(def_display, - &w, &h); + dssdrv->get_resolution(def_display, &w, &h); def_display->driver->update(def_display, 0, 0, w, h); -#endif } else { if (dssdrv->set_update_mode) dssdrv->set_update_mode(def_display, -- cgit v1.2.2 From d62abe563fa4718e7f85f3e871655434db92366d Mon Sep 17 00:00:00 2001 From: Misael Lopez Cruz Date: Tue, 23 Feb 2010 18:10:19 -0600 Subject: OMAP4: PMIC: Add support for twl6030 codec In order to have TWL6030 CODEC driver as a platform driver, codec data should be passed through twl_platform_data structure. For twl6030 audio codec, the following data may be passed: - audpwron_gpio: gpio line used to power-up/down the codec. A low-to-high transition powers codec up. Setting audpwron_gpio to a negative value means that codec will use manual power sequence instead of automatic sequence - naudint_irq: irq line for audio interrupt. twl6030 drives NAUDINT line to low when an interrupt (codec ready, plug insertion/removal, etc) is detected However, codec driver can operate if any or none of them are passed. Signed-off-by: Misael Lopez Cruz Signed-off-by: Margarita Olaya Cabrera Signed-off-by: Jorge Eduardo Candelaria Acked-by: Samuel Ortiz Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- drivers/mfd/twl-core.c | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/mfd/twl-core.c b/drivers/mfd/twl-core.c index 2a7606534196..19a930d06241 100644 --- a/drivers/mfd/twl-core.c +++ b/drivers/mfd/twl-core.c @@ -115,7 +115,8 @@ #define twl_has_watchdog() false #endif -#if defined(CONFIG_TWL4030_CODEC) || defined(CONFIG_TWL4030_CODEC_MODULE) +#if defined(CONFIG_TWL4030_CODEC) || defined(CONFIG_TWL4030_CODEC_MODULE) ||\ + defined(CONFIG_SND_SOC_TWL6030) || defined(CONFIG_SND_SOC_TWL6030_MODULE) #define twl_has_codec() true #else #define twl_has_codec() false @@ -711,8 +712,19 @@ add_children(struct twl4030_platform_data *pdata, unsigned long features) return PTR_ERR(child); } - if (twl_has_codec() && pdata->codec) { - child = add_child(1, "twl4030_codec", + if (twl_has_codec() && pdata->codec && twl_class_is_4030()) { + sub_chip_id = twl_map[TWL_MODULE_AUDIO_VOICE].sid; + child = add_child(sub_chip_id, "twl4030_codec", + pdata->codec, sizeof(*pdata->codec), + false, 0, 0); + if (IS_ERR(child)) + return PTR_ERR(child); + } + + /* Phoenix*/ + if (twl_has_codec() && pdata->codec && twl_class_is_6030()) { + sub_chip_id = twl_map[TWL_MODULE_AUDIO_VOICE].sid; + child = add_child(sub_chip_id, "twl6030_codec", pdata->codec, sizeof(*pdata->codec), false, 0, 0); if (IS_ERR(child)) -- cgit v1.2.2 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') 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.2 From 53055aae2048214cbec1f5f7f8846f9dff12b2bc Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Thu, 25 Feb 2010 11:38:13 +0200 Subject: OMAP: DSS2: DSI: add dsi_vc_dcs_read_2() helper Add dsi_vc_dcs_read_2() helper function to read two bytes from the DSI peripheral. Signed-off-by: Tomi Valkeinen --- drivers/video/omap2/dss/dsi.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'drivers') diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c index 73bdb04e6814..a9820206ca1e 100644 --- a/drivers/video/omap2/dss/dsi.c +++ b/drivers/video/omap2/dss/dsi.c @@ -2212,6 +2212,22 @@ int dsi_vc_dcs_read_1(int channel, u8 dcs_cmd, u8 *data) } EXPORT_SYMBOL(dsi_vc_dcs_read_1); +int dsi_vc_dcs_read_2(int channel, u8 dcs_cmd, u16 *data) +{ + int r; + + r = dsi_vc_dcs_read(channel, dcs_cmd, (u8 *)data, 2); + + if (r < 0) + return r; + + if (r != 2) + return -EIO; + + return 0; +} +EXPORT_SYMBOL(dsi_vc_dcs_read_2); + int dsi_vc_set_max_rx_packet_size(int channel, u16 len) { int r; -- cgit v1.2.2 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 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) (limited to 'drivers') 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); + } + } } /* -- cgit v1.2.2 From 606847540079bd3e710f132724145c5785396dcb Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Tue, 9 Feb 2010 14:14:07 +0200 Subject: OMAP: DSS2: TPO-TD03MTEA1: fix function names Copy/paste had resulted in wrong function names in TPO TD043MTEA1 panel driver. Signed-off-by: Tomi Valkeinen --- drivers/video/omap2/displays/panel-tpo-td043mtea1.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/video/omap2/displays/panel-tpo-td043mtea1.c b/drivers/video/omap2/displays/panel-tpo-td043mtea1.c index c6e4a7e9f532..d578feee3550 100644 --- a/drivers/video/omap2/displays/panel-tpo-td043mtea1.c +++ b/drivers/video/omap2/displays/panel-tpo-td043mtea1.c @@ -262,7 +262,7 @@ static const struct omap_video_timings tpo_td043_timings = { .vbp = 34, }; -static int generic_panel_power_on(struct omap_dss_device *dssdev) +static int tpo_td043_power_on(struct omap_dss_device *dssdev) { struct tpo_td043_device *tpo_td043 = dev_get_drvdata(&dssdev->dev); int nreset_gpio = dssdev->reset_gpio; @@ -302,7 +302,7 @@ err0: return r; } -static void generic_panel_power_off(struct omap_dss_device *dssdev) +static void tpo_td043_power_off(struct omap_dss_device *dssdev) { struct tpo_td043_device *tpo_td043 = dev_get_drvdata(&dssdev->dev); int nreset_gpio = dssdev->reset_gpio; @@ -332,7 +332,7 @@ static int tpo_td043_enable(struct omap_dss_device *dssdev) dev_dbg(&dssdev->dev, "enable\n"); - ret = generic_panel_power_on(dssdev); + ret = tpo_td043_power_on(dssdev); if (ret) return ret; @@ -345,14 +345,14 @@ static void tpo_td043_disable(struct omap_dss_device *dssdev) { dev_dbg(&dssdev->dev, "disable\n"); - generic_panel_power_off(dssdev); + tpo_td043_power_off(dssdev); dssdev->state = OMAP_DSS_DISPLAY_DISABLED; } static int tpo_td043_suspend(struct omap_dss_device *dssdev) { - generic_panel_power_off(dssdev); + tpo_td043_power_off(dssdev); dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED; return 0; } @@ -361,7 +361,7 @@ static int tpo_td043_resume(struct omap_dss_device *dssdev) { int r = 0; - r = generic_panel_power_on(dssdev); + r = tpo_td043_power_on(dssdev); if (r) return r; -- cgit v1.2.2 From 275143e9b237dd7e0b6d01660fd9b8acd9922fa7 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Fri, 26 Feb 2010 04:37:09 -0800 Subject: sunxvr500: Additional PCI id for sunxvr500 driver Intergraph bought 3D Labs and some XVR-500 chips have Intergraph's vendor id. Reported-by: Jurij Smakov Signed-off-by: Ben Hutchings Cc: stable@kernel.org Signed-off-by: David S. Miller --- drivers/video/sunxvr500.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/video/sunxvr500.c b/drivers/video/sunxvr500.c index 18b950706cad..4cd50497264d 100644 --- a/drivers/video/sunxvr500.c +++ b/drivers/video/sunxvr500.c @@ -400,6 +400,7 @@ static void __devexit e3d_pci_unregister(struct pci_dev *pdev) static struct pci_device_id e3d_pci_table[] = { { PCI_DEVICE(PCI_VENDOR_ID_3DLABS, 0x7a0), }, + { PCI_DEVICE(0x1091, 0x7a0), }, { PCI_DEVICE(PCI_VENDOR_ID_3DLABS, 0x7a2), }, { .vendor = PCI_VENDOR_ID_3DLABS, .device = PCI_ANY_ID, -- cgit v1.2.2 From eb28d31bc97e6374d81f404da309401ffaed467b Mon Sep 17 00:00:00 2001 From: "Martin K. Petersen" Date: Fri, 26 Feb 2010 00:20:37 -0500 Subject: block: Add BLK_ prefix to definitions Add a BLK_ prefix to block layer constants. Signed-off-by: Martin K. Petersen Signed-off-by: Jens Axboe --- drivers/block/ps3vram.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/block/ps3vram.c b/drivers/block/ps3vram.c index 1fb6c3135fc8..a7ecb43b16ab 100644 --- a/drivers/block/ps3vram.c +++ b/drivers/block/ps3vram.c @@ -753,8 +753,8 @@ static int __devinit ps3vram_probe(struct ps3_system_bus_device *dev) blk_queue_make_request(queue, ps3vram_make_request); blk_queue_max_phys_segments(queue, MAX_PHYS_SEGMENTS); blk_queue_max_hw_segments(queue, MAX_HW_SEGMENTS); - blk_queue_max_segment_size(queue, MAX_SEGMENT_SIZE); - blk_queue_max_sectors(queue, SAFE_MAX_SECTORS); + blk_queue_max_segment_size(queue, BLK_MAX_SEGMENT_SIZE); + blk_queue_max_sectors(queue, BLK_SAFE_MAX_SECTORS); gendisk = alloc_disk(1); if (!gendisk) { -- cgit v1.2.2 From 086fa5ff0854c676ec333760f4c0154b3b242616 Mon Sep 17 00:00:00 2001 From: "Martin K. Petersen" Date: Fri, 26 Feb 2010 00:20:38 -0500 Subject: block: Rename blk_queue_max_sectors to blk_queue_max_hw_sectors The block layer calling convention is blk_queue_. blk_queue_max_sectors predates this practice, leading to some confusion. Rename the function to appropriately reflect that its intended use is to set max_hw_sectors. Also introduce a temporary wrapper for backwards compability. This can be removed after the merge window is closed. Signed-off-by: Martin K. Petersen Signed-off-by: Jens Axboe --- drivers/ata/libata-scsi.c | 2 +- drivers/block/DAC960.c | 2 +- drivers/block/brd.c | 2 +- drivers/block/cciss.c | 2 +- drivers/block/drbd/drbd_nl.c | 2 +- drivers/block/floppy.c | 2 +- drivers/block/hd.c | 2 +- drivers/block/mg_disk.c | 2 +- drivers/block/paride/pd.c | 2 +- drivers/block/pktcdvd.c | 4 ++-- drivers/block/ps3disk.c | 2 +- drivers/block/ps3vram.c | 2 +- drivers/block/sunvdc.c | 2 +- drivers/block/ub.c | 2 +- drivers/block/viodasd.c | 2 +- drivers/block/xd.c | 2 +- drivers/block/xen-blkfront.c | 2 +- drivers/cdrom/viocd.c | 2 +- drivers/firewire/sbp2.c | 2 +- drivers/ide/ide-disk.c | 2 +- drivers/ide/ide-floppy.c | 4 ++-- drivers/ide/ide-probe.c | 2 +- drivers/ieee1394/sbp2.c | 2 +- drivers/md/linear.c | 2 +- drivers/md/multipath.c | 4 ++-- drivers/md/raid0.c | 4 ++-- drivers/md/raid1.c | 4 ++-- drivers/md/raid10.c | 4 ++-- drivers/memstick/core/mspro_block.c | 2 +- drivers/message/i2o/i2o_block.c | 2 +- drivers/mmc/card/queue.c | 4 ++-- drivers/s390/block/dasd.c | 2 +- drivers/s390/char/tape_block.c | 2 +- drivers/scsi/ipr.c | 2 +- drivers/scsi/pmcraid.c | 2 +- drivers/scsi/scsi_lib.c | 2 +- drivers/scsi/scsi_scan.c | 2 +- drivers/usb/storage/scsiglue.c | 6 +++--- 38 files changed, 47 insertions(+), 47 deletions(-) (limited to 'drivers') diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index d096fbcbc771..bea003a24d27 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c @@ -1097,7 +1097,7 @@ static int ata_scsi_dev_config(struct scsi_device *sdev, dev->flags |= ATA_DFLAG_NO_UNLOAD; /* configure max sectors */ - blk_queue_max_sectors(sdev->request_queue, dev->max_sectors); + blk_queue_max_hw_sectors(sdev->request_queue, dev->max_sectors); if (dev->class == ATA_DEV_ATAPI) { struct request_queue *q = sdev->request_queue; diff --git a/drivers/block/DAC960.c b/drivers/block/DAC960.c index 7412b5d4f5f3..1c0cd35e1913 100644 --- a/drivers/block/DAC960.c +++ b/drivers/block/DAC960.c @@ -2535,7 +2535,7 @@ static bool DAC960_RegisterBlockDevice(DAC960_Controller_T *Controller) RequestQueue->queuedata = Controller; blk_queue_max_hw_segments(RequestQueue, Controller->DriverScatterGatherLimit); blk_queue_max_phys_segments(RequestQueue, Controller->DriverScatterGatherLimit); - blk_queue_max_sectors(RequestQueue, Controller->MaxBlocksPerCommand); + blk_queue_max_hw_sectors(RequestQueue, Controller->MaxBlocksPerCommand); disk->queue = RequestQueue; sprintf(disk->disk_name, "rd/c%dd%d", Controller->ControllerNumber, n); disk->major = MajorNumber; diff --git a/drivers/block/brd.c b/drivers/block/brd.c index 4f688434daf1..c6ddeacb77fd 100644 --- a/drivers/block/brd.c +++ b/drivers/block/brd.c @@ -434,7 +434,7 @@ static struct brd_device *brd_alloc(int i) goto out_free_dev; blk_queue_make_request(brd->brd_queue, brd_make_request); blk_queue_ordered(brd->brd_queue, QUEUE_ORDERED_TAG, NULL); - blk_queue_max_sectors(brd->brd_queue, 1024); + blk_queue_max_hw_sectors(brd->brd_queue, 1024); blk_queue_bounce_limit(brd->brd_queue, BLK_BOUNCE_ANY); disk = brd->brd_disk = alloc_disk(1 << part_shift); diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c index 86acdca5d0ce..030e52d72254 100644 --- a/drivers/block/cciss.c +++ b/drivers/block/cciss.c @@ -1802,7 +1802,7 @@ static int cciss_add_disk(ctlr_info_t *h, struct gendisk *disk, /* This is a limit in the driver and could be eliminated. */ blk_queue_max_phys_segments(disk->queue, h->maxsgentries); - blk_queue_max_sectors(disk->queue, h->cciss_max_sectors); + blk_queue_max_hw_sectors(disk->queue, h->cciss_max_sectors); blk_queue_softirq_done(disk->queue, cciss_softirq_done); diff --git a/drivers/block/drbd/drbd_nl.c b/drivers/block/drbd/drbd_nl.c index 1292e0620663..9b55e64196fc 100644 --- a/drivers/block/drbd/drbd_nl.c +++ b/drivers/block/drbd/drbd_nl.c @@ -709,7 +709,7 @@ void drbd_setup_queue_param(struct drbd_conf *mdev, unsigned int max_seg_s) __mu max_seg_s = min(queue_max_sectors(b) * queue_logical_block_size(b), max_seg_s); - blk_queue_max_sectors(q, max_seg_s >> 9); + blk_queue_max_hw_sectors(q, max_seg_s >> 9); blk_queue_max_phys_segments(q, max_segments ? max_segments : MAX_PHYS_SEGMENTS); blk_queue_max_hw_segments(q, max_segments ? max_segments : MAX_HW_SEGMENTS); blk_queue_max_segment_size(q, max_seg_s); diff --git a/drivers/block/floppy.c b/drivers/block/floppy.c index 3266b4f65daa..b9b117059b62 100644 --- a/drivers/block/floppy.c +++ b/drivers/block/floppy.c @@ -4234,7 +4234,7 @@ static int __init floppy_init(void) err = -ENOMEM; goto out_unreg_driver; } - blk_queue_max_sectors(floppy_queue, 64); + blk_queue_max_hw_sectors(floppy_queue, 64); blk_register_region(MKDEV(FLOPPY_MAJOR, 0), 256, THIS_MODULE, floppy_find, NULL, NULL); diff --git a/drivers/block/hd.c b/drivers/block/hd.c index d5cdce08ffd2..5116c65c07cb 100644 --- a/drivers/block/hd.c +++ b/drivers/block/hd.c @@ -719,7 +719,7 @@ static int __init hd_init(void) return -ENOMEM; } - blk_queue_max_sectors(hd_queue, 255); + blk_queue_max_hw_sectors(hd_queue, 255); init_timer(&device_timer); device_timer.function = hd_times_out; blk_queue_logical_block_size(hd_queue, 512); diff --git a/drivers/block/mg_disk.c b/drivers/block/mg_disk.c index 02b2583df7fc..5416c9a606e4 100644 --- a/drivers/block/mg_disk.c +++ b/drivers/block/mg_disk.c @@ -980,7 +980,7 @@ static int mg_probe(struct platform_device *plat_dev) __func__, __LINE__); goto probe_err_6; } - blk_queue_max_sectors(host->breq, MG_MAX_SECTS); + blk_queue_max_hw_sectors(host->breq, MG_MAX_SECTS); blk_queue_logical_block_size(host->breq, MG_SECTOR_SIZE); init_timer(&host->timer); diff --git a/drivers/block/paride/pd.c b/drivers/block/paride/pd.c index 569e39e8f114..e712cd51af15 100644 --- a/drivers/block/paride/pd.c +++ b/drivers/block/paride/pd.c @@ -906,7 +906,7 @@ static int __init pd_init(void) if (!pd_queue) goto out1; - blk_queue_max_sectors(pd_queue, cluster); + blk_queue_max_hw_sectors(pd_queue, cluster); if (register_blkdev(major, name)) goto out2; diff --git a/drivers/block/pktcdvd.c b/drivers/block/pktcdvd.c index 7cd2973ebb7b..6e1daa24da2f 100644 --- a/drivers/block/pktcdvd.c +++ b/drivers/block/pktcdvd.c @@ -2312,7 +2312,7 @@ static int pkt_open_dev(struct pktcdvd_device *pd, fmode_t write) * even if the size is a multiple of the packet size. */ spin_lock_irq(q->queue_lock); - blk_queue_max_sectors(q, pd->settings.size); + blk_queue_max_hw_sectors(q, pd->settings.size); spin_unlock_irq(q->queue_lock); set_bit(PACKET_WRITABLE, &pd->flags); } else { @@ -2613,7 +2613,7 @@ static void pkt_init_queue(struct pktcdvd_device *pd) blk_queue_make_request(q, pkt_make_request); blk_queue_logical_block_size(q, CD_FRAMESIZE); - blk_queue_max_sectors(q, PACKET_MAX_SECTORS); + blk_queue_max_hw_sectors(q, PACKET_MAX_SECTORS); blk_queue_merge_bvec(q, pkt_merge_bvec); q->queuedata = pd; } diff --git a/drivers/block/ps3disk.c b/drivers/block/ps3disk.c index 03a130dca8ab..9cd1a4a542b8 100644 --- a/drivers/block/ps3disk.c +++ b/drivers/block/ps3disk.c @@ -474,7 +474,7 @@ static int __devinit ps3disk_probe(struct ps3_system_bus_device *_dev) blk_queue_bounce_limit(queue, BLK_BOUNCE_HIGH); - blk_queue_max_sectors(queue, dev->bounce_size >> 9); + blk_queue_max_hw_sectors(queue, dev->bounce_size >> 9); blk_queue_segment_boundary(queue, -1UL); blk_queue_dma_alignment(queue, dev->blk_size-1); blk_queue_logical_block_size(queue, dev->blk_size); diff --git a/drivers/block/ps3vram.c b/drivers/block/ps3vram.c index a7ecb43b16ab..6416b262934b 100644 --- a/drivers/block/ps3vram.c +++ b/drivers/block/ps3vram.c @@ -754,7 +754,7 @@ static int __devinit ps3vram_probe(struct ps3_system_bus_device *dev) blk_queue_max_phys_segments(queue, MAX_PHYS_SEGMENTS); blk_queue_max_hw_segments(queue, MAX_HW_SEGMENTS); blk_queue_max_segment_size(queue, BLK_MAX_SEGMENT_SIZE); - blk_queue_max_sectors(queue, BLK_SAFE_MAX_SECTORS); + blk_queue_max_hw_sectors(queue, BLK_SAFE_MAX_SECTORS); gendisk = alloc_disk(1); if (!gendisk) { diff --git a/drivers/block/sunvdc.c b/drivers/block/sunvdc.c index 411f064760b4..dd30cddd0f7f 100644 --- a/drivers/block/sunvdc.c +++ b/drivers/block/sunvdc.c @@ -693,7 +693,7 @@ static int probe_disk(struct vdc_port *port) blk_queue_max_hw_segments(q, port->ring_cookies); blk_queue_max_phys_segments(q, port->ring_cookies); - blk_queue_max_sectors(q, port->max_xfer_size); + blk_queue_max_hw_sectors(q, port->max_xfer_size); g->major = vdc_major; g->first_minor = port->vio.vdev->dev_no << PARTITION_SHIFT; strcpy(g->disk_name, port->disk_name); diff --git a/drivers/block/ub.c b/drivers/block/ub.c index d86d1357ccef..352ea24d66e8 100644 --- a/drivers/block/ub.c +++ b/drivers/block/ub.c @@ -2323,7 +2323,7 @@ static int ub_probe_lun(struct ub_dev *sc, int lnum) blk_queue_max_hw_segments(q, UB_MAX_REQ_SG); blk_queue_max_phys_segments(q, UB_MAX_REQ_SG); blk_queue_segment_boundary(q, 0xffffffff); /* Dubious. */ - blk_queue_max_sectors(q, UB_MAX_SECTORS); + blk_queue_max_hw_sectors(q, UB_MAX_SECTORS); blk_queue_logical_block_size(q, lun->capacity.bsize); lun->disk = disk; diff --git a/drivers/block/viodasd.c b/drivers/block/viodasd.c index a8c8b56b275e..d44ece7d7b7c 100644 --- a/drivers/block/viodasd.c +++ b/drivers/block/viodasd.c @@ -473,7 +473,7 @@ retry: d->disk = g; blk_queue_max_hw_segments(q, VIOMAXBLOCKDMA); blk_queue_max_phys_segments(q, VIOMAXBLOCKDMA); - blk_queue_max_sectors(q, VIODASD_MAXSECTORS); + blk_queue_max_hw_sectors(q, VIODASD_MAXSECTORS); g->major = VIODASD_MAJOR; g->first_minor = dev_no << PARTITION_SHIFT; if (dev_no >= 26) diff --git a/drivers/block/xd.c b/drivers/block/xd.c index d1fd032e7514..1a325fb05c92 100644 --- a/drivers/block/xd.c +++ b/drivers/block/xd.c @@ -242,7 +242,7 @@ static int __init xd_init(void) } /* xd_maxsectors depends on controller - so set after detection */ - blk_queue_max_sectors(xd_queue, xd_maxsectors); + blk_queue_max_hw_sectors(xd_queue, xd_maxsectors); for (i = 0; i < xd_drives; i++) add_disk(xd_gendisk[i]); diff --git a/drivers/block/xen-blkfront.c b/drivers/block/xen-blkfront.c index a84702d1a35e..f9861aaa1fef 100644 --- a/drivers/block/xen-blkfront.c +++ b/drivers/block/xen-blkfront.c @@ -346,7 +346,7 @@ static int xlvbd_init_blk_queue(struct gendisk *gd, u16 sector_size) /* Hard sector size and max sectors impersonate the equiv. hardware. */ blk_queue_logical_block_size(rq, sector_size); - blk_queue_max_sectors(rq, 512); + blk_queue_max_hw_sectors(rq, 512); /* Each segment in a request is up to an aligned page in size. */ blk_queue_segment_boundary(rq, PAGE_SIZE - 1); diff --git a/drivers/cdrom/viocd.c b/drivers/cdrom/viocd.c index 57ca69e0ac55..b1dfd23eb832 100644 --- a/drivers/cdrom/viocd.c +++ b/drivers/cdrom/viocd.c @@ -618,7 +618,7 @@ static int viocd_probe(struct vio_dev *vdev, const struct vio_device_id *id) sizeof(gendisk->disk_name)); blk_queue_max_hw_segments(q, 1); blk_queue_max_phys_segments(q, 1); - blk_queue_max_sectors(q, 4096 / 512); + blk_queue_max_hw_sectors(q, 4096 / 512); gendisk->queue = q; gendisk->fops = &viocd_fops; gendisk->flags = GENHD_FL_CD|GENHD_FL_REMOVABLE; diff --git a/drivers/firewire/sbp2.c b/drivers/firewire/sbp2.c index d485cdd8cbac..70fef40cd22f 100644 --- a/drivers/firewire/sbp2.c +++ b/drivers/firewire/sbp2.c @@ -1571,7 +1571,7 @@ static int sbp2_scsi_slave_configure(struct scsi_device *sdev) sdev->start_stop_pwr_cond = 1; if (lu->tgt->workarounds & SBP2_WORKAROUND_128K_MAX_TRANS) - blk_queue_max_sectors(sdev->request_queue, 128 * 1024 / 512); + blk_queue_max_hw_sectors(sdev->request_queue, 128 * 1024 / 512); blk_queue_max_segment_size(sdev->request_queue, SBP2_MAX_SEG_SIZE); diff --git a/drivers/ide/ide-disk.c b/drivers/ide/ide-disk.c index 7f878017b736..3b128dce9c3a 100644 --- a/drivers/ide/ide-disk.c +++ b/drivers/ide/ide-disk.c @@ -679,7 +679,7 @@ static void ide_disk_setup(ide_drive_t *drive) if (max_s > hwif->rqsize) max_s = hwif->rqsize; - blk_queue_max_sectors(q, max_s); + blk_queue_max_hw_sectors(q, max_s); } printk(KERN_INFO "%s: max request size: %dKiB\n", drive->name, diff --git a/drivers/ide/ide-floppy.c b/drivers/ide/ide-floppy.c index fefbdfc8db06..efd907623469 100644 --- a/drivers/ide/ide-floppy.c +++ b/drivers/ide/ide-floppy.c @@ -486,7 +486,7 @@ static void ide_floppy_setup(ide_drive_t *drive) drive->atapi_flags |= IDE_AFLAG_ZIP_DRIVE; /* This value will be visible in the /proc/ide/hdx/settings */ drive->pc_delay = IDEFLOPPY_PC_DELAY; - blk_queue_max_sectors(drive->queue, 64); + blk_queue_max_hw_sectors(drive->queue, 64); } /* @@ -494,7 +494,7 @@ static void ide_floppy_setup(ide_drive_t *drive) * nasty clicking noises without it, so please don't remove this. */ if (strncmp((char *)&id[ATA_ID_PROD], "IOMEGA Clik!", 11) == 0) { - blk_queue_max_sectors(drive->queue, 64); + blk_queue_max_hw_sectors(drive->queue, 64); drive->atapi_flags |= IDE_AFLAG_CLIK_DRIVE; /* IOMEGA Clik! drives do not support lock/unlock commands */ drive->dev_flags &= ~IDE_DFLAG_DOORLOCKING; diff --git a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c index 4d76ba473097..1ec8b31277bd 100644 --- a/drivers/ide/ide-probe.c +++ b/drivers/ide/ide-probe.c @@ -774,7 +774,7 @@ static int ide_init_queue(ide_drive_t *drive) if (hwif->rqsize < max_sectors) max_sectors = hwif->rqsize; - blk_queue_max_sectors(q, max_sectors); + blk_queue_max_hw_sectors(q, max_sectors); #ifdef CONFIG_PCI /* When we have an IOMMU, we may have a problem where pci_map_sg() diff --git a/drivers/ieee1394/sbp2.c b/drivers/ieee1394/sbp2.c index f199896c4113..c88696a6cf8a 100644 --- a/drivers/ieee1394/sbp2.c +++ b/drivers/ieee1394/sbp2.c @@ -2020,7 +2020,7 @@ static int sbp2scsi_slave_configure(struct scsi_device *sdev) if (lu->workarounds & SBP2_WORKAROUND_POWER_CONDITION) sdev->start_stop_pwr_cond = 1; if (lu->workarounds & SBP2_WORKAROUND_128K_MAX_TRANS) - blk_queue_max_sectors(sdev->request_queue, 128 * 1024 / 512); + blk_queue_max_hw_sectors(sdev->request_queue, 128 * 1024 / 512); blk_queue_max_segment_size(sdev->request_queue, SBP2_MAX_SEG_SIZE); return 0; diff --git a/drivers/md/linear.c b/drivers/md/linear.c index 00435bd20699..af2d39d603c7 100644 --- a/drivers/md/linear.c +++ b/drivers/md/linear.c @@ -177,7 +177,7 @@ static linear_conf_t *linear_conf(mddev_t *mddev, int raid_disks) */ if (rdev->bdev->bd_disk->queue->merge_bvec_fn && queue_max_sectors(mddev->queue) > (PAGE_SIZE>>9)) - blk_queue_max_sectors(mddev->queue, PAGE_SIZE>>9); + blk_queue_max_hw_sectors(mddev->queue, PAGE_SIZE>>9); conf->array_sectors += rdev->sectors; cnt++; diff --git a/drivers/md/multipath.c b/drivers/md/multipath.c index 32a662fc55c9..4b323f45ad74 100644 --- a/drivers/md/multipath.c +++ b/drivers/md/multipath.c @@ -308,7 +308,7 @@ static int multipath_add_disk(mddev_t *mddev, mdk_rdev_t *rdev) */ if (q->merge_bvec_fn && queue_max_sectors(q) > (PAGE_SIZE>>9)) - blk_queue_max_sectors(mddev->queue, PAGE_SIZE>>9); + blk_queue_max_hw_sectors(mddev->queue, PAGE_SIZE>>9); conf->working_disks++; mddev->degraded--; @@ -478,7 +478,7 @@ static int multipath_run (mddev_t *mddev) * a merge_bvec_fn to be involved in multipath */ if (rdev->bdev->bd_disk->queue->merge_bvec_fn && queue_max_sectors(mddev->queue) > (PAGE_SIZE>>9)) - blk_queue_max_sectors(mddev->queue, PAGE_SIZE>>9); + blk_queue_max_hw_sectors(mddev->queue, PAGE_SIZE>>9); if (!test_bit(Faulty, &rdev->flags)) conf->working_disks++; diff --git a/drivers/md/raid0.c b/drivers/md/raid0.c index 77605cdceaf1..a1f7147b757f 100644 --- a/drivers/md/raid0.c +++ b/drivers/md/raid0.c @@ -182,7 +182,7 @@ static int create_strip_zones(mddev_t *mddev) if (rdev1->bdev->bd_disk->queue->merge_bvec_fn && queue_max_sectors(mddev->queue) > (PAGE_SIZE>>9)) - blk_queue_max_sectors(mddev->queue, PAGE_SIZE>>9); + blk_queue_max_hw_sectors(mddev->queue, PAGE_SIZE>>9); if (!smallest || (rdev1->sectors < smallest->sectors)) smallest = rdev1; @@ -325,7 +325,7 @@ static int raid0_run(mddev_t *mddev) } if (md_check_no_bitmap(mddev)) return -EINVAL; - blk_queue_max_sectors(mddev->queue, mddev->chunk_sectors); + blk_queue_max_hw_sectors(mddev->queue, mddev->chunk_sectors); mddev->queue->queue_lock = &mddev->queue->__queue_lock; ret = create_strip_zones(mddev); diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c index 859bd3ffe435..5a06122abd3b 100644 --- a/drivers/md/raid1.c +++ b/drivers/md/raid1.c @@ -1158,7 +1158,7 @@ static int raid1_add_disk(mddev_t *mddev, mdk_rdev_t *rdev) */ if (rdev->bdev->bd_disk->queue->merge_bvec_fn && queue_max_sectors(mddev->queue) > (PAGE_SIZE>>9)) - blk_queue_max_sectors(mddev->queue, PAGE_SIZE>>9); + blk_queue_max_hw_sectors(mddev->queue, PAGE_SIZE>>9); p->head_position = 0; rdev->raid_disk = mirror; @@ -2103,7 +2103,7 @@ static int run(mddev_t *mddev) */ if (rdev->bdev->bd_disk->queue->merge_bvec_fn && queue_max_sectors(mddev->queue) > (PAGE_SIZE>>9)) - blk_queue_max_sectors(mddev->queue, PAGE_SIZE>>9); + blk_queue_max_hw_sectors(mddev->queue, PAGE_SIZE>>9); } mddev->degraded = 0; diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c index d119b7b75e71..7584f9ab9bcf 100644 --- a/drivers/md/raid10.c +++ b/drivers/md/raid10.c @@ -1161,7 +1161,7 @@ static int raid10_add_disk(mddev_t *mddev, mdk_rdev_t *rdev) */ if (rdev->bdev->bd_disk->queue->merge_bvec_fn && queue_max_sectors(mddev->queue) > (PAGE_SIZE>>9)) - blk_queue_max_sectors(mddev->queue, PAGE_SIZE>>9); + blk_queue_max_hw_sectors(mddev->queue, PAGE_SIZE>>9); p->head_position = 0; rdev->raid_disk = mirror; @@ -2260,7 +2260,7 @@ static int run(mddev_t *mddev) */ if (rdev->bdev->bd_disk->queue->merge_bvec_fn && queue_max_sectors(mddev->queue) > (PAGE_SIZE>>9)) - blk_queue_max_sectors(mddev->queue, PAGE_SIZE>>9); + blk_queue_max_hw_sectors(mddev->queue, PAGE_SIZE>>9); disk->head_position = 0; } diff --git a/drivers/memstick/core/mspro_block.c b/drivers/memstick/core/mspro_block.c index bd83fa0a4970..44d4178c4c15 100644 --- a/drivers/memstick/core/mspro_block.c +++ b/drivers/memstick/core/mspro_block.c @@ -1226,7 +1226,7 @@ static int mspro_block_init_disk(struct memstick_dev *card) blk_queue_prep_rq(msb->queue, mspro_block_prepare_req); blk_queue_bounce_limit(msb->queue, limit); - blk_queue_max_sectors(msb->queue, MSPRO_BLOCK_MAX_PAGES); + blk_queue_max_hw_sectors(msb->queue, MSPRO_BLOCK_MAX_PAGES); blk_queue_max_phys_segments(msb->queue, MSPRO_BLOCK_MAX_SEGS); blk_queue_max_hw_segments(msb->queue, MSPRO_BLOCK_MAX_SEGS); blk_queue_max_segment_size(msb->queue, diff --git a/drivers/message/i2o/i2o_block.c b/drivers/message/i2o/i2o_block.c index e39986a78273..d033cfdb516f 100644 --- a/drivers/message/i2o/i2o_block.c +++ b/drivers/message/i2o/i2o_block.c @@ -1066,7 +1066,7 @@ static int i2o_block_probe(struct device *dev) queue->queuedata = i2o_blk_dev; blk_queue_max_phys_segments(queue, I2O_MAX_PHYS_SEGMENTS); - blk_queue_max_sectors(queue, max_sectors); + blk_queue_max_hw_sectors(queue, max_sectors); blk_queue_max_hw_segments(queue, i2o_sg_tablesize(c, body_size)); osm_debug("max sectors = %d\n", queue->max_sectors); diff --git a/drivers/mmc/card/queue.c b/drivers/mmc/card/queue.c index c5a7a855f4b1..09b633d5657b 100644 --- a/drivers/mmc/card/queue.c +++ b/drivers/mmc/card/queue.c @@ -154,7 +154,7 @@ int mmc_init_queue(struct mmc_queue *mq, struct mmc_card *card, spinlock_t *lock if (mq->bounce_buf) { blk_queue_bounce_limit(mq->queue, BLK_BOUNCE_ANY); - blk_queue_max_sectors(mq->queue, bouncesz / 512); + blk_queue_max_hw_sectors(mq->queue, bouncesz / 512); blk_queue_max_phys_segments(mq->queue, bouncesz / 512); blk_queue_max_hw_segments(mq->queue, bouncesz / 512); blk_queue_max_segment_size(mq->queue, bouncesz); @@ -180,7 +180,7 @@ int mmc_init_queue(struct mmc_queue *mq, struct mmc_card *card, spinlock_t *lock if (!mq->bounce_buf) { blk_queue_bounce_limit(mq->queue, limit); - blk_queue_max_sectors(mq->queue, + blk_queue_max_hw_sectors(mq->queue, min(host->max_blk_count, host->max_req_size / 512)); blk_queue_max_phys_segments(mq->queue, host->max_phys_segs); blk_queue_max_hw_segments(mq->queue, host->max_hw_segs); diff --git a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c index 5905936c7c60..14b1e25b9dcf 100644 --- a/drivers/s390/block/dasd.c +++ b/drivers/s390/block/dasd.c @@ -2129,7 +2129,7 @@ static void dasd_setup_queue(struct dasd_block *block) blk_queue_logical_block_size(block->request_queue, block->bp_block); max = block->base->discipline->max_blocks << block->s2b_shift; - blk_queue_max_sectors(block->request_queue, max); + blk_queue_max_hw_sectors(block->request_queue, max); blk_queue_max_phys_segments(block->request_queue, -1L); blk_queue_max_hw_segments(block->request_queue, -1L); /* with page sized segments we can translate each segement into diff --git a/drivers/s390/char/tape_block.c b/drivers/s390/char/tape_block.c index 8d3d720737da..509ed056fddd 100644 --- a/drivers/s390/char/tape_block.c +++ b/drivers/s390/char/tape_block.c @@ -222,7 +222,7 @@ tapeblock_setup_device(struct tape_device * device) goto cleanup_queue; blk_queue_logical_block_size(blkdat->request_queue, TAPEBLOCK_HSEC_SIZE); - blk_queue_max_sectors(blkdat->request_queue, TAPEBLOCK_MAX_SEC); + blk_queue_max_hw_sectors(blkdat->request_queue, TAPEBLOCK_MAX_SEC); blk_queue_max_phys_segments(blkdat->request_queue, -1L); blk_queue_max_hw_segments(blkdat->request_queue, -1L); blk_queue_max_segment_size(blkdat->request_queue, -1L); diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c index 9e52d16c7c39..032f0d0e6cb4 100644 --- a/drivers/scsi/ipr.c +++ b/drivers/scsi/ipr.c @@ -3674,7 +3674,7 @@ static int ipr_slave_configure(struct scsi_device *sdev) if (ipr_is_vset_device(res)) { blk_queue_rq_timeout(sdev->request_queue, IPR_VSET_RW_TIMEOUT); - blk_queue_max_sectors(sdev->request_queue, IPR_VSET_MAX_SECTORS); + blk_queue_max_hw_sectors(sdev->request_queue, IPR_VSET_MAX_SECTORS); } if (ipr_is_vset_device(res) || ipr_is_scsi_disk(res)) sdev->allow_restart = 1; diff --git a/drivers/scsi/pmcraid.c b/drivers/scsi/pmcraid.c index b6f1ef954af1..9b1c1433c26b 100644 --- a/drivers/scsi/pmcraid.c +++ b/drivers/scsi/pmcraid.c @@ -235,7 +235,7 @@ static int pmcraid_slave_configure(struct scsi_device *scsi_dev) scsi_dev->allow_restart = 1; blk_queue_rq_timeout(scsi_dev->request_queue, PMCRAID_VSET_IO_TIMEOUT); - blk_queue_max_sectors(scsi_dev->request_queue, + blk_queue_max_hw_sectors(scsi_dev->request_queue, PMCRAID_VSET_MAX_SECTORS); } diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index c6642423cc67..ac3cca74bdfb 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c @@ -1627,7 +1627,7 @@ struct request_queue *__scsi_alloc_queue(struct Scsi_Host *shost, blk_queue_max_hw_segments(q, shost->sg_tablesize); blk_queue_max_phys_segments(q, SCSI_MAX_SG_CHAIN_SEGMENTS); - blk_queue_max_sectors(q, shost->max_sectors); + blk_queue_max_hw_sectors(q, shost->max_sectors); blk_queue_bounce_limit(q, scsi_calculate_bounce_limit(shost)); blk_queue_segment_boundary(q, shost->dma_boundary); dma_set_seg_boundary(dev, shost->dma_boundary); diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c index 012f73a96880..5d9b5130d8c8 100644 --- a/drivers/scsi/scsi_scan.c +++ b/drivers/scsi/scsi_scan.c @@ -879,7 +879,7 @@ static int scsi_add_lun(struct scsi_device *sdev, unsigned char *inq_result, * broken RA4x00 Compaq Disk Array */ if (*bflags & BLIST_MAX_512) - blk_queue_max_sectors(sdev->request_queue, 512); + blk_queue_max_hw_sectors(sdev->request_queue, 512); /* * Some devices may not want to have a start command automatically diff --git a/drivers/usb/storage/scsiglue.c b/drivers/usb/storage/scsiglue.c index e5e6df39e737..aadc16b5eed7 100644 --- a/drivers/usb/storage/scsiglue.c +++ b/drivers/usb/storage/scsiglue.c @@ -134,14 +134,14 @@ static int slave_configure(struct scsi_device *sdev) if (us->fflags & US_FL_MAX_SECTORS_MIN) max_sectors = PAGE_CACHE_SIZE >> 9; if (queue_max_sectors(sdev->request_queue) > max_sectors) - blk_queue_max_sectors(sdev->request_queue, + blk_queue_max_hw_sectors(sdev->request_queue, max_sectors); } else if (sdev->type == TYPE_TAPE) { /* Tapes need much higher max_sector limits, so just * raise it to the maximum possible (4 GB / 512) and * let the queue segment size sort out the real limit. */ - blk_queue_max_sectors(sdev->request_queue, 0x7FFFFF); + blk_queue_max_hw_sectors(sdev->request_queue, 0x7FFFFF); } /* Some USB host controllers can't do DMA; they have to use PIO. @@ -495,7 +495,7 @@ static ssize_t store_max_sectors(struct device *dev, struct device_attribute *at unsigned short ms; if (sscanf(buf, "%hu", &ms) > 0 && ms <= SCSI_DEFAULT_MAX_SECTORS) { - blk_queue_max_sectors(sdev->request_queue, ms); + blk_queue_max_hw_sectors(sdev->request_queue, ms); return strlen(buf); } return -EINVAL; -- cgit v1.2.2 From 8a78362c4eefc1deddbefe2c7f38aabbc2429d6b Mon Sep 17 00:00:00 2001 From: "Martin K. Petersen" Date: Fri, 26 Feb 2010 00:20:39 -0500 Subject: block: Consolidate phys_segment and hw_segment limits Except for SCSI no device drivers distinguish between physical and hardware segment limits. Consolidate the two into a single segment limit. Signed-off-by: Martin K. Petersen Signed-off-by: Jens Axboe --- drivers/ata/sata_nv.c | 2 +- drivers/block/DAC960.c | 2 +- drivers/block/cciss.c | 5 +---- drivers/block/cpqarray.c | 5 +---- drivers/block/drbd/drbd_nl.c | 3 +-- drivers/block/paride/pf.c | 3 +-- drivers/block/pktcdvd.c | 4 ++-- drivers/block/ps3disk.c | 3 +-- drivers/block/ps3vram.c | 3 +-- drivers/block/sunvdc.c | 3 +-- drivers/block/sx8.c | 3 +-- drivers/block/ub.c | 3 +-- drivers/block/viodasd.c | 3 +-- drivers/block/xen-blkfront.c | 3 +-- drivers/cdrom/gdrom.c | 2 +- drivers/cdrom/viocd.c | 3 +-- drivers/ide/ide-probe.c | 3 +-- drivers/md/raid5.c | 2 +- drivers/memstick/core/mspro_block.c | 3 +-- drivers/message/i2o/i2o_block.c | 3 +-- drivers/mmc/card/queue.c | 6 ++---- drivers/s390/block/dasd.c | 3 +-- drivers/s390/char/tape_block.c | 3 +-- drivers/scsi/ibmvscsi/ibmvfc.c | 4 ++-- drivers/scsi/scsi_lib.c | 4 ++-- drivers/scsi/sg.c | 6 ++---- drivers/scsi/st.c | 3 +-- drivers/staging/hv/blkvsc_drv.c | 5 +---- 28 files changed, 33 insertions(+), 62 deletions(-) (limited to 'drivers') diff --git a/drivers/ata/sata_nv.c b/drivers/ata/sata_nv.c index 0c82d335c55d..684fe04dbbb7 100644 --- a/drivers/ata/sata_nv.c +++ b/drivers/ata/sata_nv.c @@ -772,7 +772,7 @@ static int nv_adma_slave_config(struct scsi_device *sdev) } blk_queue_segment_boundary(sdev->request_queue, segment_boundary); - blk_queue_max_hw_segments(sdev->request_queue, sg_tablesize); + blk_queue_max_segments(sdev->request_queue, sg_tablesize); ata_port_printk(ap, KERN_INFO, "DMA mask 0x%llX, segment boundary 0x%lX, hw segs %hu\n", (unsigned long long)*ap->host->dev->dma_mask, diff --git a/drivers/block/DAC960.c b/drivers/block/DAC960.c index 1c0cd35e1913..459f1bc25a7b 100644 --- a/drivers/block/DAC960.c +++ b/drivers/block/DAC960.c @@ -2534,7 +2534,7 @@ static bool DAC960_RegisterBlockDevice(DAC960_Controller_T *Controller) blk_queue_bounce_limit(RequestQueue, Controller->BounceBufferLimit); RequestQueue->queuedata = Controller; blk_queue_max_hw_segments(RequestQueue, Controller->DriverScatterGatherLimit); - blk_queue_max_phys_segments(RequestQueue, Controller->DriverScatterGatherLimit); + blk_queue_max_segments(RequestQueue, Controller->DriverScatterGatherLimit); blk_queue_max_hw_sectors(RequestQueue, Controller->MaxBlocksPerCommand); disk->queue = RequestQueue; sprintf(disk->disk_name, "rd/c%dd%d", Controller->ControllerNumber, n); diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c index 030e52d72254..a29e69418a03 100644 --- a/drivers/block/cciss.c +++ b/drivers/block/cciss.c @@ -1797,10 +1797,7 @@ static int cciss_add_disk(ctlr_info_t *h, struct gendisk *disk, blk_queue_bounce_limit(disk->queue, h->pdev->dma_mask); /* This is a hardware imposed limit. */ - blk_queue_max_hw_segments(disk->queue, h->maxsgentries); - - /* This is a limit in the driver and could be eliminated. */ - blk_queue_max_phys_segments(disk->queue, h->maxsgentries); + blk_queue_max_segments(disk->queue, h->maxsgentries); blk_queue_max_hw_sectors(disk->queue, h->cciss_max_sectors); diff --git a/drivers/block/cpqarray.c b/drivers/block/cpqarray.c index 6422651ec364..91d11631cec9 100644 --- a/drivers/block/cpqarray.c +++ b/drivers/block/cpqarray.c @@ -448,11 +448,8 @@ static int __init cpqarray_register_ctlr( int i, struct pci_dev *pdev) blk_queue_bounce_limit(q, hba[i]->pci_dev->dma_mask); /* This is a hardware imposed limit. */ - blk_queue_max_hw_segments(q, SG_MAX); + blk_queue_max_segments(q, SG_MAX); - /* This is a driver limit and could be eliminated. */ - blk_queue_max_phys_segments(q, SG_MAX); - init_timer(&hba[i]->timer); hba[i]->timer.expires = jiffies + IDA_TIMER; hba[i]->timer.data = (unsigned long)hba[i]; diff --git a/drivers/block/drbd/drbd_nl.c b/drivers/block/drbd/drbd_nl.c index 9b55e64196fc..4df3b40b1057 100644 --- a/drivers/block/drbd/drbd_nl.c +++ b/drivers/block/drbd/drbd_nl.c @@ -710,8 +710,7 @@ void drbd_setup_queue_param(struct drbd_conf *mdev, unsigned int max_seg_s) __mu max_seg_s = min(queue_max_sectors(b) * queue_logical_block_size(b), max_seg_s); blk_queue_max_hw_sectors(q, max_seg_s >> 9); - blk_queue_max_phys_segments(q, max_segments ? max_segments : MAX_PHYS_SEGMENTS); - blk_queue_max_hw_segments(q, max_segments ? max_segments : MAX_HW_SEGMENTS); + blk_queue_max_segments(q, max_segments ? max_segments : BLK_MAX_SEGMENTS); blk_queue_max_segment_size(q, max_seg_s); blk_queue_logical_block_size(q, 512); blk_queue_segment_boundary(q, PAGE_SIZE-1); diff --git a/drivers/block/paride/pf.c b/drivers/block/paride/pf.c index ea54ea393553..ddb4f9abd480 100644 --- a/drivers/block/paride/pf.c +++ b/drivers/block/paride/pf.c @@ -956,8 +956,7 @@ static int __init pf_init(void) return -ENOMEM; } - blk_queue_max_phys_segments(pf_queue, cluster); - blk_queue_max_hw_segments(pf_queue, cluster); + blk_queue_max_segments(pf_queue, cluster); for (pf = units, unit = 0; unit < PF_UNITS; pf++, unit++) { struct gendisk *disk = pf->disk; diff --git a/drivers/block/pktcdvd.c b/drivers/block/pktcdvd.c index 6e1daa24da2f..b72935b8f203 100644 --- a/drivers/block/pktcdvd.c +++ b/drivers/block/pktcdvd.c @@ -950,14 +950,14 @@ static void pkt_iosched_process_queue(struct pktcdvd_device *pd) static int pkt_set_segment_merging(struct pktcdvd_device *pd, struct request_queue *q) { if ((pd->settings.size << 9) / CD_FRAMESIZE - <= queue_max_phys_segments(q)) { + <= queue_max_segments(q)) { /* * The cdrom device can handle one segment/frame */ clear_bit(PACKET_MERGE_SEGS, &pd->flags); return 0; } else if ((pd->settings.size << 9) / PAGE_SIZE - <= queue_max_phys_segments(q)) { + <= queue_max_segments(q)) { /* * We can handle this case at the expense of some extra memory * copies during write operations diff --git a/drivers/block/ps3disk.c b/drivers/block/ps3disk.c index 9cd1a4a542b8..bc95469d33c1 100644 --- a/drivers/block/ps3disk.c +++ b/drivers/block/ps3disk.c @@ -482,8 +482,7 @@ static int __devinit ps3disk_probe(struct ps3_system_bus_device *_dev) blk_queue_ordered(queue, QUEUE_ORDERED_DRAIN_FLUSH, ps3disk_prepare_flush); - blk_queue_max_phys_segments(queue, -1); - blk_queue_max_hw_segments(queue, -1); + blk_queue_max_segments(queue, -1); blk_queue_max_segment_size(queue, dev->bounce_size); gendisk = alloc_disk(PS3DISK_MINORS); diff --git a/drivers/block/ps3vram.c b/drivers/block/ps3vram.c index 6416b262934b..83ebb390b164 100644 --- a/drivers/block/ps3vram.c +++ b/drivers/block/ps3vram.c @@ -751,8 +751,7 @@ static int __devinit ps3vram_probe(struct ps3_system_bus_device *dev) priv->queue = queue; queue->queuedata = dev; blk_queue_make_request(queue, ps3vram_make_request); - blk_queue_max_phys_segments(queue, MAX_PHYS_SEGMENTS); - blk_queue_max_hw_segments(queue, MAX_HW_SEGMENTS); + blk_queue_max_segments(queue, BLK_MAX_HW_SEGMENTS); blk_queue_max_segment_size(queue, BLK_MAX_SEGMENT_SIZE); blk_queue_max_hw_sectors(queue, BLK_SAFE_MAX_SECTORS); diff --git a/drivers/block/sunvdc.c b/drivers/block/sunvdc.c index dd30cddd0f7f..48e8fee9f2d4 100644 --- a/drivers/block/sunvdc.c +++ b/drivers/block/sunvdc.c @@ -691,8 +691,7 @@ static int probe_disk(struct vdc_port *port) port->disk = g; - blk_queue_max_hw_segments(q, port->ring_cookies); - blk_queue_max_phys_segments(q, port->ring_cookies); + blk_queue_max_segments(q, port->ring_cookies); blk_queue_max_hw_sectors(q, port->max_xfer_size); g->major = vdc_major; g->first_minor = port->vio.vdev->dev_no << PARTITION_SHIFT; diff --git a/drivers/block/sx8.c b/drivers/block/sx8.c index 7bd7b2f83116..b70f0fca9a42 100644 --- a/drivers/block/sx8.c +++ b/drivers/block/sx8.c @@ -1518,8 +1518,7 @@ static int carm_init_disks(struct carm_host *host) break; } disk->queue = q; - blk_queue_max_hw_segments(q, CARM_MAX_REQ_SG); - blk_queue_max_phys_segments(q, CARM_MAX_REQ_SG); + blk_queue_max_segments(q, CARM_MAX_REQ_SG); blk_queue_segment_boundary(q, CARM_SG_BOUNDARY); q->queuedata = port; diff --git a/drivers/block/ub.c b/drivers/block/ub.c index 352ea24d66e8..2e889838e819 100644 --- a/drivers/block/ub.c +++ b/drivers/block/ub.c @@ -2320,8 +2320,7 @@ static int ub_probe_lun(struct ub_dev *sc, int lnum) disk->queue = q; blk_queue_bounce_limit(q, BLK_BOUNCE_HIGH); - blk_queue_max_hw_segments(q, UB_MAX_REQ_SG); - blk_queue_max_phys_segments(q, UB_MAX_REQ_SG); + blk_queue_max_segments(q, UB_MAX_REQ_SG); blk_queue_segment_boundary(q, 0xffffffff); /* Dubious. */ blk_queue_max_hw_sectors(q, UB_MAX_SECTORS); blk_queue_logical_block_size(q, lun->capacity.bsize); diff --git a/drivers/block/viodasd.c b/drivers/block/viodasd.c index d44ece7d7b7c..c12b31362ac6 100644 --- a/drivers/block/viodasd.c +++ b/drivers/block/viodasd.c @@ -471,8 +471,7 @@ retry: } d->disk = g; - blk_queue_max_hw_segments(q, VIOMAXBLOCKDMA); - blk_queue_max_phys_segments(q, VIOMAXBLOCKDMA); + blk_queue_max_segments(q, VIOMAXBLOCKDMA); blk_queue_max_hw_sectors(q, VIODASD_MAXSECTORS); g->major = VIODASD_MAJOR; g->first_minor = dev_no << PARTITION_SHIFT; diff --git a/drivers/block/xen-blkfront.c b/drivers/block/xen-blkfront.c index f9861aaa1fef..9c09694b2520 100644 --- a/drivers/block/xen-blkfront.c +++ b/drivers/block/xen-blkfront.c @@ -353,8 +353,7 @@ static int xlvbd_init_blk_queue(struct gendisk *gd, u16 sector_size) blk_queue_max_segment_size(rq, PAGE_SIZE); /* Ensure a merged request will fit in a single I/O ring slot. */ - blk_queue_max_phys_segments(rq, BLKIF_MAX_SEGMENTS_PER_REQUEST); - blk_queue_max_hw_segments(rq, BLKIF_MAX_SEGMENTS_PER_REQUEST); + blk_queue_max_segments(rq, BLKIF_MAX_SEGMENTS_PER_REQUEST); /* Make sure buffer addresses are sector-aligned. */ blk_queue_dma_alignment(rq, 511); diff --git a/drivers/cdrom/gdrom.c b/drivers/cdrom/gdrom.c index e789e6c9a422..03c71f7698cb 100644 --- a/drivers/cdrom/gdrom.c +++ b/drivers/cdrom/gdrom.c @@ -741,7 +741,7 @@ static int __devinit probe_gdrom_setupqueue(void) { blk_queue_logical_block_size(gd.gdrom_rq, GDROM_HARD_SECTOR); /* using DMA so memory will need to be contiguous */ - blk_queue_max_hw_segments(gd.gdrom_rq, 1); + blk_queue_max_segments(gd.gdrom_rq, 1); /* set a large max size to get most from DMA */ blk_queue_max_segment_size(gd.gdrom_rq, 0x40000); gd.disk->queue = gd.gdrom_rq; diff --git a/drivers/cdrom/viocd.c b/drivers/cdrom/viocd.c index b1dfd23eb832..cc435be0bc13 100644 --- a/drivers/cdrom/viocd.c +++ b/drivers/cdrom/viocd.c @@ -616,8 +616,7 @@ static int viocd_probe(struct vio_dev *vdev, const struct vio_device_id *id) gendisk->first_minor = deviceno; strncpy(gendisk->disk_name, c->name, sizeof(gendisk->disk_name)); - blk_queue_max_hw_segments(q, 1); - blk_queue_max_phys_segments(q, 1); + blk_queue_max_segments(q, 1); blk_queue_max_hw_sectors(q, 4096 / 512); gendisk->queue = q; gendisk->fops = &viocd_fops; diff --git a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c index 1ec8b31277bd..f8c1ae6ad74c 100644 --- a/drivers/ide/ide-probe.c +++ b/drivers/ide/ide-probe.c @@ -790,8 +790,7 @@ static int ide_init_queue(ide_drive_t *drive) max_sg_entries >>= 1; #endif /* CONFIG_PCI */ - blk_queue_max_hw_segments(q, max_sg_entries); - blk_queue_max_phys_segments(q, max_sg_entries); + blk_queue_max_segments(q, max_sg_entries); /* assign drive queue */ drive->queue = q; diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index ceb24afdc147..509c8f3dd9a5 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c @@ -3739,7 +3739,7 @@ static int bio_fits_rdev(struct bio *bi) if ((bi->bi_size>>9) > queue_max_sectors(q)) return 0; blk_recount_segments(q, bi); - if (bi->bi_phys_segments > queue_max_phys_segments(q)) + if (bi->bi_phys_segments > queue_max_segments(q)) return 0; if (q->merge_bvec_fn) diff --git a/drivers/memstick/core/mspro_block.c b/drivers/memstick/core/mspro_block.c index 44d4178c4c15..972b87069d55 100644 --- a/drivers/memstick/core/mspro_block.c +++ b/drivers/memstick/core/mspro_block.c @@ -1227,8 +1227,7 @@ static int mspro_block_init_disk(struct memstick_dev *card) blk_queue_bounce_limit(msb->queue, limit); blk_queue_max_hw_sectors(msb->queue, MSPRO_BLOCK_MAX_PAGES); - blk_queue_max_phys_segments(msb->queue, MSPRO_BLOCK_MAX_SEGS); - blk_queue_max_hw_segments(msb->queue, MSPRO_BLOCK_MAX_SEGS); + blk_queue_max_segments(msb->queue, MSPRO_BLOCK_MAX_SEGS); blk_queue_max_segment_size(msb->queue, MSPRO_BLOCK_MAX_PAGES * msb->page_size); diff --git a/drivers/message/i2o/i2o_block.c b/drivers/message/i2o/i2o_block.c index d033cfdb516f..2658b1484a2c 100644 --- a/drivers/message/i2o/i2o_block.c +++ b/drivers/message/i2o/i2o_block.c @@ -1065,9 +1065,8 @@ static int i2o_block_probe(struct device *dev) queue = gd->queue; queue->queuedata = i2o_blk_dev; - blk_queue_max_phys_segments(queue, I2O_MAX_PHYS_SEGMENTS); blk_queue_max_hw_sectors(queue, max_sectors); - blk_queue_max_hw_segments(queue, i2o_sg_tablesize(c, body_size)); + blk_queue_max_segments(queue, i2o_sg_tablesize(c, body_size)); osm_debug("max sectors = %d\n", queue->max_sectors); osm_debug("phys segments = %d\n", queue->max_phys_segments); diff --git a/drivers/mmc/card/queue.c b/drivers/mmc/card/queue.c index 09b633d5657b..381fe032caa1 100644 --- a/drivers/mmc/card/queue.c +++ b/drivers/mmc/card/queue.c @@ -155,8 +155,7 @@ int mmc_init_queue(struct mmc_queue *mq, struct mmc_card *card, spinlock_t *lock if (mq->bounce_buf) { blk_queue_bounce_limit(mq->queue, BLK_BOUNCE_ANY); blk_queue_max_hw_sectors(mq->queue, bouncesz / 512); - blk_queue_max_phys_segments(mq->queue, bouncesz / 512); - blk_queue_max_hw_segments(mq->queue, bouncesz / 512); + blk_queue_max_segments(mq->queue, bouncesz / 512); blk_queue_max_segment_size(mq->queue, bouncesz); mq->sg = kmalloc(sizeof(struct scatterlist), @@ -182,8 +181,7 @@ int mmc_init_queue(struct mmc_queue *mq, struct mmc_card *card, spinlock_t *lock blk_queue_bounce_limit(mq->queue, limit); blk_queue_max_hw_sectors(mq->queue, min(host->max_blk_count, host->max_req_size / 512)); - blk_queue_max_phys_segments(mq->queue, host->max_phys_segs); - blk_queue_max_hw_segments(mq->queue, host->max_hw_segs); + blk_queue_max_segments(mq->queue, host->max_hw_segs); blk_queue_max_segment_size(mq->queue, host->max_seg_size); mq->sg = kmalloc(sizeof(struct scatterlist) * diff --git a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c index 14b1e25b9dcf..8831e9308d05 100644 --- a/drivers/s390/block/dasd.c +++ b/drivers/s390/block/dasd.c @@ -2130,8 +2130,7 @@ static void dasd_setup_queue(struct dasd_block *block) blk_queue_logical_block_size(block->request_queue, block->bp_block); max = block->base->discipline->max_blocks << block->s2b_shift; blk_queue_max_hw_sectors(block->request_queue, max); - blk_queue_max_phys_segments(block->request_queue, -1L); - blk_queue_max_hw_segments(block->request_queue, -1L); + blk_queue_max_segments(block->request_queue, -1L); /* with page sized segments we can translate each segement into * one idaw/tidaw */ diff --git a/drivers/s390/char/tape_block.c b/drivers/s390/char/tape_block.c index 509ed056fddd..097da8ce6be6 100644 --- a/drivers/s390/char/tape_block.c +++ b/drivers/s390/char/tape_block.c @@ -223,8 +223,7 @@ tapeblock_setup_device(struct tape_device * device) blk_queue_logical_block_size(blkdat->request_queue, TAPEBLOCK_HSEC_SIZE); blk_queue_max_hw_sectors(blkdat->request_queue, TAPEBLOCK_MAX_SEC); - blk_queue_max_phys_segments(blkdat->request_queue, -1L); - blk_queue_max_hw_segments(blkdat->request_queue, -1L); + blk_queue_max_segments(blkdat->request_queue, -1L); blk_queue_max_segment_size(blkdat->request_queue, -1L); blk_queue_segment_boundary(blkdat->request_queue, -1L); diff --git a/drivers/scsi/ibmvscsi/ibmvfc.c b/drivers/scsi/ibmvscsi/ibmvfc.c index 87b536a97cb4..732f6d35b4a8 100644 --- a/drivers/scsi/ibmvscsi/ibmvfc.c +++ b/drivers/scsi/ibmvscsi/ibmvfc.c @@ -4195,7 +4195,7 @@ static void ibmvfc_tgt_add_rport(struct ibmvfc_target *tgt) if (tgt->service_parms.class3_parms[0] & 0x80000000) rport->supported_classes |= FC_COS_CLASS3; if (rport->rqst_q) - blk_queue_max_hw_segments(rport->rqst_q, 1); + blk_queue_max_segments(rport->rqst_q, 1); } else tgt_dbg(tgt, "rport add failed\n"); spin_unlock_irqrestore(vhost->host->host_lock, flags); @@ -4669,7 +4669,7 @@ static int ibmvfc_probe(struct vio_dev *vdev, const struct vio_device_id *id) } if (shost_to_fc_host(shost)->rqst_q) - blk_queue_max_hw_segments(shost_to_fc_host(shost)->rqst_q, 1); + blk_queue_max_segments(shost_to_fc_host(shost)->rqst_q, 1); dev_set_drvdata(dev, vhost); spin_lock(&ibmvfc_driver_lock); list_add_tail(&vhost->queue, &ibmvfc_head); diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index ac3cca74bdfb..f8fbf47377ae 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c @@ -1624,8 +1624,8 @@ struct request_queue *__scsi_alloc_queue(struct Scsi_Host *shost, /* * this limit is imposed by hardware restrictions */ - blk_queue_max_hw_segments(q, shost->sg_tablesize); - blk_queue_max_phys_segments(q, SCSI_MAX_SG_CHAIN_SEGMENTS); + blk_queue_max_segments(q, min_t(unsigned short, shost->sg_tablesize, + SCSI_MAX_SG_CHAIN_SEGMENTS)); blk_queue_max_hw_sectors(q, shost->max_sectors); blk_queue_bounce_limit(q, scsi_calculate_bounce_limit(shost)); diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c index 040f751809ea..c996d98636f3 100644 --- a/drivers/scsi/sg.c +++ b/drivers/scsi/sg.c @@ -287,8 +287,7 @@ sg_open(struct inode *inode, struct file *filp) if (list_empty(&sdp->sfds)) { /* no existing opens on this device */ sdp->sgdebug = 0; q = sdp->device->request_queue; - sdp->sg_tablesize = min(queue_max_hw_segments(q), - queue_max_phys_segments(q)); + sdp->sg_tablesize = queue_max_segments(q); } if ((sfp = sg_add_sfp(sdp, dev))) filp->private_data = sfp; @@ -1376,8 +1375,7 @@ static Sg_device *sg_alloc(struct gendisk *disk, struct scsi_device *scsidp) sdp->device = scsidp; INIT_LIST_HEAD(&sdp->sfds); init_waitqueue_head(&sdp->o_excl_wait); - sdp->sg_tablesize = min(queue_max_hw_segments(q), - queue_max_phys_segments(q)); + sdp->sg_tablesize = queue_max_segments(q); sdp->index = k; kref_init(&sdp->d_ref); diff --git a/drivers/scsi/st.c b/drivers/scsi/st.c index d04ea9a6f673..f67d1a159aad 100644 --- a/drivers/scsi/st.c +++ b/drivers/scsi/st.c @@ -3983,8 +3983,7 @@ static int st_probe(struct device *dev) return -ENODEV; } - i = min(queue_max_hw_segments(SDp->request_queue), - queue_max_phys_segments(SDp->request_queue)); + i = queue_max_segments(SDp->request_queue); if (st_max_sg_segs < i) i = st_max_sg_segs; buffer = new_tape_buffer((SDp->host)->unchecked_isa_dma, i); diff --git a/drivers/staging/hv/blkvsc_drv.c b/drivers/staging/hv/blkvsc_drv.c index 62b282844a53..45d908114d11 100644 --- a/drivers/staging/hv/blkvsc_drv.c +++ b/drivers/staging/hv/blkvsc_drv.c @@ -363,10 +363,7 @@ static int blkvsc_probe(struct device *device) blkdev->gd->queue = blk_init_queue(blkvsc_request, &blkdev->lock); blk_queue_max_segment_size(blkdev->gd->queue, PAGE_SIZE); - blk_queue_max_phys_segments(blkdev->gd->queue, - MAX_MULTIPAGE_BUFFER_COUNT); - blk_queue_max_hw_segments(blkdev->gd->queue, - MAX_MULTIPAGE_BUFFER_COUNT); + blk_queue_max_segments(blkdev->gd->queue, MAX_MULTIPAGE_BUFFER_COUNT); blk_queue_segment_boundary(blkdev->gd->queue, PAGE_SIZE-1); blk_queue_bounce_limit(blkdev->gd->queue, BLK_BOUNCE_ANY); blk_queue_dma_alignment(blkdev->gd->queue, 511); -- cgit v1.2.2 From 5d68e0326b146f28fbb8fe6375dd7d15ca929be7 Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Fri, 26 Feb 2010 11:32:56 +0200 Subject: OMAP: DSS2: DSI: add error prints Add error printing for dsi_vc_dcs_write() and dsi_vc_dcs_read(). Signed-off-by: Tomi Valkeinen --- drivers/video/omap2/dss/dsi.c | 47 +++++++++++++++++++++++++++++++------------ 1 file changed, 34 insertions(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c index a9820206ca1e..3af207b2bde3 100644 --- a/drivers/video/omap2/dss/dsi.c +++ b/drivers/video/omap2/dss/dsi.c @@ -2081,10 +2081,16 @@ int dsi_vc_dcs_write(int channel, u8 *data, int len) r = dsi_vc_dcs_write_nosync(channel, data, len); if (r) - return r; + goto err; r = dsi_vc_send_bta_sync(channel); + if (r) + goto err; + return 0; +err: + DSSERR("dsi_vc_dcs_write(ch %d, cmd 0x%02x, len %d) failed\n", + channel, data[0], len); return r; } EXPORT_SYMBOL(dsi_vc_dcs_write); @@ -2115,16 +2121,17 @@ int dsi_vc_dcs_read(int channel, u8 dcs_cmd, u8 *buf, int buflen) r = dsi_vc_send_short(channel, DSI_DT_DCS_READ, dcs_cmd, 0); if (r) - return r; + goto err; r = dsi_vc_send_bta_sync(channel); if (r) - return r; + goto err; /* RX_FIFO_NOT_EMPTY */ if (REG_GET(DSI_VC_CTRL(channel), 20, 20) == 0) { DSSERR("RX fifo empty when trying to read.\n"); - return -EIO; + r = -EIO; + goto err; } val = dsi_read_reg(DSI_VC_SHORT_PACKET_HEADER(channel)); @@ -2134,15 +2141,18 @@ int dsi_vc_dcs_read(int channel, u8 dcs_cmd, u8 *buf, int buflen) if (dt == DSI_DT_RX_ACK_WITH_ERR) { u16 err = FLD_GET(val, 23, 8); dsi_show_rx_ack_with_err(err); - return -EIO; + r = -EIO; + goto err; } else if (dt == DSI_DT_RX_SHORT_READ_1) { u8 data = FLD_GET(val, 15, 8); if (dsi.debug_read) DSSDBG("\tDCS short response, 1 byte: %02x\n", data); - if (buflen < 1) - return -EIO; + if (buflen < 1) { + r = -EIO; + goto err; + } buf[0] = data; @@ -2152,8 +2162,10 @@ int dsi_vc_dcs_read(int channel, u8 dcs_cmd, u8 *buf, int buflen) if (dsi.debug_read) DSSDBG("\tDCS short response, 2 byte: %04x\n", data); - if (buflen < 2) - return -EIO; + if (buflen < 2) { + r = -EIO; + goto err; + } buf[0] = data & 0xff; buf[1] = (data >> 8) & 0xff; @@ -2165,8 +2177,10 @@ int dsi_vc_dcs_read(int channel, u8 dcs_cmd, u8 *buf, int buflen) if (dsi.debug_read) DSSDBG("\tDCS long response, len %d\n", len); - if (len > buflen) - return -EIO; + if (len > buflen) { + r = -EIO; + goto err; + } /* two byte checksum ends the packet, not included in len */ for (w = 0; w < len + 2;) { @@ -2188,11 +2202,18 @@ int dsi_vc_dcs_read(int channel, u8 dcs_cmd, u8 *buf, int buflen) } return len; - } else { DSSERR("\tunknown datatype 0x%02x\n", dt); - return -EIO; + r = -EIO; + goto err; } + + BUG(); +err: + DSSERR("dsi_vc_dcs_read(ch %d, cmd 0x%02x) failed\n", + channel, dcs_cmd); + return r; + } EXPORT_SYMBOL(dsi_vc_dcs_read); -- cgit v1.2.2 From 3119815912a220bdac943dfbdfee640414c0c611 Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Thu, 25 Feb 2010 19:08:55 +0200 Subject: virtio: fix out of range array access I have observed the following error on virtio-net module unload: ------------[ cut here ]------------ WARNING: at kernel/irq/manage.c:858 __free_irq+0xa0/0x14c() Hardware name: Bochs Trying to free already-free IRQ 0 Modules linked in: virtio_net(-) virtio_blk virtio_pci virtio_ring virtio af_packet e1000 shpchp aacraid uhci_hcd ohci_hcd ehci_hcd [last unloaded: scsi_wait_scan] Pid: 1957, comm: rmmod Not tainted 2.6.33-rc8-vhost #24 Call Trace: [] warn_slowpath_common+0x7c/0x94 [] warn_slowpath_fmt+0x41/0x43 [] ? __free_pages+0x5a/0x70 [] __free_irq+0xa0/0x14c [] free_irq+0x3f/0x65 [] vp_del_vqs+0x81/0xb1 [virtio_pci] [] virtnet_remove+0xda/0x10b [virtio_net] [] virtio_dev_remove+0x22/0x4a [virtio] [] __device_release_driver+0x66/0xac [] driver_detach+0x83/0xa9 [] bus_remove_driver+0x91/0xb4 [] driver_unregister+0x6c/0x74 [] unregister_virtio_driver+0xe/0x10 [virtio] [] fini+0x15/0x17 [virtio_net] [] sys_delete_module+0x1c3/0x230 [] ? old_ich_force_enable_hpet+0x117/0x164 [] ? do_page_fault+0x29c/0x2cc [] sysenter_dispatch+0x7/0x27 ---[ end trace 15e88e4c576cc62b ]--- The bug is in virtio-pci: we use msix_vector as array index to get irq entry, but some vqs do not have a dedicated vector so this causes an out of bounds access. By chance, we seem to often get 0 value, which results in this error. Fix by verifying that vector is legal before using it as index. Signed-off-by: Michael S. Tsirkin Acked-by: Anthony Liguori Acked-by: Shirley Ma Acked-by: Amit Shah --- drivers/virtio/virtio_pci.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/virtio/virtio_pci.c b/drivers/virtio/virtio_pci.c index 1d5191fab62e..1b6573216998 100644 --- a/drivers/virtio/virtio_pci.c +++ b/drivers/virtio/virtio_pci.c @@ -473,7 +473,8 @@ static void vp_del_vqs(struct virtio_device *vdev) list_for_each_entry_safe(vq, n, &vdev->vqs, list) { info = vq->priv; - if (vp_dev->per_vq_vectors) + if (vp_dev->per_vq_vectors && + info->msix_vector != VIRTIO_MSI_NO_VECTOR) free_irq(vp_dev->msix_entries[info->msix_vector].vector, vq); vp_del_vq(vq); -- cgit v1.2.2 From 58daa9ce96b847ed130453f5fdd63c579fb1f84f Mon Sep 17 00:00:00 2001 From: "Stephen M. Cameron" Date: Fri, 26 Feb 2010 16:01:12 -0600 Subject: cciss: clarify command list padding calculation cciss: clarify command list padding calculation Signed-off-by: Stephen M. Cameron Signed-off-by: Jens Axboe --- drivers/block/cciss_cmd.h | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/block/cciss_cmd.h b/drivers/block/cciss_cmd.h index 25f97623bacf..515c9f03c201 100644 --- a/drivers/block/cciss_cmd.h +++ b/drivers/block/cciss_cmd.h @@ -168,9 +168,14 @@ typedef struct _SGDescriptor_struct { #define CMD_MSG_STALE 0xff /* This structure needs to be divisible by 8 for new - * indexing method. + * indexing method. PAD_32 and PAD_64 can be adjusted + * independently as needed for 32-bit and 64-bits systems. */ -#define PADSIZE (sizeof(long) - 4) +#define IS_64_BIT ((sizeof(long) - 4)/4) +#define IS_32_BIT (!IS_64_BIT) +#define PAD_32 (0) +#define PAD_64 (4) +#define PADSIZE (IS_32_BIT * PAD_32 + IS_64_BIT * PAD_64) typedef struct _CommandList_struct { CommandListHeader_struct Header; RequestBlock_struct Request; -- cgit v1.2.2 From 1b7d0d28ad82cbd5650c26ec8e370176b112e407 Mon Sep 17 00:00:00 2001 From: "Stephen M. Cameron" Date: Fri, 26 Feb 2010 16:01:17 -0600 Subject: cciss: detect bad alignment of scsi commands at build time cciss: detect bad alignment of scsi commands at build time Incidentally fix some nearby c++ style comments. Signed-off-by: Stephen M. Cameron Signed-off-by: Jens Axboe --- drivers/block/cciss.c | 2 +- drivers/block/cciss_cmd.h | 9 ++++++--- drivers/block/cciss_scsi.c | 12 ++++++++---- 3 files changed, 15 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c index a29e69418a03..cd8c7c20b1c3 100644 --- a/drivers/block/cciss.c +++ b/drivers/block/cciss.c @@ -4496,7 +4496,7 @@ static int __init cciss_init(void) * boundary. Given that we use pci_alloc_consistent() to allocate an * array of them, the size must be a multiple of 8 bytes. */ - BUILD_BUG_ON(sizeof(CommandList_struct) % 8); + BUILD_BUG_ON(sizeof(CommandList_struct) % COMMANDLIST_ALIGNMENT); printk(KERN_INFO DRIVER_NAME "\n"); diff --git a/drivers/block/cciss_cmd.h b/drivers/block/cciss_cmd.h index 515c9f03c201..e624ff959cb6 100644 --- a/drivers/block/cciss_cmd.h +++ b/drivers/block/cciss_cmd.h @@ -167,10 +167,13 @@ typedef struct _SGDescriptor_struct { #define CMD_MSG_TIMEOUT 0x05 #define CMD_MSG_STALE 0xff -/* This structure needs to be divisible by 8 for new - * indexing method. PAD_32 and PAD_64 can be adjusted - * independently as needed for 32-bit and 64-bits systems. +/* This structure needs to be divisible by COMMANDLIST_ALIGNMENT + * because low bits of the address are used to to indicate that + * whether the tag contains an index or an address. PAD_32 and + * PAD_64 can be adjusted independently as needed for 32-bit + * and 64-bits systems. */ +#define COMMANDLIST_ALIGNMENT (8) #define IS_64_BIT ((sizeof(long) - 4)/4) #define IS_32_BIT (!IS_64_BIT) #define PAD_32 (0) diff --git a/drivers/block/cciss_scsi.c b/drivers/block/cciss_scsi.c index 5d0e46dc3632..f203606faaff 100644 --- a/drivers/block/cciss_scsi.c +++ b/drivers/block/cciss_scsi.c @@ -93,11 +93,15 @@ static struct scsi_host_template cciss_driver_template = { }; #pragma pack(1) + +#define SCSI_PAD_32 4 +#define SCSI_PAD_64 4 + struct cciss_scsi_cmd_stack_elem_t { CommandList_struct cmd; ErrorInfo_struct Err; __u32 busaddr; - __u32 pad; + u8 pad[IS_32_BIT * SCSI_PAD_32 + IS_64_BIT * SCSI_PAD_64]; }; #pragma pack() @@ -202,9 +206,9 @@ scsi_cmd_stack_setup(int ctlr, struct cciss_scsi_adapter_data_t *sa) stk = &sa->cmd_stack; size = sizeof(struct cciss_scsi_cmd_stack_elem_t) * CMD_STACK_SIZE; - // pci_alloc_consistent guarantees 32-bit DMA address will - // be used - + /* Check alignment, see cciss_cmd.h near CommandList_struct def. */ + BUILD_BUG_ON((sizeof(*stk->pool) % COMMANDLIST_ALIGNMENT) != 0); + /* pci_alloc_consistent guarantees 32-bit DMA address will be used */ stk->pool = (struct cciss_scsi_cmd_stack_elem_t *) pci_alloc_consistent(hba[ctlr]->pdev, size, &stk->cmd_pool_handle); -- cgit v1.2.2 From 49fc5601ea3bf9625d699dc777f80f72e8126c0b Mon Sep 17 00:00:00 2001 From: "Stephen M. Cameron" Date: Fri, 26 Feb 2010 16:01:22 -0600 Subject: cciss: factor out scatter gather chain block allocation and freeing cciss: factor out scatter gather chain block allocation and freeing Rationale is that I want to use this code from the scsi half of the driver. Signed-off-by: Stephen M. Cameron Signed-off-by: Jens Axboe --- drivers/block/cciss.c | 108 +++++++++++++++++++++++++++----------------------- 1 file changed, 58 insertions(+), 50 deletions(-) (limited to 'drivers') diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c index cd8c7c20b1c3..eddb916d2908 100644 --- a/drivers/block/cciss.c +++ b/drivers/block/cciss.c @@ -257,6 +257,59 @@ static inline void removeQ(CommandList_struct *c) hlist_del_init(&c->list); } +static void cciss_free_sg_chain_blocks(struct Cmd_sg_list **cmd_sg_list, + int nr_cmds) +{ + int i; + + if (!cmd_sg_list) + return; + for (i = 0; i < nr_cmds; i++) { + if (cmd_sg_list[i]) { + kfree(cmd_sg_list[i]->sgchain); + kfree(cmd_sg_list[i]); + cmd_sg_list[i] = NULL; + } + } + kfree(cmd_sg_list); +} + +static struct Cmd_sg_list **cciss_allocate_sg_chain_blocks(ctlr_info_t *h, + int chainsize, int nr_cmds) +{ + int j; + struct Cmd_sg_list **cmd_sg_list; + + if (chainsize <= 0) + return NULL; + + cmd_sg_list = kmalloc(sizeof(*cmd_sg_list) * nr_cmds, GFP_KERNEL); + if (!cmd_sg_list) + return NULL; + + /* Build up chain blocks for each command */ + for (j = 0; j < nr_cmds; j++) { + cmd_sg_list[j] = kmalloc(sizeof(*cmd_sg_list[j]), GFP_KERNEL); + if (!cmd_sg_list[j]) { + dev_err(&h->pdev->dev, "Cannot get memory " + "for chain block.\n"); + goto clean; + } + /* Need a block of chainsized s/g elements. */ + cmd_sg_list[j]->sgchain = kmalloc((chainsize * + sizeof(SGDescriptor_struct)), GFP_KERNEL); + if (!cmd_sg_list[j]->sgchain) { + dev_err(&h->pdev->dev, "Cannot get memory " + "for s/g chains.\n"); + goto clean; + } + } + return cmd_sg_list; +clean: + cciss_free_sg_chain_blocks(cmd_sg_list, nr_cmds); + return NULL; +} + #include "cciss_scsi.c" /* For SCSI tape support */ static const char *raid_label[] = { "0", "4", "1(1+0)", "5", "5+1", "ADG", @@ -4238,37 +4291,10 @@ static int __devinit cciss_init_one(struct pci_dev *pdev, goto clean4; } } - hba[i]->cmd_sg_list = kmalloc(sizeof(struct Cmd_sg_list *) * - hba[i]->nr_cmds, - GFP_KERNEL); - if (!hba[i]->cmd_sg_list) { - printk(KERN_ERR "cciss%d: Cannot get memory for " - "s/g chaining.\n", i); + hba[i]->cmd_sg_list = cciss_allocate_sg_chain_blocks(hba[i], + hba[i]->chainsize, hba[i]->nr_cmds); + if (!hba[i]->cmd_sg_list && hba[i]->chainsize > 0) goto clean4; - } - /* Build up chain blocks for each command */ - if (hba[i]->chainsize > 0) { - for (j = 0; j < hba[i]->nr_cmds; j++) { - hba[i]->cmd_sg_list[j] = - kmalloc(sizeof(struct Cmd_sg_list), - GFP_KERNEL); - if (!hba[i]->cmd_sg_list[j]) { - printk(KERN_ERR "cciss%d: Cannot get memory " - "for chain block.\n", i); - goto clean4; - } - /* Need a block of chainsized s/g elements. */ - hba[i]->cmd_sg_list[j]->sgchain = - kmalloc((hba[i]->chainsize * - sizeof(SGDescriptor_struct)), - GFP_KERNEL); - if (!hba[i]->cmd_sg_list[j]->sgchain) { - printk(KERN_ERR "cciss%d: Cannot get memory " - "for s/g chains\n", i); - goto clean4; - } - } - } spin_lock_init(&hba[i]->lock); @@ -4327,16 +4353,7 @@ clean4: for (k = 0; k < hba[i]->nr_cmds; k++) kfree(hba[i]->scatter_list[k]); kfree(hba[i]->scatter_list); - /* Only free up extra s/g lists if controller supports them */ - if (hba[i]->chainsize > 0) { - for (j = 0; j < hba[i]->nr_cmds; j++) { - if (hba[i]->cmd_sg_list[j]) { - kfree(hba[i]->cmd_sg_list[j]->sgchain); - kfree(hba[i]->cmd_sg_list[j]); - } - } - kfree(hba[i]->cmd_sg_list); - } + cciss_free_sg_chain_blocks(hba[i]->cmd_sg_list, hba[i]->nr_cmds); if (hba[i]->cmd_pool) pci_free_consistent(hba[i]->pdev, hba[i]->nr_cmds * sizeof(CommandList_struct), @@ -4454,16 +4471,7 @@ static void __devexit cciss_remove_one(struct pci_dev *pdev) for (j = 0; j < hba[i]->nr_cmds; j++) kfree(hba[i]->scatter_list[j]); kfree(hba[i]->scatter_list); - /* Only free up extra s/g lists if controller supports them */ - if (hba[i]->chainsize > 0) { - for (j = 0; j < hba[i]->nr_cmds; j++) { - if (hba[i]->cmd_sg_list[j]) { - kfree(hba[i]->cmd_sg_list[j]->sgchain); - kfree(hba[i]->cmd_sg_list[j]); - } - } - kfree(hba[i]->cmd_sg_list); - } + cciss_free_sg_chain_blocks(hba[i]->cmd_sg_list, hba[i]->nr_cmds); /* * Deliberately omit pci_disable_device(): it does something nasty to * Smart Array controllers that pci_enable_device does not undo -- cgit v1.2.2 From dccc9b563e455b91f7247b1ca6b0face40323538 Mon Sep 17 00:00:00 2001 From: "Stephen M. Cameron" Date: Fri, 26 Feb 2010 16:01:27 -0600 Subject: cciss: simplify scatter gather code cciss: simplify scatter gather code. Instead of allocating an array of pointers to a structure containing an SGDescriptor structure, and two other elements that aren't really used, just allocate SGDescriptor structs. Signed-off-by: Stephen M. Cameron Signed-off-by: Jens Axboe --- drivers/block/cciss.c | 43 +++++++++++++++---------------------------- drivers/block/cciss.h | 8 +------- 2 files changed, 16 insertions(+), 35 deletions(-) (limited to 'drivers') diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c index eddb916d2908..adc517c1381c 100644 --- a/drivers/block/cciss.c +++ b/drivers/block/cciss.c @@ -257,7 +257,7 @@ static inline void removeQ(CommandList_struct *c) hlist_del_init(&c->list); } -static void cciss_free_sg_chain_blocks(struct Cmd_sg_list **cmd_sg_list, +static void cciss_free_sg_chain_blocks(SGDescriptor_struct **cmd_sg_list, int nr_cmds) { int i; @@ -265,20 +265,17 @@ static void cciss_free_sg_chain_blocks(struct Cmd_sg_list **cmd_sg_list, if (!cmd_sg_list) return; for (i = 0; i < nr_cmds; i++) { - if (cmd_sg_list[i]) { - kfree(cmd_sg_list[i]->sgchain); - kfree(cmd_sg_list[i]); - cmd_sg_list[i] = NULL; - } + kfree(cmd_sg_list[i]); + cmd_sg_list[i] = NULL; } kfree(cmd_sg_list); } -static struct Cmd_sg_list **cciss_allocate_sg_chain_blocks(ctlr_info_t *h, - int chainsize, int nr_cmds) +static SGDescriptor_struct **cciss_allocate_sg_chain_blocks( + ctlr_info_t *h, int chainsize, int nr_cmds) { int j; - struct Cmd_sg_list **cmd_sg_list; + SGDescriptor_struct **cmd_sg_list; if (chainsize <= 0) return NULL; @@ -289,16 +286,10 @@ static struct Cmd_sg_list **cciss_allocate_sg_chain_blocks(ctlr_info_t *h, /* Build up chain blocks for each command */ for (j = 0; j < nr_cmds; j++) { - cmd_sg_list[j] = kmalloc(sizeof(*cmd_sg_list[j]), GFP_KERNEL); - if (!cmd_sg_list[j]) { - dev_err(&h->pdev->dev, "Cannot get memory " - "for chain block.\n"); - goto clean; - } /* Need a block of chainsized s/g elements. */ - cmd_sg_list[j]->sgchain = kmalloc((chainsize * - sizeof(SGDescriptor_struct)), GFP_KERNEL); - if (!cmd_sg_list[j]->sgchain) { + cmd_sg_list[j] = kmalloc((chainsize * + sizeof(*cmd_sg_list[j])), GFP_KERNEL); + if (!cmd_sg_list[j]) { dev_err(&h->pdev->dev, "Cannot get memory " "for s/g chains.\n"); goto clean; @@ -1731,7 +1722,7 @@ static void cciss_softirq_done(struct request *rq) pci_unmap_single(h->pdev, temp64.val, cmd->SG[i].Len, ddir); /* Point to the next block */ - curr_sg = h->cmd_sg_list[cmd->cmdindex]->sgchain; + curr_sg = h->cmd_sg_list[cmd->cmdindex]; sg_index = 0; } temp64.val32.lower = curr_sg[sg_index].Addr.lower; @@ -3206,7 +3197,7 @@ static void do_cciss_request(struct request_queue *q) curr_sg[sg_index].Ext = CCISS_SG_CHAIN; /* Point to next chain block. */ - curr_sg = h->cmd_sg_list[c->cmdindex]->sgchain; + curr_sg = h->cmd_sg_list[c->cmdindex]; sg_index = 0; chained = 1; } @@ -3223,6 +3214,7 @@ static void do_cciss_request(struct request_queue *q) if (chained) { int len; + dma_addr_t dma_addr; curr_sg = c->SG; sg_index = h->max_cmd_sgentries - 1; len = curr_sg[sg_index].Len; @@ -3231,16 +3223,11 @@ static void do_cciss_request(struct request_queue *q) * block with address of next chain block. */ temp64.val = pci_map_single(h->pdev, - h->cmd_sg_list[c->cmdindex]->sgchain, - len, dir); - - h->cmd_sg_list[c->cmdindex]->sg_chain_dma = temp64.val; + h->cmd_sg_list[c->cmdindex], len, dir); + dma_addr = temp64.val; curr_sg[sg_index].Addr.lower = temp64.val32.lower; curr_sg[sg_index].Addr.upper = temp64.val32.upper; - - pci_dma_sync_single_for_device(h->pdev, - h->cmd_sg_list[c->cmdindex]->sg_chain_dma, - len, dir); + pci_dma_sync_single_for_device(h->pdev, dma_addr, len, dir); } /* track how many SG entries we are using */ diff --git a/drivers/block/cciss.h b/drivers/block/cciss.h index 2b07bdacbd12..ac454fdd4d30 100644 --- a/drivers/block/cciss.h +++ b/drivers/block/cciss.h @@ -55,12 +55,6 @@ typedef struct _drive_info_struct char device_initialized; /* indicates whether dev is initialized */ } drive_info_struct; -struct Cmd_sg_list { - SGDescriptor_struct *sgchain; - dma_addr_t sg_chain_dma; - int chain_block_size; -}; - struct ctlr_info { int ctlr; @@ -89,7 +83,7 @@ struct ctlr_info int maxsgentries; int chainsize; int max_cmd_sgentries; - struct Cmd_sg_list **cmd_sg_list; + SGDescriptor_struct **cmd_sg_list; # define DOORBELL_INT 0 # define PERF_MODE_INT 1 -- cgit v1.2.2 From 2ad6cdc20fbeea1e1744190c00cebb64e4b4c491 Mon Sep 17 00:00:00 2001 From: "Stephen M. Cameron" Date: Fri, 26 Feb 2010 16:01:32 -0600 Subject: cciss: fix scatter gather chain block dma direction kludge cciss: fix scatter gather chain block dma direction kludge The data direction for the chained block of scatter gather elements should always be PCI_DMA_TODEVICE, but was mistakenly set to the direction of the data transfer, then a kludge to fix it was added, in which pci_dma_sync_single_for_device or pci_dma_sync_single_for_cpu was called. If the correct direction is used in the first place, the kludge isn't needed. Signed-off-by: Stephen M. Cameron Signed-off-by: Jens Axboe --- drivers/block/cciss.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c index adc517c1381c..c0d794ce69c6 100644 --- a/drivers/block/cciss.c +++ b/drivers/block/cciss.c @@ -1717,10 +1717,8 @@ static void cciss_softirq_done(struct request *rq) if (curr_sg[sg_index].Ext == CCISS_SG_CHAIN) { temp64.val32.lower = cmd->SG[i].Addr.lower; temp64.val32.upper = cmd->SG[i].Addr.upper; - pci_dma_sync_single_for_cpu(h->pdev, temp64.val, - cmd->SG[i].Len, ddir); pci_unmap_single(h->pdev, temp64.val, - cmd->SG[i].Len, ddir); + cmd->SG[i].Len, PCI_DMA_TODEVICE); /* Point to the next block */ curr_sg = h->cmd_sg_list[cmd->cmdindex]; sg_index = 0; @@ -3223,11 +3221,11 @@ static void do_cciss_request(struct request_queue *q) * block with address of next chain block. */ temp64.val = pci_map_single(h->pdev, - h->cmd_sg_list[c->cmdindex], len, dir); + h->cmd_sg_list[c->cmdindex], len, + PCI_DMA_TODEVICE); dma_addr = temp64.val; curr_sg[sg_index].Addr.lower = temp64.val32.lower; curr_sg[sg_index].Addr.upper = temp64.val32.upper; - pci_dma_sync_single_for_device(h->pdev, dma_addr, len, dir); } /* track how many SG entries we are using */ -- cgit v1.2.2 From d45033ef56fa9b09b73a6eb2a0f280fa7c1bab09 Mon Sep 17 00:00:00 2001 From: "Stephen M. Cameron" Date: Fri, 26 Feb 2010 16:01:37 -0600 Subject: cciss: factor out scatter gather chain block mapping code cciss: factor out scatter gather chain block mapping code Rationale is I want to use this code from the scsi half of the driver. Signed-off-by: Stephen M. Cameron Signed-off-by: Jens Axboe --- drivers/block/cciss.c | 63 +++++++++++++++++++++++++++------------------------ 1 file changed, 34 insertions(+), 29 deletions(-) (limited to 'drivers') diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c index c0d794ce69c6..9e3af307aae1 100644 --- a/drivers/block/cciss.c +++ b/drivers/block/cciss.c @@ -301,6 +301,35 @@ clean: return NULL; } +static void cciss_unmap_sg_chain_block(ctlr_info_t *h, CommandList_struct *c) +{ + SGDescriptor_struct *chain_sg; + u64bit temp64; + + if (c->Header.SGTotal <= h->max_cmd_sgentries) + return; + + chain_sg = &c->SG[h->max_cmd_sgentries - 1]; + temp64.val32.lower = chain_sg->Addr.lower; + temp64.val32.upper = chain_sg->Addr.upper; + pci_unmap_single(h->pdev, temp64.val, chain_sg->Len, PCI_DMA_TODEVICE); +} + +static void cciss_map_sg_chain_block(ctlr_info_t *h, CommandList_struct *c, + SGDescriptor_struct *chain_block, int len) +{ + SGDescriptor_struct *chain_sg; + u64bit temp64; + + chain_sg = &c->SG[h->max_cmd_sgentries - 1]; + chain_sg->Ext = CCISS_SG_CHAIN; + chain_sg->Len = len; + temp64.val = pci_map_single(h->pdev, chain_block, len, + PCI_DMA_TODEVICE); + chain_sg->Addr.lower = temp64.val32.lower; + chain_sg->Addr.upper = temp64.val32.upper; +} + #include "cciss_scsi.c" /* For SCSI tape support */ static const char *raid_label[] = { "0", "4", "1(1+0)", "5", "5+1", "ADG", @@ -1715,10 +1744,7 @@ static void cciss_softirq_done(struct request *rq) /* unmap the DMA mapping for all the scatter gather elements */ for (i = 0; i < cmd->Header.SGList; i++) { if (curr_sg[sg_index].Ext == CCISS_SG_CHAIN) { - temp64.val32.lower = cmd->SG[i].Addr.lower; - temp64.val32.upper = cmd->SG[i].Addr.upper; - pci_unmap_single(h->pdev, temp64.val, - cmd->SG[i].Len, PCI_DMA_TODEVICE); + cciss_unmap_sg_chain_block(h, cmd); /* Point to the next block */ curr_sg = h->cmd_sg_list[cmd->cmdindex]; sg_index = 0; @@ -3122,7 +3148,6 @@ static void do_cciss_request(struct request_queue *q) SGDescriptor_struct *curr_sg; drive_info_struct *drv; int i, dir; - int nseg = 0; int sg_index = 0; int chained = 0; @@ -3189,11 +3214,6 @@ static void do_cciss_request(struct request_queue *q) for (i = 0; i < seg; i++) { if (((sg_index+1) == (h->max_cmd_sgentries)) && !chained && ((seg - i) > 1)) { - nseg = seg - i; - curr_sg[sg_index].Len = (nseg) * - sizeof(SGDescriptor_struct); - curr_sg[sg_index].Ext = CCISS_SG_CHAIN; - /* Point to next chain block. */ curr_sg = h->cmd_sg_list[c->cmdindex]; sg_index = 0; @@ -3206,27 +3226,12 @@ static void do_cciss_request(struct request_queue *q) curr_sg[sg_index].Addr.lower = temp64.val32.lower; curr_sg[sg_index].Addr.upper = temp64.val32.upper; curr_sg[sg_index].Ext = 0; /* we are not chaining */ - ++sg_index; } - - if (chained) { - int len; - dma_addr_t dma_addr; - curr_sg = c->SG; - sg_index = h->max_cmd_sgentries - 1; - len = curr_sg[sg_index].Len; - /* Setup pointer to next chain block. - * Fill out last element in current chain - * block with address of next chain block. - */ - temp64.val = pci_map_single(h->pdev, - h->cmd_sg_list[c->cmdindex], len, - PCI_DMA_TODEVICE); - dma_addr = temp64.val; - curr_sg[sg_index].Addr.lower = temp64.val32.lower; - curr_sg[sg_index].Addr.upper = temp64.val32.upper; - } + if (chained) + cciss_map_sg_chain_block(h, c, h->cmd_sg_list[c->cmdindex], + (seg - (h->max_cmd_sgentries - 1)) * + sizeof(SGDescriptor_struct)); /* track how many SG entries we are using */ if (seg > h->maxSG) -- cgit v1.2.2 From aad9fb6f2c5beafe76a724c90a4bd0d695ab8b42 Mon Sep 17 00:00:00 2001 From: "Stephen M. Cameron" Date: Fri, 26 Feb 2010 16:01:42 -0600 Subject: cciss: do not use void pointer for scsi hba data cciss: do not use void pointer for scsi hba data and get rid of related unnecessary type casting and delete some superfluous and misleading comments nearby. Signed-off-by: Stephen M. Cameron Signed-off-by: Jens Axboe --- drivers/block/cciss.h | 4 +--- drivers/block/cciss_scsi.c | 23 ++++++++++------------- 2 files changed, 11 insertions(+), 16 deletions(-) (limited to 'drivers') diff --git a/drivers/block/cciss.h b/drivers/block/cciss.h index ac454fdd4d30..c5d411174db0 100644 --- a/drivers/block/cciss.h +++ b/drivers/block/cciss.h @@ -131,9 +131,7 @@ struct ctlr_info /* Disk structures we need to pass back */ struct gendisk *gendisk[CISS_MAX_LUN]; #ifdef CONFIG_CISS_SCSI_TAPE - void *scsi_ctlr; /* ptr to structure containing scsi related stuff */ - /* list of block side commands the scsi error handling sucked up */ - /* and saved for later processing */ + struct cciss_scsi_adapter_data_t *scsi_ctlr; #endif unsigned char alive; struct list_head scan_list; diff --git a/drivers/block/cciss_scsi.c b/drivers/block/cciss_scsi.c index f203606faaff..c4582323a07d 100644 --- a/drivers/block/cciss_scsi.c +++ b/drivers/block/cciss_scsi.c @@ -127,11 +127,9 @@ struct cciss_scsi_adapter_data_t { }; #define CPQ_TAPE_LOCK(ctlr, flags) spin_lock_irqsave( \ - &(((struct cciss_scsi_adapter_data_t *) \ - hba[ctlr]->scsi_ctlr)->lock), flags); + &hba[ctlr]->scsi_ctlr->lock, flags); #define CPQ_TAPE_UNLOCK(ctlr, flags) spin_unlock_irqrestore( \ - &(((struct cciss_scsi_adapter_data_t *) \ - hba[ctlr]->scsi_ctlr)->lock), flags); + &hba[ctlr]->scsi_ctlr->lock, flags); static CommandList_struct * scsi_cmd_alloc(ctlr_info_t *h) @@ -147,7 +145,7 @@ scsi_cmd_alloc(ctlr_info_t *h) struct cciss_scsi_cmd_stack_t *stk; u64bit temp64; - sa = (struct cciss_scsi_adapter_data_t *) h->scsi_ctlr; + sa = h->scsi_ctlr; stk = &sa->cmd_stack; if (stk->top < 0) @@ -186,7 +184,7 @@ scsi_cmd_free(ctlr_info_t *h, CommandList_struct *cmd) struct cciss_scsi_adapter_data_t *sa; struct cciss_scsi_cmd_stack_t *stk; - sa = (struct cciss_scsi_adapter_data_t *) h->scsi_ctlr; + sa = h->scsi_ctlr; stk = &sa->cmd_stack; if (stk->top >= CMD_STACK_SIZE) { printk("cciss: scsi_cmd_free called too many times.\n"); @@ -233,7 +231,7 @@ scsi_cmd_stack_free(int ctlr) struct cciss_scsi_cmd_stack_t *stk; size_t size; - sa = (struct cciss_scsi_adapter_data_t *) hba[ctlr]->scsi_ctlr; + sa = hba[ctlr]->scsi_ctlr; stk = &sa->cmd_stack; if (stk->top != CMD_STACK_SIZE-1) { printk( "cciss: %d scsi commands are still outstanding.\n", @@ -534,8 +532,7 @@ adjust_cciss_scsi_table(int ctlr, int hostno, CPQ_TAPE_LOCK(ctlr, flags); if (hostno != -1) /* if it's not the first time... */ - sh = ((struct cciss_scsi_adapter_data_t *) - hba[ctlr]->scsi_ctlr)->scsi_host; + sh = hba[ctlr]->scsi_ctlr->scsi_host; /* find any devices in ccissscsi[] that are not in sd[] and remove them from ccissscsi[] */ @@ -706,7 +703,7 @@ cciss_scsi_setup(int cntl_num) kfree(shba); shba = NULL; } - hba[cntl_num]->scsi_ctlr = (void *) shba; + hba[cntl_num]->scsi_ctlr = shba; return; } @@ -853,7 +850,7 @@ cciss_scsi_detect(int ctlr) sh->this_id = SELF_SCSI_ID; ((struct cciss_scsi_adapter_data_t *) - hba[ctlr]->scsi_ctlr)->scsi_host = (void *) sh; + hba[ctlr]->scsi_ctlr)->scsi_host = sh; sh->hostdata[0] = (unsigned long) hba[ctlr]; sh->irq = hba[ctlr]->intr[SIMPLE_MODE_INT]; sh->unique_id = sh->irq; @@ -1518,7 +1515,7 @@ cciss_unregister_scsi(int ctlr) /* we are being forcibly unloaded, and may not refuse. */ spin_lock_irqsave(CCISS_LOCK(ctlr), flags); - sa = (struct cciss_scsi_adapter_data_t *) hba[ctlr]->scsi_ctlr; + sa = hba[ctlr]->scsi_ctlr; stk = &sa->cmd_stack; /* if we weren't ever actually registered, don't unregister */ @@ -1545,7 +1542,7 @@ cciss_engage_scsi(int ctlr) unsigned long flags; spin_lock_irqsave(CCISS_LOCK(ctlr), flags); - sa = (struct cciss_scsi_adapter_data_t *) hba[ctlr]->scsi_ctlr; + sa = hba[ctlr]->scsi_ctlr; stk = &sa->cmd_stack; if (sa->registered) { -- cgit v1.2.2 From bf8873781831c7799255e0932848401070185dd0 Mon Sep 17 00:00:00 2001 From: "Stephen M. Cameron" Date: Fri, 26 Feb 2010 16:01:47 -0600 Subject: cciss: eliminate unnecessary pointer use in cciss scsi code cciss: eliminate unnecessary pointer use in cciss scsi code An extra level of indirection was being used in some places for no real reason. Signed-off-by: Stephen M. Cameron Signed-off-by: Jens Axboe --- drivers/block/cciss_scsi.c | 31 +++++++++++++++---------------- 1 file changed, 15 insertions(+), 16 deletions(-) (limited to 'drivers') diff --git a/drivers/block/cciss_scsi.c b/drivers/block/cciss_scsi.c index c4582323a07d..6dc15b669694 100644 --- a/drivers/block/cciss_scsi.c +++ b/drivers/block/cciss_scsi.c @@ -1400,7 +1400,7 @@ cciss_scatter_gather(struct pci_dev *pdev, static int cciss_scsi_queue_command (struct scsi_cmnd *cmd, void (* done)(struct scsi_cmnd *)) { - ctlr_info_t **c; + ctlr_info_t *c; int ctlr, rc; unsigned char scsi3addr[8]; CommandList_struct *cp; @@ -1408,8 +1408,8 @@ cciss_scsi_queue_command (struct scsi_cmnd *cmd, void (* done)(struct scsi_cmnd // Get the ptr to our adapter structure (hba[i]) out of cmd->host. // We violate cmd->host privacy here. (Is there another way?) - c = (ctlr_info_t **) &cmd->device->host->hostdata[0]; - ctlr = (*c)->ctlr; + c = (ctlr_info_t *) cmd->device->host->hostdata[0]; + ctlr = c->ctlr; rc = lookup_scsi3addr(ctlr, cmd->device->channel, cmd->device->id, cmd->device->lun, scsi3addr); @@ -1432,7 +1432,7 @@ cciss_scsi_queue_command (struct scsi_cmnd *cmd, void (* done)(struct scsi_cmnd see what the device thinks of it. */ spin_lock_irqsave(CCISS_LOCK(ctlr), flags); - cp = scsi_cmd_alloc(*c); + cp = scsi_cmd_alloc(c); spin_unlock_irqrestore(CCISS_LOCK(ctlr), flags); if (cp == NULL) { /* trouble... */ printk("scsi_cmd_alloc returned NULL!\n"); @@ -1490,15 +1490,14 @@ cciss_scsi_queue_command (struct scsi_cmnd *cmd, void (* done)(struct scsi_cmnd BUG(); break; } - - cciss_scatter_gather((*c)->pdev, cp, cmd); // Fill the SG list + cciss_scatter_gather(c->pdev, cp, cmd); /* Put the request on the tail of the request queue */ spin_lock_irqsave(CCISS_LOCK(ctlr), flags); - addQ(&(*c)->reqQ, cp); - (*c)->Qdepth++; - start_io(*c); + addQ(&c->reqQ, cp); + c->Qdepth++; + start_io(c); spin_unlock_irqrestore(CCISS_LOCK(ctlr), flags); /* the cmd'll come back via intr handler in complete_scsi_command() */ @@ -1655,14 +1654,14 @@ static int cciss_eh_device_reset_handler(struct scsi_cmnd *scsicmd) int rc; CommandList_struct *cmd_in_trouble; unsigned char lunaddr[8]; - ctlr_info_t **c; + ctlr_info_t *c; int ctlr; /* find the controller to which the command to be aborted was sent */ - c = (ctlr_info_t **) &scsicmd->device->host->hostdata[0]; + c = (ctlr_info_t *) scsicmd->device->host->hostdata[0]; if (c == NULL) /* paranoia */ return FAILED; - ctlr = (*c)->ctlr; + ctlr = c->ctlr; printk(KERN_WARNING "cciss%d: resetting tape drive or medium changer.\n", ctlr); /* find the command that's giving us trouble */ cmd_in_trouble = (CommandList_struct *) scsicmd->host_scribble; @@ -1672,7 +1671,7 @@ static int cciss_eh_device_reset_handler(struct scsi_cmnd *scsicmd) /* send a reset to the SCSI LUN which the command was sent to */ rc = sendcmd_withirq(CCISS_RESET_MSG, ctlr, NULL, 0, 0, lunaddr, TYPE_MSG); - if (rc == 0 && wait_for_device_to_become_ready(*c, lunaddr) == 0) + if (rc == 0 && wait_for_device_to_become_ready(c, lunaddr) == 0) return SUCCESS; printk(KERN_WARNING "cciss%d: resetting device failed.\n", ctlr); return FAILED; @@ -1683,14 +1682,14 @@ static int cciss_eh_abort_handler(struct scsi_cmnd *scsicmd) int rc; CommandList_struct *cmd_to_abort; unsigned char lunaddr[8]; - ctlr_info_t **c; + ctlr_info_t *c; int ctlr; /* find the controller to which the command to be aborted was sent */ - c = (ctlr_info_t **) &scsicmd->device->host->hostdata[0]; + c = (ctlr_info_t *) scsicmd->device->host->hostdata[0]; if (c == NULL) /* paranoia */ return FAILED; - ctlr = (*c)->ctlr; + ctlr = c->ctlr; printk(KERN_WARNING "cciss%d: aborting tardy SCSI cmd\n", ctlr); /* find the command to be aborted */ -- cgit v1.2.2 From 87c3a922a7ee8cfb9ab837f4ae38c993e9b30711 Mon Sep 17 00:00:00 2001 From: "Stephen M. Cameron" Date: Fri, 26 Feb 2010 16:01:53 -0600 Subject: cciss: Fix problem with scatter gather elements in the scsi half of the driver cciss: Fix problem with scatter gather elements in the scsi half of the driver When support for more than 31 scatter gather elements was added to the block half of the driver, the SCSI half of the driver was not addressed, and the bump from 31 to 32 scatter gather elements in the command block itself (not chained) actually broke the SCSI half of the driver, so that any transfer requiring 32 scatter gather elements wouldn't work. This fix also increases the max transfer size and size of the scatter gather table to the limit supported by the controller Signed-off-by: Stephen M. Cameron Signed-off-by: Jens Axboe --- drivers/block/cciss_scsi.c | 85 ++++++++++++++++++++++++++++++++-------------- 1 file changed, 59 insertions(+), 26 deletions(-) (limited to 'drivers') diff --git a/drivers/block/cciss_scsi.c b/drivers/block/cciss_scsi.c index 6dc15b669694..e1d0e2cfec72 100644 --- a/drivers/block/cciss_scsi.c +++ b/drivers/block/cciss_scsi.c @@ -84,7 +84,6 @@ static struct scsi_host_template cciss_driver_template = { .queuecommand = cciss_scsi_queue_command, .can_queue = SCSI_CCISS_CAN_QUEUE, .this_id = 7, - .sg_tablesize = MAXSGENTRIES, .cmd_per_lun = 1, .use_clustering = DISABLE_CLUSTERING, /* Can't have eh_bus_reset_handler or eh_host_reset_handler for cciss */ @@ -94,13 +93,14 @@ static struct scsi_host_template cciss_driver_template = { #pragma pack(1) -#define SCSI_PAD_32 4 -#define SCSI_PAD_64 4 +#define SCSI_PAD_32 0 +#define SCSI_PAD_64 0 struct cciss_scsi_cmd_stack_elem_t { CommandList_struct cmd; ErrorInfo_struct Err; __u32 busaddr; + int cmdindex; u8 pad[IS_32_BIT * SCSI_PAD_32 + IS_64_BIT * SCSI_PAD_64]; }; @@ -122,6 +122,7 @@ struct cciss_scsi_cmd_stack_t { struct cciss_scsi_adapter_data_t { struct Scsi_Host *scsi_host; struct cciss_scsi_cmd_stack_t cmd_stack; + SGDescriptor_struct **cmd_sg_list; int registered; spinlock_t lock; // to protect ccissscsi[ctlr]; }; @@ -156,6 +157,7 @@ scsi_cmd_alloc(ctlr_info_t *h) memset(&c->Err, 0, sizeof(c->Err)); /* set physical addr of cmd and addr of scsi parameters */ c->cmd.busaddr = c->busaddr; + c->cmd.cmdindex = c->cmdindex; /* (__u32) (stk->cmd_pool_handle + (sizeof(struct cciss_scsi_cmd_stack_elem_t)*stk->top)); */ @@ -201,6 +203,11 @@ scsi_cmd_stack_setup(int ctlr, struct cciss_scsi_adapter_data_t *sa) struct cciss_scsi_cmd_stack_t *stk; size_t size; + sa->cmd_sg_list = cciss_allocate_sg_chain_blocks(hba[ctlr], + hba[ctlr]->chainsize, CMD_STACK_SIZE); + if (!sa->cmd_sg_list && hba[ctlr]->chainsize > 0) + return -ENOMEM; + stk = &sa->cmd_stack; size = sizeof(struct cciss_scsi_cmd_stack_elem_t) * CMD_STACK_SIZE; @@ -211,14 +218,16 @@ scsi_cmd_stack_setup(int ctlr, struct cciss_scsi_adapter_data_t *sa) pci_alloc_consistent(hba[ctlr]->pdev, size, &stk->cmd_pool_handle); if (stk->pool == NULL) { - printk("stk->pool is null\n"); - return -1; + cciss_free_sg_chain_blocks(sa->cmd_sg_list, CMD_STACK_SIZE); + sa->cmd_sg_list = NULL; + return -ENOMEM; } for (i=0; ielem[i] = &stk->pool[i]; stk->elem[i]->busaddr = (__u32) (stk->cmd_pool_handle + (sizeof(struct cciss_scsi_cmd_stack_elem_t) * i)); + stk->elem[i]->cmdindex = i; } stk->top = CMD_STACK_SIZE-1; return 0; @@ -243,6 +252,7 @@ scsi_cmd_stack_free(int ctlr) pci_free_consistent(hba[ctlr]->pdev, size, stk->pool, stk->cmd_pool_handle); stk->pool = NULL; + cciss_free_sg_chain_blocks(sa->cmd_sg_list, CMD_STACK_SIZE); } #if 0 @@ -726,6 +736,8 @@ complete_scsi_command( CommandList_struct *cp, int timeout, __u32 tag) ctlr = hba[cp->ctlr]; scsi_dma_unmap(cmd); + if (cp->Header.SGTotal > ctlr->max_cmd_sgentries) + cciss_unmap_sg_chain_block(ctlr, cp); cmd->result = (DID_OK << 16); /* host byte */ cmd->result |= (COMMAND_COMPLETE << 8); /* msg byte */ @@ -848,6 +860,7 @@ cciss_scsi_detect(int ctlr) sh->io_port = 0; // good enough? FIXME, sh->n_io_port = 0; // I don't think we use these two... sh->this_id = SELF_SCSI_ID; + sh->sg_tablesize = hba[ctlr]->maxsgentries; ((struct cciss_scsi_adapter_data_t *) hba[ctlr]->scsi_ctlr)->scsi_host = sh; @@ -1365,34 +1378,54 @@ cciss_scsi_proc_info(struct Scsi_Host *sh, dma mapping and fills in the scatter gather entries of the cciss command, cp. */ -static void -cciss_scatter_gather(struct pci_dev *pdev, - CommandList_struct *cp, - struct scsi_cmnd *cmd) +static void cciss_scatter_gather(ctlr_info_t *h, CommandList_struct *cp, + struct scsi_cmnd *cmd) { unsigned int len; struct scatterlist *sg; __u64 addr64; - int use_sg, i; - - BUG_ON(scsi_sg_count(cmd) > MAXSGENTRIES); - - use_sg = scsi_dma_map(cmd); - if (use_sg) { /* not too many addrs? */ - scsi_for_each_sg(cmd, sg, use_sg, i) { + int request_nsgs, i, chained, sg_index; + struct cciss_scsi_adapter_data_t *sa = h->scsi_ctlr; + SGDescriptor_struct *curr_sg; + + BUG_ON(scsi_sg_count(cmd) > h->maxsgentries); + + chained = 0; + sg_index = 0; + curr_sg = cp->SG; + request_nsgs = scsi_dma_map(cmd); + if (request_nsgs) { + scsi_for_each_sg(cmd, sg, request_nsgs, i) { + if (sg_index + 1 == h->max_cmd_sgentries && + !chained && request_nsgs - i > 1) { + chained = 1; + sg_index = 0; + curr_sg = sa->cmd_sg_list[cp->cmdindex]; + } addr64 = (__u64) sg_dma_address(sg); len = sg_dma_len(sg); - cp->SG[i].Addr.lower = - (__u32) (addr64 & (__u64) 0x00000000FFFFFFFF); - cp->SG[i].Addr.upper = - (__u32) ((addr64 >> 32) & (__u64) 0x00000000FFFFFFFF); - cp->SG[i].Len = len; - cp->SG[i].Ext = 0; // we are not chaining + curr_sg[sg_index].Addr.lower = + (__u32) (addr64 & 0x0FFFFFFFFULL); + curr_sg[sg_index].Addr.upper = + (__u32) ((addr64 >> 32) & 0x0FFFFFFFFULL); + curr_sg[sg_index].Len = len; + curr_sg[sg_index].Ext = 0; + ++sg_index; } + if (chained) + cciss_map_sg_chain_block(h, cp, + sa->cmd_sg_list[cp->cmdindex], + (request_nsgs - (h->max_cmd_sgentries - 1)) * + sizeof(SGDescriptor_struct)); } - - cp->Header.SGList = (__u8) use_sg; /* no. SGs contig in this cmd */ - cp->Header.SGTotal = (__u16) use_sg; /* total sgs in this cmd list */ + /* track how many SG entries we are using */ + if (request_nsgs > h->maxSG) + h->maxSG = request_nsgs; + cp->Header.SGTotal = (__u8) request_nsgs + chained; + if (request_nsgs > h->max_cmd_sgentries) + cp->Header.SGList = h->max_cmd_sgentries; + else + cp->Header.SGList = cp->Header.SGTotal; return; } @@ -1490,7 +1523,7 @@ cciss_scsi_queue_command (struct scsi_cmnd *cmd, void (* done)(struct scsi_cmnd BUG(); break; } - cciss_scatter_gather(c->pdev, cp, cmd); + cciss_scatter_gather(c, cp, cmd); /* Put the request on the tail of the request queue */ -- cgit v1.2.2 From 91f63d0efa1b2ff3f8773aad61c2970f097232aa Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Mon, 1 Mar 2010 19:21:01 +1100 Subject: block: fix for "Consolidate phys_segment and hw_segment limits" Signed-off-by: Stephen Rothwell Signed-off-by: Jens Axboe --- drivers/block/ps3vram.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/block/ps3vram.c b/drivers/block/ps3vram.c index 83ebb390b164..e44608229972 100644 --- a/drivers/block/ps3vram.c +++ b/drivers/block/ps3vram.c @@ -751,7 +751,7 @@ static int __devinit ps3vram_probe(struct ps3_system_bus_device *dev) priv->queue = queue; queue->queuedata = dev; blk_queue_make_request(queue, ps3vram_make_request); - blk_queue_max_segments(queue, BLK_MAX_HW_SEGMENTS); + blk_queue_max_segments(queue, BLK_MAX_SEGMENTS); blk_queue_max_segment_size(queue, BLK_MAX_SEGMENT_SIZE); blk_queue_max_hw_sectors(queue, BLK_SAFE_MAX_SECTORS); -- cgit v1.2.2 From a4c1a148a0c4c690b95938e9577be9e461bc5e5a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Tue, 23 Feb 2010 23:36:26 +0100 Subject: OMAP: DSS2: OMAPFB: Constify some function parameters MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Ville Syrjälä Signed-off-by: Tomi Valkeinen --- drivers/video/omap2/omapfb/omapfb-main.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/video/omap2/omapfb/omapfb-main.c b/drivers/video/omap2/omapfb/omapfb-main.c index e3a1730df5fd..4a76917b7cc8 100644 --- a/drivers/video/omap2/omapfb/omapfb-main.c +++ b/drivers/video/omap2/omapfb/omapfb-main.c @@ -154,9 +154,9 @@ static void fill_fb(struct fb_info *fbi) } #endif -static unsigned omapfb_get_vrfb_offset(struct omapfb_info *ofbi, int rot) +static unsigned omapfb_get_vrfb_offset(const struct omapfb_info *ofbi, int rot) { - struct vrfb *vrfb = &ofbi->region.vrfb; + const struct vrfb *vrfb = &ofbi->region.vrfb; unsigned offset; switch (rot) { @@ -181,7 +181,7 @@ static unsigned omapfb_get_vrfb_offset(struct omapfb_info *ofbi, int rot) return offset; } -static u32 omapfb_get_region_rot_paddr(struct omapfb_info *ofbi, int rot) +static u32 omapfb_get_region_rot_paddr(const struct omapfb_info *ofbi, int rot) { if (ofbi->rotation_type == OMAP_DSS_ROT_VRFB) { return ofbi->region.vrfb.paddr[rot] @@ -191,7 +191,7 @@ static u32 omapfb_get_region_rot_paddr(struct omapfb_info *ofbi, int rot) } } -static u32 omapfb_get_region_paddr(struct omapfb_info *ofbi) +static u32 omapfb_get_region_paddr(const struct omapfb_info *ofbi) { if (ofbi->rotation_type == OMAP_DSS_ROT_VRFB) return ofbi->region.vrfb.paddr[0]; @@ -199,7 +199,7 @@ static u32 omapfb_get_region_paddr(struct omapfb_info *ofbi) return ofbi->region.paddr; } -static void __iomem *omapfb_get_region_vaddr(struct omapfb_info *ofbi) +static void __iomem *omapfb_get_region_vaddr(const struct omapfb_info *ofbi) { if (ofbi->rotation_type == OMAP_DSS_ROT_VRFB) return ofbi->region.vrfb.vaddr[0]; @@ -780,8 +780,8 @@ static int omapfb_release(struct fb_info *fbi, int user) return 0; } -static unsigned calc_rotation_offset_dma(struct fb_var_screeninfo *var, - struct fb_fix_screeninfo *fix, int rotation) +static unsigned calc_rotation_offset_dma(const struct fb_var_screeninfo *var, + const struct fb_fix_screeninfo *fix, int rotation) { unsigned offset; @@ -791,8 +791,8 @@ static unsigned calc_rotation_offset_dma(struct fb_var_screeninfo *var, return offset; } -static unsigned calc_rotation_offset_vrfb(struct fb_var_screeninfo *var, - struct fb_fix_screeninfo *fix, int rotation) +static unsigned calc_rotation_offset_vrfb(const struct fb_var_screeninfo *var, + const struct fb_fix_screeninfo *fix, int rotation) { unsigned offset; -- cgit v1.2.2 From 1189b7ff6485ebf1039440c34150360fab7cfb01 Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Mon, 1 Mar 2010 13:52:10 +0200 Subject: OMAP: DSS2: Taal: Fix ESD check Using taal_enable_te() when DSI bus was locked caused a deadlock. Signed-off-by: Tomi Valkeinen --- drivers/video/omap2/displays/panel-taal.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/video/omap2/displays/panel-taal.c b/drivers/video/omap2/displays/panel-taal.c index a722733106b1..2b5777621779 100644 --- a/drivers/video/omap2/displays/panel-taal.c +++ b/drivers/video/omap2/displays/panel-taal.c @@ -1055,8 +1055,11 @@ static void taal_esd_work(struct work_struct *work) } /* Self-diagnostics result is also shown on TE GPIO line. We need * to re-enable TE after self diagnostics */ - if (td->use_ext_te && td->te_enabled) - taal_enable_te(dssdev, true); + if (td->use_ext_te && td->te_enabled) { + r = taal_dcs_write_1(DCS_TEAR_ON, 0); + if (r) + goto err; + } dsi_bus_unlock(); -- cgit v1.2.2 From 9a928660c9dcaff568c9d379655c5aa16fb981f8 Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Sun, 28 Feb 2010 15:49:39 -0800 Subject: pci: don't reassign to ROM res if it is not going to be enabled A ROM resource that doesn't fit should not cause us to try to re-assign all the bus resources. Nobody generally cares, and re-assigning is going to just cause way more troubles than it tries to solve. Signed-off-by: Yinghai Lu Signed-off-by: Linus Torvalds --- drivers/pci/setup-bus.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c index bf32f07c4efb..4fe36d2e1049 100644 --- a/drivers/pci/setup-bus.c +++ b/drivers/pci/setup-bus.c @@ -101,9 +101,17 @@ static void __assign_resources_sorted(struct resource_list *head, for (list = head->next; list;) { res = list->res; idx = res - &list->dev->resource[0]; + if (pci_assign_resource(list->dev, idx)) { - if (fail_head && !pci_is_root_bus(list->dev->bus)) - add_to_failed_list(fail_head, list->dev, res); + if (fail_head && !pci_is_root_bus(list->dev->bus)) { + /* + * if the failed res is for ROM BAR, and it will + * be enabled later, don't add it to the list + */ + if (!((idx == PCI_ROM_RESOURCE) && + (!(res->flags & IORESOURCE_ROM_ENABLE)))) + add_to_failed_list(fail_head, list->dev, res); + } res->start = 0; res->end = 0; res->flags = 0; -- cgit v1.2.2 From 786f8ba2e9449a7f01ec6bc35838d0a335921061 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Sun, 28 Feb 2010 17:32:45 -0800 Subject: scsi.c: add missing kernel-doc notation for new VPD parameters Add missing kernel-doc notation for new function parameters: Warning(drivers/scsi/scsi.c:1031): No description found for parameter 'buf' Warning(drivers/scsi/scsi.c:1031): No description found for parameter 'buf_len' Signed-off-by: Randy Dunlap Cc: James Bottomley Signed-off-by: Linus Torvalds --- drivers/scsi/scsi.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c index 513661f45e5f..1c08f6164658 100644 --- a/drivers/scsi/scsi.c +++ b/drivers/scsi/scsi.c @@ -1018,6 +1018,8 @@ static int scsi_vpd_inquiry(struct scsi_device *sdev, unsigned char *buffer, * scsi_get_vpd_page - Get Vital Product Data from a SCSI device * @sdev: The device to ask * @page: Which Vital Product Data to return + * @buf: where to store the VPD + * @buf_len: number of bytes in the VPD buffer area * * SCSI devices may optionally supply Vital Product Data. Each 'page' * of VPD is defined in the appropriate SCSI document (eg SPC, SBC). -- cgit v1.2.2 From 56f46f8c8741d02516d9150a46a5b05fe910ee11 Mon Sep 17 00:00:00 2001 From: Sergei Shtylyov Date: Sat, 5 Dec 2009 00:37:43 +0400 Subject: pata_hpt37x: use ATA_DMA_* constants Use ATA_DMA_* constants instead of the bare numbers for the BMIDE registers. Signed-off-by: Sergei Shtylyov Signed-off-by: Jeff Garzik --- drivers/ata/pata_hpt37x.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/ata/pata_hpt37x.c b/drivers/ata/pata_hpt37x.c index 4224cfccedef..342aaaaf3832 100644 --- a/drivers/ata/pata_hpt37x.c +++ b/drivers/ata/pata_hpt37x.c @@ -461,24 +461,25 @@ static void hpt370_bmdma_stop(struct ata_queued_cmd *qc) { struct ata_port *ap = qc->ap; struct pci_dev *pdev = to_pci_dev(ap->host->dev); - u8 dma_stat = ioread8(ap->ioaddr.bmdma_addr + 2); - u8 dma_cmd; void __iomem *bmdma = ap->ioaddr.bmdma_addr; + u8 dma_stat = ioread8(bmdma + ATA_DMA_STATUS); + u8 dma_cmd; - if (dma_stat & 0x01) { + if (dma_stat & ATA_DMA_ACTIVE) { udelay(20); - dma_stat = ioread8(bmdma + 2); + dma_stat = ioread8(bmdma + ATA_DMA_STATUS); } - if (dma_stat & 0x01) { + if (dma_stat & ATA_DMA_ACTIVE) { /* Clear the engine */ pci_write_config_byte(pdev, 0x50 + 4 * ap->port_no, 0x37); udelay(10); /* Stop DMA */ - dma_cmd = ioread8(bmdma ); - iowrite8(dma_cmd & 0xFE, bmdma); + dma_cmd = ioread8(bmdma + ATA_DMA_CMD); + iowrite8(dma_cmd & ~ATA_DMA_START, bmdma + ATA_DMA_CMD); /* Clear Error */ - dma_stat = ioread8(bmdma + 2); - iowrite8(dma_stat | 0x06 , bmdma + 2); + dma_stat = ioread8(bmdma + ATA_DMA_STATUS); + iowrite8(dma_stat | ATA_DMA_INTR | ATA_DMA_ERR, + bmdma + ATA_DMA_STATUS); /* Clear the engine */ pci_write_config_byte(pdev, 0x50 + 4 * ap->port_no, 0x37); udelay(10); -- cgit v1.2.2 From 60661933995bc7a09686c901439e17c2a4ea7d5d Mon Sep 17 00:00:00 2001 From: Sergei Shtylyov Date: Mon, 7 Dec 2009 23:25:52 +0400 Subject: pata_hpt3x2n: always stretch UltraDMA timing The UltraDMA Tss timing must be stretched with ATA clock of 66 MHz, but the driver only does this when PCI clock is 66 MHz, whereas it always programs DPLL clock (which is used as the ATA clock) to 66 MHz. Signed-off-by: Sergei Shtylyov Cc: Signed-off-by: Jeff Garzik --- drivers/ata/pata_hpt3x2n.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/ata/pata_hpt3x2n.c b/drivers/ata/pata_hpt3x2n.c index dd26bc73bd9a..269b5dbe51bb 100644 --- a/drivers/ata/pata_hpt3x2n.c +++ b/drivers/ata/pata_hpt3x2n.c @@ -25,7 +25,7 @@ #include #define DRV_NAME "pata_hpt3x2n" -#define DRV_VERSION "0.3.8" +#define DRV_VERSION "0.3.9" enum { HPT_PCI_FAST = (1 << 31), @@ -544,16 +544,16 @@ static int hpt3x2n_init_one(struct pci_dev *dev, const struct pci_device_id *id) pci_mhz); /* Set our private data up. We only need a few flags so we use it directly */ - if (pci_mhz > 60) { + if (pci_mhz > 60) hpriv = (void *)(PCI66 | USE_DPLL); - /* - * On HPT371N, if ATA clock is 66 MHz we must set bit 2 in - * the MISC. register to stretch the UltraDMA Tss timing. - * NOTE: This register is only writeable via I/O space. - */ - if (dev->device == PCI_DEVICE_ID_TTI_HPT371) - outb(inb(iobase + 0x9c) | 0x04, iobase + 0x9c); - } + + /* + * On HPT371N, if ATA clock is 66 MHz we must set bit 2 in + * the MISC. register to stretch the UltraDMA Tss timing. + * NOTE: This register is only writeable via I/O space. + */ + if (dev->device == PCI_DEVICE_ID_TTI_HPT371) + outb(inb(iobase + 0x9c) | 0x04, iobase + 0x9c); /* Now kick off ATA set up */ return ata_pci_sff_init_one(dev, ppi, &hpt3x2n_sht, hpriv); -- cgit v1.2.2 From 1a1b172b9672e88d37adb5925b509e9236625d7e Mon Sep 17 00:00:00 2001 From: Sergei Shtylyov Date: Mon, 7 Dec 2009 23:30:06 +0400 Subject: pata_hpt{37x|3x2n}: unify mode programming As these drivers' set_piomode() and set_dmamode() methods are almost identical, factor out the common hpt{37x|3x2n}_set_mode() function to be called by both of them, the same as in 'pata_hpt366' driver. This results in ~5% decrease in the 'pata_hpt37x' driver binary size and in ~4% decrease in the 'pata_hpt3x2n' driver binary size (as measured on x86-32). Signed-off-by: Sergei Shtylyov Signed-off-by: Jeff Garzik --- drivers/ata/pata_hpt37x.c | 137 +++++++++++++++++++-------------------------- drivers/ata/pata_hpt3x2n.c | 69 ++++++++++------------- 2 files changed, 90 insertions(+), 116 deletions(-) (limited to 'drivers') diff --git a/drivers/ata/pata_hpt37x.c b/drivers/ata/pata_hpt37x.c index 342aaaaf3832..9b191763e6e5 100644 --- a/drivers/ata/pata_hpt37x.c +++ b/drivers/ata/pata_hpt37x.c @@ -24,7 +24,7 @@ #include #define DRV_NAME "pata_hpt37x" -#define DRV_VERSION "0.6.14" +#define DRV_VERSION "0.6.15" struct hpt_clock { u8 xfer_speed; @@ -384,20 +384,12 @@ static int hpt37x_pre_reset(struct ata_link *link, unsigned long deadline) return ata_sff_prereset(link, deadline); } -/** - * hpt370_set_piomode - PIO setup - * @ap: ATA interface - * @adev: device on the interface - * - * Perform PIO mode setup. - */ - -static void hpt370_set_piomode(struct ata_port *ap, struct ata_device *adev) +static void hpt370_set_mode(struct ata_port *ap, struct ata_device *adev, + u8 mode) { struct pci_dev *pdev = to_pci_dev(ap->host->dev); u32 addr1, addr2; - u32 reg; - u32 mode; + u32 reg, timing, mask; u8 fast; addr1 = 0x40 + 4 * (adev->devno + 2 * ap->port_no); @@ -409,11 +401,31 @@ static void hpt370_set_piomode(struct ata_port *ap, struct ata_device *adev) fast |= 0x01; pci_write_config_byte(pdev, addr2, fast); + /* Determine timing mask and find matching mode entry */ + if (mode < XFER_MW_DMA_0) + mask = 0xcfc3ffff; + else if (mode < XFER_UDMA_0) + mask = 0x31c001ff; + else + mask = 0x303c0000; + + timing = hpt37x_find_mode(ap, mode); + pci_read_config_dword(pdev, addr1, ®); - mode = hpt37x_find_mode(ap, adev->pio_mode); - mode &= 0xCFC3FFFF; /* Leave DMA bits alone */ - reg &= ~0xCFC3FFFF; /* Strip timing bits */ - pci_write_config_dword(pdev, addr1, reg | mode); + reg = (reg & ~mask) | (timing & mask); + pci_write_config_dword(pdev, addr1, reg); +} +/** + * hpt370_set_piomode - PIO setup + * @ap: ATA interface + * @adev: device on the interface + * + * Perform PIO mode setup. + */ + +static void hpt370_set_piomode(struct ata_port *ap, struct ata_device *adev) +{ + hpt370_set_mode(ap, adev, adev->pio_mode); } /** @@ -421,33 +433,12 @@ static void hpt370_set_piomode(struct ata_port *ap, struct ata_device *adev) * @ap: ATA interface * @adev: Device being configured * - * Set up the channel for MWDMA or UDMA modes. Much the same as with - * PIO, load the mode number and then set MWDMA or UDMA flag. + * Set up the channel for MWDMA or UDMA modes. */ static void hpt370_set_dmamode(struct ata_port *ap, struct ata_device *adev) { - struct pci_dev *pdev = to_pci_dev(ap->host->dev); - u32 addr1, addr2; - u32 reg, mode, mask; - u8 fast; - - addr1 = 0x40 + 4 * (adev->devno + 2 * ap->port_no); - addr2 = 0x51 + 4 * ap->port_no; - - /* Fast interrupt prediction disable, hold off interrupt disable */ - pci_read_config_byte(pdev, addr2, &fast); - fast &= ~0x02; - fast |= 0x01; - pci_write_config_byte(pdev, addr2, fast); - - mask = adev->dma_mode < XFER_UDMA_0 ? 0x31C001FF : 0x303C0000; - - pci_read_config_dword(pdev, addr1, ®); - mode = hpt37x_find_mode(ap, adev->dma_mode); - mode &= mask; - reg &= ~mask; - pci_write_config_dword(pdev, addr1, reg | mode); + hpt370_set_mode(ap, adev, adev->dma_mode); } /** @@ -487,20 +478,12 @@ static void hpt370_bmdma_stop(struct ata_queued_cmd *qc) ata_bmdma_stop(qc); } -/** - * hpt372_set_piomode - PIO setup - * @ap: ATA interface - * @adev: device on the interface - * - * Perform PIO mode setup. - */ - -static void hpt372_set_piomode(struct ata_port *ap, struct ata_device *adev) +static void hpt372_set_mode(struct ata_port *ap, struct ata_device *adev, + u8 mode) { struct pci_dev *pdev = to_pci_dev(ap->host->dev); u32 addr1, addr2; - u32 reg; - u32 mode; + u32 reg, timing, mask; u8 fast; addr1 = 0x40 + 4 * (adev->devno + 2 * ap->port_no); @@ -511,13 +494,32 @@ static void hpt372_set_piomode(struct ata_port *ap, struct ata_device *adev) fast &= ~0x07; pci_write_config_byte(pdev, addr2, fast); + /* Determine timing mask and find matching mode entry */ + if (mode < XFER_MW_DMA_0) + mask = 0xcfc3ffff; + else if (mode < XFER_UDMA_0) + mask = 0x31c001ff; + else + mask = 0x303c0000; + + timing = hpt37x_find_mode(ap, mode); + pci_read_config_dword(pdev, addr1, ®); - mode = hpt37x_find_mode(ap, adev->pio_mode); + reg = (reg & ~mask) | (timing & mask); + pci_write_config_dword(pdev, addr1, reg); +} - printk("Find mode for %d reports %X\n", adev->pio_mode, mode); - mode &= 0xCFC3FFFF; /* Leave DMA bits alone */ - reg &= ~0xCFC3FFFF; /* Strip timing bits */ - pci_write_config_dword(pdev, addr1, reg | mode); +/** + * hpt372_set_piomode - PIO setup + * @ap: ATA interface + * @adev: device on the interface + * + * Perform PIO mode setup. + */ + +static void hpt372_set_piomode(struct ata_port *ap, struct ata_device *adev) +{ + hpt372_set_mode(ap, adev, adev->pio_mode); } /** @@ -525,33 +527,12 @@ static void hpt372_set_piomode(struct ata_port *ap, struct ata_device *adev) * @ap: ATA interface * @adev: Device being configured * - * Set up the channel for MWDMA or UDMA modes. Much the same as with - * PIO, load the mode number and then set MWDMA or UDMA flag. + * Set up the channel for MWDMA or UDMA modes. */ static void hpt372_set_dmamode(struct ata_port *ap, struct ata_device *adev) { - struct pci_dev *pdev = to_pci_dev(ap->host->dev); - u32 addr1, addr2; - u32 reg, mode, mask; - u8 fast; - - addr1 = 0x40 + 4 * (adev->devno + 2 * ap->port_no); - addr2 = 0x51 + 4 * ap->port_no; - - /* Fast interrupt prediction disable, hold off interrupt disable */ - pci_read_config_byte(pdev, addr2, &fast); - fast &= ~0x07; - pci_write_config_byte(pdev, addr2, fast); - - mask = adev->dma_mode < XFER_UDMA_0 ? 0x31C001FF : 0x303C0000; - - pci_read_config_dword(pdev, addr1, ®); - mode = hpt37x_find_mode(ap, adev->dma_mode); - printk("Find mode for DMA %d reports %X\n", adev->dma_mode, mode); - mode &= mask; - reg &= ~mask; - pci_write_config_dword(pdev, addr1, reg | mode); + hpt372_set_mode(ap, adev, adev->dma_mode); } /** diff --git a/drivers/ata/pata_hpt3x2n.c b/drivers/ata/pata_hpt3x2n.c index 269b5dbe51bb..b131c8f824d7 100644 --- a/drivers/ata/pata_hpt3x2n.c +++ b/drivers/ata/pata_hpt3x2n.c @@ -25,7 +25,7 @@ #include #define DRV_NAME "pata_hpt3x2n" -#define DRV_VERSION "0.3.9" +#define DRV_VERSION "0.3.10" enum { HPT_PCI_FAST = (1 << 31), @@ -161,20 +161,12 @@ static int hpt3x2n_pre_reset(struct ata_link *link, unsigned long deadline) return ata_sff_prereset(link, deadline); } -/** - * hpt3x2n_set_piomode - PIO setup - * @ap: ATA interface - * @adev: device on the interface - * - * Perform PIO mode setup. - */ - -static void hpt3x2n_set_piomode(struct ata_port *ap, struct ata_device *adev) +static void hpt3x2n_set_mode(struct ata_port *ap, struct ata_device *adev, + u8 mode) { struct pci_dev *pdev = to_pci_dev(ap->host->dev); u32 addr1, addr2; - u32 reg; - u32 mode; + u32 reg, timing, mask; u8 fast; addr1 = 0x40 + 4 * (adev->devno + 2 * ap->port_no); @@ -185,11 +177,32 @@ static void hpt3x2n_set_piomode(struct ata_port *ap, struct ata_device *adev) fast &= ~0x07; pci_write_config_byte(pdev, addr2, fast); + /* Determine timing mask and find matching mode entry */ + if (mode < XFER_MW_DMA_0) + mask = 0xcfc3ffff; + else if (mode < XFER_UDMA_0) + mask = 0x31c001ff; + else + mask = 0x303c0000; + + timing = hpt3x2n_find_mode(ap, mode); + pci_read_config_dword(pdev, addr1, ®); - mode = hpt3x2n_find_mode(ap, adev->pio_mode); - mode &= 0xCFC3FFFF; /* Leave DMA bits alone */ - reg &= ~0xCFC3FFFF; /* Strip timing bits */ - pci_write_config_dword(pdev, addr1, reg | mode); + reg = (reg & ~mask) | (timing & mask); + pci_write_config_dword(pdev, addr1, reg); +} + +/** + * hpt3x2n_set_piomode - PIO setup + * @ap: ATA interface + * @adev: device on the interface + * + * Perform PIO mode setup. + */ + +static void hpt3x2n_set_piomode(struct ata_port *ap, struct ata_device *adev) +{ + hpt3x2n_set_mode(ap, adev, adev->pio_mode); } /** @@ -197,32 +210,12 @@ static void hpt3x2n_set_piomode(struct ata_port *ap, struct ata_device *adev) * @ap: ATA interface * @adev: Device being configured * - * Set up the channel for MWDMA or UDMA modes. Much the same as with - * PIO, load the mode number and then set MWDMA or UDMA flag. + * Set up the channel for MWDMA or UDMA modes. */ static void hpt3x2n_set_dmamode(struct ata_port *ap, struct ata_device *adev) { - struct pci_dev *pdev = to_pci_dev(ap->host->dev); - u32 addr1, addr2; - u32 reg, mode, mask; - u8 fast; - - addr1 = 0x40 + 4 * (adev->devno + 2 * ap->port_no); - addr2 = 0x51 + 4 * ap->port_no; - - /* Fast interrupt prediction disable, hold off interrupt disable */ - pci_read_config_byte(pdev, addr2, &fast); - fast &= ~0x07; - pci_write_config_byte(pdev, addr2, fast); - - mask = adev->dma_mode < XFER_UDMA_0 ? 0x31C001FF : 0x303C0000; - - pci_read_config_dword(pdev, addr1, ®); - mode = hpt3x2n_find_mode(ap, adev->dma_mode); - mode &= mask; - reg &= ~mask; - pci_write_config_dword(pdev, addr1, reg | mode); + hpt3x2n_set_mode(ap, adev, adev->dma_mode); } /** -- cgit v1.2.2 From 859faa875ed6760fcdfaf6f1fec1155a7e43dc21 Mon Sep 17 00:00:00 2001 From: Sergei Shtylyov Date: Mon, 7 Dec 2009 23:36:15 +0400 Subject: pata_hpt366: remove redundant code There's no need to clear the fast interrupt bit in hpt366_set_mode() since we're doing it in hpt366_init_chipset() already. While at it, rename 'addr1' local variable to 'addr' and exclude 'ap->port_no' from its calculation as HPT36x are single-channel-per-function chips. Signed-off-by: Sergei Shtylyov Signed-off-by: Jeff Garzik --- drivers/ata/pata_hpt366.c | 17 ++++------------- 1 file changed, 4 insertions(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/ata/pata_hpt366.c b/drivers/ata/pata_hpt366.c index 0bd48e8f21bd..f6b285890ae9 100644 --- a/drivers/ata/pata_hpt366.c +++ b/drivers/ata/pata_hpt366.c @@ -27,7 +27,7 @@ #include #define DRV_NAME "pata_hpt366" -#define DRV_VERSION "0.6.7" +#define DRV_VERSION "0.6.8" struct hpt_clock { u8 xfer_mode; @@ -207,17 +207,8 @@ static void hpt366_set_mode(struct ata_port *ap, struct ata_device *adev, { struct hpt_clock *clocks = ap->host->private_data; struct pci_dev *pdev = to_pci_dev(ap->host->dev); - u32 addr1 = 0x40 + 4 * (adev->devno + 2 * ap->port_no); - u32 addr2 = 0x51 + 4 * ap->port_no; + u32 addr = 0x40 + 4 * adev->devno; u32 mask, reg; - u8 fast; - - /* Fast interrupt prediction disable, hold off interrupt disable */ - pci_read_config_byte(pdev, addr2, &fast); - if (fast & 0x80) { - fast &= ~0x80; - pci_write_config_byte(pdev, addr2, fast); - } /* determine timing mask and find matching clock entry */ if (mode < XFER_MW_DMA_0) @@ -240,9 +231,9 @@ static void hpt366_set_mode(struct ata_port *ap, struct ata_device *adev, * on-chip PIO FIFO/buffer (and PIO MST mode as well) to avoid * problems handling I/O errors later. */ - pci_read_config_dword(pdev, addr1, ®); + pci_read_config_dword(pdev, addr, ®); reg = ((reg & ~mask) | (clocks->timing & mask)) & ~0xc0000000; - pci_write_config_dword(pdev, addr1, reg); + pci_write_config_dword(pdev, addr, reg); } /** -- cgit v1.2.2 From fd5e62e22db29a067d3f26ba54caac308eb5e3a8 Mon Sep 17 00:00:00 2001 From: Sergei Shtylyov Date: Mon, 7 Dec 2009 23:38:11 +0400 Subject: pata_hpt{37x|3x2n}: improve timing register documentation Describe UDMA timing bits 18-20 and 21 separately; add a note to bit 31 about it being meaningful for PIO only. Reformat the whole comment, while at it... Signed-off-by: Sergei Shtylyov Signed-off-by: Jeff Garzik --- drivers/ata/pata_hpt37x.c | 31 +++++++++++++++---------------- drivers/ata/pata_hpt3x2n.c | 31 +++++++++++++++---------------- 2 files changed, 30 insertions(+), 32 deletions(-) (limited to 'drivers') diff --git a/drivers/ata/pata_hpt37x.c b/drivers/ata/pata_hpt37x.c index 9b191763e6e5..228dc1a8992f 100644 --- a/drivers/ata/pata_hpt37x.c +++ b/drivers/ata/pata_hpt37x.c @@ -39,25 +39,24 @@ struct hpt_chip { /* key for bus clock timings * bit - * 0:3 data_high_time. inactive time of DIOW_/DIOR_ for PIO and MW - * DMA. cycles = value + 1 - * 4:8 data_low_time. active time of DIOW_/DIOR_ for PIO and MW - * DMA. cycles = value + 1 - * 9:12 cmd_high_time. inactive time of DIOW_/DIOR_ during task file + * 0:3 data_high_time. Inactive time of DIOW_/DIOR_ for PIO and MW DMA. + * cycles = value + 1 + * 4:8 data_low_time. Active time of DIOW_/DIOR_ for PIO and MW DMA. + * cycles = value + 1 + * 9:12 cmd_high_time. Inactive time of DIOW_/DIOR_ during task file * register access. - * 13:17 cmd_low_time. active time of DIOW_/DIOR_ during task file + * 13:17 cmd_low_time. Active time of DIOW_/DIOR_ during task file * register access. - * 18:21 udma_cycle_time. clock freq and clock cycles for UDMA xfer. - * during task file register access. - * 22:24 pre_high_time. time to initialize 1st cycle for PIO and MW DMA - * xfer. - * 25:27 cmd_pre_high_time. time to initialize 1st PIO cycle for task + * 18:20 udma_cycle_time. Clock cycles for UDMA xfer. + * 21 CLK frequency for UDMA: 0=ATA clock, 1=dual ATA clock. + * 22:24 pre_high_time. Time to initialize 1st cycle for PIO and MW DMA xfer. + * 25:27 cmd_pre_high_time. Time to initialize 1st PIO cycle for task file * register access. - * 28 UDMA enable - * 29 DMA enable - * 30 PIO_MST enable. if set, the chip is in bus master mode during - * PIO. - * 31 FIFO enable. + * 28 UDMA enable. + * 29 DMA enable. + * 30 PIO_MST enable. If set, the chip is in bus master mode during + * PIO xfer. + * 31 FIFO enable. Only for PIO. */ static struct hpt_clock hpt37x_timings_33[] = { diff --git a/drivers/ata/pata_hpt3x2n.c b/drivers/ata/pata_hpt3x2n.c index b131c8f824d7..4a291221f277 100644 --- a/drivers/ata/pata_hpt3x2n.c +++ b/drivers/ata/pata_hpt3x2n.c @@ -45,25 +45,24 @@ struct hpt_chip { /* key for bus clock timings * bit - * 0:3 data_high_time. inactive time of DIOW_/DIOR_ for PIO and MW - * DMA. cycles = value + 1 - * 4:8 data_low_time. active time of DIOW_/DIOR_ for PIO and MW - * DMA. cycles = value + 1 - * 9:12 cmd_high_time. inactive time of DIOW_/DIOR_ during task file + * 0:3 data_high_time. Inactive time of DIOW_/DIOR_ for PIO and MW DMA. + * cycles = value + 1 + * 4:8 data_low_time. Active time of DIOW_/DIOR_ for PIO and MW DMA. + * cycles = value + 1 + * 9:12 cmd_high_time. Inactive time of DIOW_/DIOR_ during task file * register access. - * 13:17 cmd_low_time. active time of DIOW_/DIOR_ during task file + * 13:17 cmd_low_time. Active time of DIOW_/DIOR_ during task file * register access. - * 18:21 udma_cycle_time. clock freq and clock cycles for UDMA xfer. - * during task file register access. - * 22:24 pre_high_time. time to initialize 1st cycle for PIO and MW DMA - * xfer. - * 25:27 cmd_pre_high_time. time to initialize 1st PIO cycle for task + * 18:20 udma_cycle_time. Clock cycles for UDMA xfer. + * 21 CLK frequency for UDMA: 0=ATA clock, 1=dual ATA clock. + * 22:24 pre_high_time. Time to initialize 1st cycle for PIO and MW DMA xfer. + * 25:27 cmd_pre_high_time. Time to initialize 1st PIO cycle for task file * register access. - * 28 UDMA enable - * 29 DMA enable - * 30 PIO_MST enable. if set, the chip is in bus master mode during - * PIO. - * 31 FIFO enable. + * 28 UDMA enable. + * 29 DMA enable. + * 30 PIO_MST enable. If set, the chip is in bus master mode during + * PIO xfer. + * 31 FIFO enable. Only for PIO. */ /* 66MHz DPLL clocks */ -- cgit v1.2.2 From d817898c2fc73e6ea33b58498c87a43d7e9fcd7a Mon Sep 17 00:00:00 2001 From: Sergei Shtylyov Date: Mon, 7 Dec 2009 23:39:38 +0400 Subject: pata_hpt366: remove irrelevant TODO HPT36x chips just don't have DPLL. Signed-off-by: Sergei Shtylyov Signed-off-by: Jeff Garzik --- drivers/ata/pata_hpt366.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/ata/pata_hpt366.c b/drivers/ata/pata_hpt366.c index f6b285890ae9..3ec88f2c8665 100644 --- a/drivers/ata/pata_hpt366.c +++ b/drivers/ata/pata_hpt366.c @@ -11,9 +11,7 @@ * * * TODO - * Maybe PLL mode - * Look into engine reset on timeout errors. Should not be - * required. + * Look into engine reset on timeout errors. Should not be required. */ -- cgit v1.2.2 From d6ef31539d715db7a0eb2d67a1a008c9d8ccf059 Mon Sep 17 00:00:00 2001 From: Shane Huang Date: Wed, 9 Dec 2009 17:23:04 +0800 Subject: ahci: Implement SATA AHCI FIS-based switching support Tested on AMD internal reference board. Signed-off-by: Shane Huang Acked-by: Tejun Heo Signed-off-by: Jeff Garzik --- drivers/ata/ahci.c | 221 ++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 203 insertions(+), 18 deletions(-) (limited to 'drivers') diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index a6a736a7dbf2..705bd8b1ea67 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c @@ -93,6 +93,9 @@ enum { AHCI_CMD_TBL_AR_SZ = AHCI_CMD_TBL_SZ * AHCI_MAX_CMDS, AHCI_PORT_PRIV_DMA_SZ = AHCI_CMD_SLOT_SZ + AHCI_CMD_TBL_AR_SZ + AHCI_RX_FIS_SZ, + AHCI_PORT_PRIV_FBS_DMA_SZ = AHCI_CMD_SLOT_SZ + + AHCI_CMD_TBL_AR_SZ + + (AHCI_RX_FIS_SZ * 16), AHCI_IRQ_ON_SG = (1 << 31), AHCI_CMD_ATAPI = (1 << 5), AHCI_CMD_WRITE = (1 << 6), @@ -170,6 +173,7 @@ enum { PORT_SCR_ERR = 0x30, /* SATA phy register: SError */ PORT_SCR_ACT = 0x34, /* SATA phy register: SActive */ PORT_SCR_NTF = 0x3c, /* SATA phy register: SNotification */ + PORT_FBS = 0x40, /* FIS-based Switching */ /* PORT_IRQ_{STAT,MASK} bits */ PORT_IRQ_COLD_PRES = (1 << 31), /* cold presence detect */ @@ -208,6 +212,7 @@ enum { PORT_CMD_ASP = (1 << 27), /* Aggressive Slumber/Partial */ PORT_CMD_ALPE = (1 << 26), /* Aggressive Link PM enable */ PORT_CMD_ATAPI = (1 << 24), /* Device is ATAPI */ + PORT_CMD_FBSCP = (1 << 22), /* FBS Capable Port */ PORT_CMD_PMP = (1 << 17), /* PMP attached */ PORT_CMD_LIST_ON = (1 << 15), /* cmd list DMA engine running */ PORT_CMD_FIS_ON = (1 << 14), /* FIS DMA engine running */ @@ -222,6 +227,14 @@ enum { PORT_CMD_ICC_PARTIAL = (0x2 << 28), /* Put i/f in partial state */ PORT_CMD_ICC_SLUMBER = (0x6 << 28), /* Put i/f in slumber state */ + PORT_FBS_DWE_OFFSET = 16, /* FBS device with error offset */ + PORT_FBS_ADO_OFFSET = 12, /* FBS active dev optimization offset */ + PORT_FBS_DEV_OFFSET = 8, /* FBS device to issue offset */ + PORT_FBS_DEV_MASK = (0xf << PORT_FBS_DEV_OFFSET), /* FBS.DEV */ + PORT_FBS_SDE = (1 << 2), /* FBS single device error */ + PORT_FBS_DEC = (1 << 1), /* FBS device error clear */ + PORT_FBS_EN = (1 << 0), /* Enable FBS */ + /* hpriv->flags bits */ AHCI_HFLAG_NO_NCQ = (1 << 0), AHCI_HFLAG_IGN_IRQ_IF_ERR = (1 << 1), /* ignore IRQ_IF_ERR */ @@ -304,6 +317,9 @@ struct ahci_port_priv { unsigned int ncq_saw_dmas:1; unsigned int ncq_saw_sdb:1; u32 intr_mask; /* interrupts to enable */ + bool fbs_supported; /* set iff FBS is supported */ + bool fbs_enabled; /* set iff FBS is enabled */ + int fbs_last_dev; /* save FBS.DEV of last FIS */ /* enclosure management info per PM slot */ struct ahci_em_priv em_priv[EM_MAX_SLOTS]; }; @@ -315,9 +331,12 @@ static unsigned int ahci_qc_issue(struct ata_queued_cmd *qc); static bool ahci_qc_fill_rtf(struct ata_queued_cmd *qc); static int ahci_port_start(struct ata_port *ap); static void ahci_port_stop(struct ata_port *ap); +static int ahci_pmp_qc_defer(struct ata_queued_cmd *qc); static void ahci_qc_prep(struct ata_queued_cmd *qc); static void ahci_freeze(struct ata_port *ap); static void ahci_thaw(struct ata_port *ap); +static void ahci_enable_fbs(struct ata_port *ap); +static void ahci_disable_fbs(struct ata_port *ap); static void ahci_pmp_attach(struct ata_port *ap); static void ahci_pmp_detach(struct ata_port *ap); static int ahci_softreset(struct ata_link *link, unsigned int *class, @@ -390,7 +409,7 @@ static struct scsi_host_template ahci_sht = { static struct ata_port_operations ahci_ops = { .inherits = &sata_pmp_port_ops, - .qc_defer = sata_pmp_qc_defer_cmd_switch, + .qc_defer = ahci_pmp_qc_defer, .qc_prep = ahci_qc_prep, .qc_issue = ahci_qc_issue, .qc_fill_rtf = ahci_qc_fill_rtf, @@ -2045,6 +2064,17 @@ static unsigned int ahci_fill_sg(struct ata_queued_cmd *qc, void *cmd_tbl) return si; } +static int ahci_pmp_qc_defer(struct ata_queued_cmd *qc) +{ + struct ata_port *ap = qc->ap; + struct ahci_port_priv *pp = ap->private_data; + + if (!sata_pmp_attached(ap) || pp->fbs_enabled) + return ata_std_qc_defer(qc); + else + return sata_pmp_qc_defer_cmd_switch(qc); +} + static void ahci_qc_prep(struct ata_queued_cmd *qc) { struct ata_port *ap = qc->ap; @@ -2083,6 +2113,31 @@ static void ahci_qc_prep(struct ata_queued_cmd *qc) ahci_fill_cmd_slot(pp, qc->tag, opts); } +static void ahci_fbs_dec_intr(struct ata_port *ap) +{ + struct ahci_port_priv *pp = ap->private_data; + void __iomem *port_mmio = ahci_port_base(ap); + u32 fbs = readl(port_mmio + PORT_FBS); + int retries = 3; + + DPRINTK("ENTER\n"); + BUG_ON(!pp->fbs_enabled); + + /* time to wait for DEC is not specified by AHCI spec, + * add a retry loop for safety. + */ + writel(fbs | PORT_FBS_DEC, port_mmio + PORT_FBS); + fbs = readl(port_mmio + PORT_FBS); + while ((fbs & PORT_FBS_DEC) && retries--) { + udelay(1); + fbs = readl(port_mmio + PORT_FBS); + } + + if (fbs & PORT_FBS_DEC) + dev_printk(KERN_ERR, ap->host->dev, + "failed to clear device error\n"); +} + static void ahci_error_intr(struct ata_port *ap, u32 irq_stat) { struct ahci_host_priv *hpriv = ap->host->private_data; @@ -2091,12 +2146,26 @@ static void ahci_error_intr(struct ata_port *ap, u32 irq_stat) struct ata_link *link = NULL; struct ata_queued_cmd *active_qc; struct ata_eh_info *active_ehi; + bool fbs_need_dec = false; u32 serror; - /* determine active link */ - ata_for_each_link(link, ap, EDGE) - if (ata_link_active(link)) - break; + /* determine active link with error */ + if (pp->fbs_enabled) { + void __iomem *port_mmio = ahci_port_base(ap); + u32 fbs = readl(port_mmio + PORT_FBS); + int pmp = fbs >> PORT_FBS_DWE_OFFSET; + + if ((fbs & PORT_FBS_SDE) && (pmp < ap->nr_pmp_links) && + ata_link_online(&ap->pmp_link[pmp])) { + link = &ap->pmp_link[pmp]; + fbs_need_dec = true; + } + + } else + ata_for_each_link(link, ap, EDGE) + if (ata_link_active(link)) + break; + if (!link) link = &ap->link; @@ -2153,8 +2222,13 @@ static void ahci_error_intr(struct ata_port *ap, u32 irq_stat) } if (irq_stat & PORT_IRQ_IF_ERR) { - host_ehi->err_mask |= AC_ERR_ATA_BUS; - host_ehi->action |= ATA_EH_RESET; + if (fbs_need_dec) + active_ehi->err_mask |= AC_ERR_DEV; + else { + host_ehi->err_mask |= AC_ERR_ATA_BUS; + host_ehi->action |= ATA_EH_RESET; + } + ata_ehi_push_desc(host_ehi, "interface fatal error"); } @@ -2169,7 +2243,10 @@ static void ahci_error_intr(struct ata_port *ap, u32 irq_stat) if (irq_stat & PORT_IRQ_FREEZE) ata_port_freeze(ap); - else + else if (fbs_need_dec) { + ata_link_abort(link); + ahci_fbs_dec_intr(ap); + } else ata_port_abort(ap); } @@ -2222,12 +2299,19 @@ static void ahci_port_intr(struct ata_port *ap) /* If the 'N' bit in word 0 of the FIS is set, * we just received asynchronous notification. * Tell libata about it. + * + * Lack of SNotification should not appear in + * ahci 1.2, so the workaround is unnecessary + * when FBS is enabled. */ - const __le32 *f = pp->rx_fis + RX_FIS_SDB; - u32 f0 = le32_to_cpu(f[0]); - - if (f0 & (1 << 15)) - sata_async_notification(ap); + if (pp->fbs_enabled) + WARN_ON_ONCE(1); + else { + const __le32 *f = pp->rx_fis + RX_FIS_SDB; + u32 f0 = le32_to_cpu(f[0]); + if (f0 & (1 << 15)) + sata_async_notification(ap); + } } } @@ -2321,6 +2405,15 @@ static unsigned int ahci_qc_issue(struct ata_queued_cmd *qc) if (qc->tf.protocol == ATA_PROT_NCQ) writel(1 << qc->tag, port_mmio + PORT_SCR_ACT); + + if (pp->fbs_enabled && pp->fbs_last_dev != qc->dev->link->pmp) { + u32 fbs = readl(port_mmio + PORT_FBS); + fbs &= ~(PORT_FBS_DEV_MASK | PORT_FBS_DEC); + fbs |= qc->dev->link->pmp << PORT_FBS_DEV_OFFSET; + writel(fbs, port_mmio + PORT_FBS); + pp->fbs_last_dev = qc->dev->link->pmp; + } + writel(1 << qc->tag, port_mmio + PORT_CMD_ISSUE); ahci_sw_activity(qc->dev->link); @@ -2333,6 +2426,9 @@ static bool ahci_qc_fill_rtf(struct ata_queued_cmd *qc) struct ahci_port_priv *pp = qc->ap->private_data; u8 *d2h_fis = pp->rx_fis + RX_FIS_D2H_REG; + if (pp->fbs_enabled) + d2h_fis += qc->dev->link->pmp * AHCI_RX_FIS_SZ; + ata_tf_from_fis(d2h_fis, &qc->result_tf); return true; } @@ -2381,6 +2477,71 @@ static void ahci_post_internal_cmd(struct ata_queued_cmd *qc) ahci_kick_engine(ap); } +static void ahci_enable_fbs(struct ata_port *ap) +{ + struct ahci_port_priv *pp = ap->private_data; + void __iomem *port_mmio = ahci_port_base(ap); + u32 fbs; + int rc; + + if (!pp->fbs_supported) + return; + + fbs = readl(port_mmio + PORT_FBS); + if (fbs & PORT_FBS_EN) { + pp->fbs_enabled = true; + pp->fbs_last_dev = -1; /* initialization */ + return; + } + + rc = ahci_stop_engine(ap); + if (rc) + return; + + writel(fbs | PORT_FBS_EN, port_mmio + PORT_FBS); + fbs = readl(port_mmio + PORT_FBS); + if (fbs & PORT_FBS_EN) { + dev_printk(KERN_INFO, ap->host->dev, "FBS is enabled.\n"); + pp->fbs_enabled = true; + pp->fbs_last_dev = -1; /* initialization */ + } else + dev_printk(KERN_ERR, ap->host->dev, "Failed to enable FBS\n"); + + ahci_start_engine(ap); +} + +static void ahci_disable_fbs(struct ata_port *ap) +{ + struct ahci_port_priv *pp = ap->private_data; + void __iomem *port_mmio = ahci_port_base(ap); + u32 fbs; + int rc; + + if (!pp->fbs_supported) + return; + + fbs = readl(port_mmio + PORT_FBS); + if ((fbs & PORT_FBS_EN) == 0) { + pp->fbs_enabled = false; + return; + } + + rc = ahci_stop_engine(ap); + if (rc) + return; + + writel(fbs & ~PORT_FBS_EN, port_mmio + PORT_FBS); + fbs = readl(port_mmio + PORT_FBS); + if (fbs & PORT_FBS_EN) + dev_printk(KERN_ERR, ap->host->dev, "Failed to disable FBS\n"); + else { + dev_printk(KERN_INFO, ap->host->dev, "FBS is disabled.\n"); + pp->fbs_enabled = false; + } + + ahci_start_engine(ap); +} + static void ahci_pmp_attach(struct ata_port *ap) { void __iomem *port_mmio = ahci_port_base(ap); @@ -2391,6 +2552,8 @@ static void ahci_pmp_attach(struct ata_port *ap) cmd |= PORT_CMD_PMP; writel(cmd, port_mmio + PORT_CMD); + ahci_enable_fbs(ap); + pp->intr_mask |= PORT_IRQ_BAD_PMP; writel(pp->intr_mask, port_mmio + PORT_IRQ_MASK); } @@ -2401,6 +2564,8 @@ static void ahci_pmp_detach(struct ata_port *ap) struct ahci_port_priv *pp = ap->private_data; u32 cmd; + ahci_disable_fbs(ap); + cmd = readl(port_mmio + PORT_CMD); cmd &= ~PORT_CMD_PMP; writel(cmd, port_mmio + PORT_CMD); @@ -2492,20 +2657,40 @@ static int ahci_pci_device_resume(struct pci_dev *pdev) static int ahci_port_start(struct ata_port *ap) { + struct ahci_host_priv *hpriv = ap->host->private_data; struct device *dev = ap->host->dev; struct ahci_port_priv *pp; void *mem; dma_addr_t mem_dma; + size_t dma_sz, rx_fis_sz; pp = devm_kzalloc(dev, sizeof(*pp), GFP_KERNEL); if (!pp) return -ENOMEM; - mem = dmam_alloc_coherent(dev, AHCI_PORT_PRIV_DMA_SZ, &mem_dma, - GFP_KERNEL); + /* check FBS capability */ + if ((hpriv->cap & HOST_CAP_FBS) && sata_pmp_supported(ap)) { + void __iomem *port_mmio = ahci_port_base(ap); + u32 cmd = readl(port_mmio + PORT_CMD); + if (cmd & PORT_CMD_FBSCP) + pp->fbs_supported = true; + else + dev_printk(KERN_WARNING, dev, + "The port is not capable of FBS\n"); + } + + if (pp->fbs_supported) { + dma_sz = AHCI_PORT_PRIV_FBS_DMA_SZ; + rx_fis_sz = AHCI_RX_FIS_SZ * 16; + } else { + dma_sz = AHCI_PORT_PRIV_DMA_SZ; + rx_fis_sz = AHCI_RX_FIS_SZ; + } + + mem = dmam_alloc_coherent(dev, dma_sz, &mem_dma, GFP_KERNEL); if (!mem) return -ENOMEM; - memset(mem, 0, AHCI_PORT_PRIV_DMA_SZ); + memset(mem, 0, dma_sz); /* * First item in chunk of DMA memory: 32-slot command table, @@ -2523,8 +2708,8 @@ static int ahci_port_start(struct ata_port *ap) pp->rx_fis = mem; pp->rx_fis_dma = mem_dma; - mem += AHCI_RX_FIS_SZ; - mem_dma += AHCI_RX_FIS_SZ; + mem += rx_fis_sz; + mem_dma += rx_fis_sz; /* * Third item: data area for storing a single command -- cgit v1.2.2 From 5623cab83ea61e0420f2064216d83eab067a24c6 Mon Sep 17 00:00:00 2001 From: Seth Heasley Date: Tue, 12 Jan 2010 17:00:18 -0800 Subject: ahci: AHCI and RAID mode SATA patch for Intel Cougar Point DeviceIDs Signed-off-by: Seth Heasley Signed-off-by: Jeff Garzik --- drivers/ata/ahci.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'drivers') diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index 705bd8b1ea67..89d66fa725a4 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c @@ -589,6 +589,12 @@ static const struct pci_device_id ahci_pci_tbl[] = { { PCI_VDEVICE(INTEL, 0x3b2b), board_ahci }, /* PCH RAID */ { PCI_VDEVICE(INTEL, 0x3b2c), board_ahci }, /* PCH RAID */ { PCI_VDEVICE(INTEL, 0x3b2f), board_ahci }, /* PCH AHCI */ + { PCI_VDEVICE(INTEL, 0x1c02), board_ahci }, /* CPT AHCI */ + { PCI_VDEVICE(INTEL, 0x1c03), board_ahci }, /* CPT AHCI */ + { PCI_VDEVICE(INTEL, 0x1c04), board_ahci }, /* CPT RAID */ + { PCI_VDEVICE(INTEL, 0x1c05), board_ahci }, /* CPT RAID */ + { PCI_VDEVICE(INTEL, 0x1c06), board_ahci }, /* CPT RAID */ + { PCI_VDEVICE(INTEL, 0x1c07), board_ahci }, /* CPT RAID */ /* JMicron 360/1/3/5/6, match class to avoid IDE function */ { PCI_VENDOR_ID_JMICRON, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, -- cgit v1.2.2 From 88e8201e67aace3d86de9e75122ea525f0e7248e Mon Sep 17 00:00:00 2001 From: Seth Heasley Date: Tue, 12 Jan 2010 17:01:28 -0800 Subject: ata_piix: IDE Mode SATA patch for Intel Cougar Point DeviceIDs Signed-off-by: Seth Heasley Signed-off-by: Jeff Garzik --- drivers/ata/ata_piix.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'drivers') diff --git a/drivers/ata/ata_piix.c b/drivers/ata/ata_piix.c index 6f3f2257d0f0..b5f614b9c245 100644 --- a/drivers/ata/ata_piix.c +++ b/drivers/ata/ata_piix.c @@ -291,6 +291,14 @@ static const struct pci_device_id piix_pci_tbl[] = { { 0x8086, 0x3b2d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata }, /* SATA Controller IDE (PCH) */ { 0x8086, 0x3b2e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata }, + /* SATA Controller IDE (CPT) */ + { 0x8086, 0x1c00, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata }, + /* SATA Controller IDE (CPT) */ + { 0x8086, 0x1c01, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata }, + /* SATA Controller IDE (CPT) */ + { 0x8086, 0x1c08, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata }, + /* SATA Controller IDE (CPT) */ + { 0x8086, 0x1c09, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata }, { } /* terminate list */ }; -- cgit v1.2.2 From d88ec2e5c13261cf317b46832a7de216f6d06537 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Tue, 19 Jan 2010 10:46:32 +0900 Subject: libata: cleanup ata_sff_interrupt() host->ports[i] is never NULL if i < host->n_ports and non-NULL return from ata_qc_from_tag() guarantees that the returned qc is active. Drop unnecessary tests. Superflous () dropped as suggested by Sergei. Signed-off-by: Tejun Heo Cc: Sergei Shtylyov Signed-off-by: Jeff Garzik --- drivers/ata/libata-sff.c | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/ata/libata-sff.c b/drivers/ata/libata-sff.c index 730ef3c384ca..c62ed13b0596 100644 --- a/drivers/ata/libata-sff.c +++ b/drivers/ata/libata-sff.c @@ -1770,18 +1770,15 @@ irqreturn_t ata_sff_interrupt(int irq, void *dev_instance) spin_lock_irqsave(&host->lock, flags); for (i = 0; i < host->n_ports; i++) { - struct ata_port *ap; + struct ata_port *ap = host->ports[i]; + struct ata_queued_cmd *qc; - ap = host->ports[i]; - if (ap && - !(ap->flags & ATA_FLAG_DISABLED)) { - struct ata_queued_cmd *qc; + if (unlikely(ap->flags & ATA_FLAG_DISABLED)) + continue; - qc = ata_qc_from_tag(ap, ap->link.active_tag); - if (qc && (!(qc->tf.flags & ATA_TFLAG_POLLING)) && - (qc->flags & ATA_QCFLAG_ACTIVE)) - handled |= ata_sff_host_intr(ap, qc); - } + qc = ata_qc_from_tag(ap, ap->link.active_tag); + if (qc && !(qc->tf.flags & ATA_TFLAG_POLLING)) + handled |= ata_sff_host_intr(ap, qc); } spin_unlock_irqrestore(&host->lock, flags); -- cgit v1.2.2 From 27943620cbd960f710a385ff4a538e14ed3f1922 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Tue, 19 Jan 2010 10:49:19 +0900 Subject: libata: implement spurious irq handling for SFF and apply it to piix Traditional IDE interface sucks in that it doesn't have a reliable IRQ pending bit, so if the controller raises IRQ while the driver is expecting it not to, the IRQ won't be cleared and eventually the IRQ line will be killed by interrupt subsystem. Some controllers have non-standard mechanism to indicate IRQ pending so that this condition can be detected and worked around. This patch adds an optional operation ->sff_irq_check() which will be called for each port from the ata_sff_interrupt() if an unexpected interrupt is received. If the operation returns %true, ->sff_check_status() and ->sff_irq_clear() will be cleared for the port. Note that this doesn't mark the interrupt as handled so it won't prevent IRQ subsystem from killing the IRQ if this mechanism fails to clear the spurious IRQ. This patch also implements ->sff_irq_check() for ata_piix. Note that this adds slight overhead to shared IRQ operation as IRQs which are destined for other controllers will trigger extra register accesses to check whether IDE interrupt is pending but this solves rare screaming IRQ cases and for some curious reason also helps weird BIOS related glitch on Samsung n130 as reported in bko#14314. http://bugzilla.kernel.org/show_bug.cgi?id=14314 * piix_base_ops dropped as suggested by Sergei. * Spurious IRQ detection doesn't kick in anymore if polling qc is in progress. This provides less protection but some controllers have possible data corruption issues if the wrong register is accessed while a command is in progress. Signed-off-by: Tejun Heo Reported-by: Johannes Stezenbach Reported-by: Hans Werner Cc: Alan Cox Cc: Sergei Shtylyov Signed-off-by: Jeff Garzik --- drivers/ata/ata_piix.c | 20 +++++++++++++++----- drivers/ata/libata-sff.c | 35 ++++++++++++++++++++++++++++++++--- 2 files changed, 47 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/ata/ata_piix.c b/drivers/ata/ata_piix.c index b5f614b9c245..c33806654e46 100644 --- a/drivers/ata/ata_piix.c +++ b/drivers/ata/ata_piix.c @@ -173,6 +173,7 @@ static int piix_sidpr_scr_read(struct ata_link *link, unsigned int reg, u32 *val); static int piix_sidpr_scr_write(struct ata_link *link, unsigned int reg, u32 val); +static bool piix_irq_check(struct ata_port *ap); #ifdef CONFIG_PM static int piix_pci_device_suspend(struct pci_dev *pdev, pm_message_t mesg); static int piix_pci_device_resume(struct pci_dev *pdev); @@ -317,8 +318,13 @@ static struct scsi_host_template piix_sht = { ATA_BMDMA_SHT(DRV_NAME), }; -static struct ata_port_operations piix_pata_ops = { +static struct ata_port_operations piix_sata_ops = { .inherits = &ata_bmdma32_port_ops, + .sff_irq_check = piix_irq_check, +}; + +static struct ata_port_operations piix_pata_ops = { + .inherits = &piix_sata_ops, .cable_detect = ata_cable_40wire, .set_piomode = piix_set_piomode, .set_dmamode = piix_set_dmamode, @@ -336,10 +342,6 @@ static struct ata_port_operations ich_pata_ops = { .set_dmamode = ich_set_dmamode, }; -static struct ata_port_operations piix_sata_ops = { - .inherits = &ata_bmdma32_port_ops, -}; - static struct ata_port_operations piix_sidpr_sata_ops = { .inherits = &piix_sata_ops, .hardreset = sata_std_hardreset, @@ -970,6 +972,14 @@ static int piix_sidpr_scr_write(struct ata_link *link, return 0; } +static bool piix_irq_check(struct ata_port *ap) +{ + if (unlikely(!ap->ioaddr.bmdma_addr)) + return false; + + return ap->ops->bmdma_status(ap) & ATA_DMA_INTR; +} + #ifdef CONFIG_PM static int piix_broken_suspend(void) { diff --git a/drivers/ata/libata-sff.c b/drivers/ata/libata-sff.c index c62ed13b0596..c2661ea70330 100644 --- a/drivers/ata/libata-sff.c +++ b/drivers/ata/libata-sff.c @@ -1763,7 +1763,7 @@ irqreturn_t ata_sff_interrupt(int irq, void *dev_instance) { struct ata_host *host = dev_instance; unsigned int i; - unsigned int handled = 0; + unsigned int handled = 0, polling = 0; unsigned long flags; /* TODO: make _irqsave conditional on x86 PCI IDE legacy mode */ @@ -1777,8 +1777,37 @@ irqreturn_t ata_sff_interrupt(int irq, void *dev_instance) continue; qc = ata_qc_from_tag(ap, ap->link.active_tag); - if (qc && !(qc->tf.flags & ATA_TFLAG_POLLING)) - handled |= ata_sff_host_intr(ap, qc); + if (qc) { + if (!(qc->tf.flags & ATA_TFLAG_POLLING)) + handled |= ata_sff_host_intr(ap, qc); + else + polling |= 1 << i; + } + } + + /* + * If no port was expecting IRQ but the controller is actually + * asserting IRQ line, nobody cared will ensue. Check IRQ + * pending status if available and clear spurious IRQ. + */ + if (!handled) { + for (i = 0; i < host->n_ports; i++) { + struct ata_port *ap = host->ports[i]; + + if (polling & (1 << i)) + continue; + + if (!ap->ops->sff_irq_check || + !ap->ops->sff_irq_check(ap)) + continue; + + if (printk_ratelimit()) + ata_port_printk(ap, KERN_INFO, + "clearing spurious IRQ\n"); + + ap->ops->sff_check_status(ap); + ap->ops->sff_irq_clear(ap); + } } spin_unlock_irqrestore(&host->lock, flags); -- cgit v1.2.2 From 9ffc5da5e1e57592da9c22d83a98c63afc8d985c Mon Sep 17 00:00:00 2001 From: Robert Hancock Date: Tue, 19 Jan 2010 23:03:39 -0600 Subject: libata: make functions/variables static Make some variables in ahci and a function in pata_pcmcia static, as found using sparse. Signed-off-by: Robert Hancock Signed-off-by: Jeff Garzik --- drivers/ata/ahci.c | 8 ++++---- drivers/ata/pata_pcmcia.c | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index 89d66fa725a4..6bd930b93bcc 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c @@ -375,10 +375,10 @@ static ssize_t ahci_show_host_version(struct device *dev, static ssize_t ahci_show_port_cmd(struct device *dev, struct device_attribute *attr, char *buf); -DEVICE_ATTR(ahci_host_caps, S_IRUGO, ahci_show_host_caps, NULL); -DEVICE_ATTR(ahci_host_cap2, S_IRUGO, ahci_show_host_cap2, NULL); -DEVICE_ATTR(ahci_host_version, S_IRUGO, ahci_show_host_version, NULL); -DEVICE_ATTR(ahci_port_cmd, S_IRUGO, ahci_show_port_cmd, NULL); +static DEVICE_ATTR(ahci_host_caps, S_IRUGO, ahci_show_host_caps, NULL); +static DEVICE_ATTR(ahci_host_cap2, S_IRUGO, ahci_show_host_cap2, NULL); +static DEVICE_ATTR(ahci_host_version, S_IRUGO, ahci_show_host_version, NULL); +static DEVICE_ATTR(ahci_port_cmd, S_IRUGO, ahci_show_port_cmd, NULL); static struct device_attribute *ahci_shost_attrs[] = { &dev_attr_link_power_management_policy, diff --git a/drivers/ata/pata_pcmcia.c b/drivers/ata/pata_pcmcia.c index 1b392c9e8531..36103531feeb 100644 --- a/drivers/ata/pata_pcmcia.c +++ b/drivers/ata/pata_pcmcia.c @@ -136,7 +136,7 @@ static unsigned int ata_data_xfer_8bit(struct ata_device *dev, * */ -void pcmcia_8bit_drain_fifo(struct ata_queued_cmd *qc) +static void pcmcia_8bit_drain_fifo(struct ata_queued_cmd *qc) { int count; struct ata_port *ap; -- cgit v1.2.2 From 02d1d6160ffe13f4ebc6f85f72366a5da0b1fb9b Mon Sep 17 00:00:00 2001 From: Bart Hartgers Date: Sun, 17 Jan 2010 00:56:54 +0100 Subject: sata_via: Correctly setup PIO/DMA for pata slave on vt6421. Before only the timings for master were set. Datasheet can be found here: ftp://ftp.vtbridge.org/Docs/Storage/DS_VT6421A_100_CCPL.PDF Surprisingly, a slave drive works without this patch. According to the datasheet, the controller by default derives the DMA mode from the Set Features command issued to a drive. Not sure about the PIO timings, though. The real problem is that the timings for the master effectively are the ones tuned for the slave. If these support different UDMA-settings, there is trouble, especially when the slave supports a higher UDMA than the master. Anyhow, using the same mechanism for both master and slave seems like a good idea. Signed-off-by: Bart Hartgers Acked-by: Tejun Heo Signed-off-by: Jeff Garzik --- drivers/ata/sata_via.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/ata/sata_via.c b/drivers/ata/sata_via.c index 02efd9a83d26..2a17fa375164 100644 --- a/drivers/ata/sata_via.c +++ b/drivers/ata/sata_via.c @@ -44,7 +44,7 @@ #include #define DRV_NAME "sata_via" -#define DRV_VERSION "2.4" +#define DRV_VERSION "2.5" /* * vt8251 is different from other sata controllers of VIA. It has two @@ -392,14 +392,16 @@ static void vt6421_set_pio_mode(struct ata_port *ap, struct ata_device *adev) { struct pci_dev *pdev = to_pci_dev(ap->host->dev); static const u8 pio_bits[] = { 0xA8, 0x65, 0x65, 0x31, 0x20 }; - pci_write_config_byte(pdev, PATA_PIO_TIMING, pio_bits[adev->pio_mode - XFER_PIO_0]); + pci_write_config_byte(pdev, PATA_PIO_TIMING - adev->devno, + pio_bits[adev->pio_mode - XFER_PIO_0]); } static void vt6421_set_dma_mode(struct ata_port *ap, struct ata_device *adev) { struct pci_dev *pdev = to_pci_dev(ap->host->dev); static const u8 udma_bits[] = { 0xEE, 0xE8, 0xE6, 0xE4, 0xE2, 0xE1, 0xE0, 0xE0 }; - pci_write_config_byte(pdev, PATA_UDMA_TIMING, udma_bits[adev->dma_mode - XFER_UDMA_0]); + pci_write_config_byte(pdev, PATA_UDMA_TIMING - adev->devno, + udma_bits[adev->dma_mode - XFER_UDMA_0]); } static const unsigned int svia_bar_sizes[] = { -- cgit v1.2.2 From 9e8808a99c6decdb4ab78081a26d3752339f424c Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 18 Jan 2010 18:13:57 +0100 Subject: libata: fix CFA handling in ide_timing_compute() Use standard cycle timing for CFA PIO5 and PIO6 modes. Based on commit 74638c8 for IDE subsystem. Signed-off-by: Bartlomiej Zolnierkiewicz Signed-off-by: Jeff Garzik --- drivers/ata/libata-core.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 6728328f3bea..9c77b0d1a9d0 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -3211,6 +3211,7 @@ const struct ata_timing *ata_timing_find_mode(u8 xfer_mode) int ata_timing_compute(struct ata_device *adev, unsigned short speed, struct ata_timing *t, int T, int UT) { + const u16 *id = adev->id; const struct ata_timing *s; struct ata_timing p; @@ -3228,14 +3229,18 @@ int ata_timing_compute(struct ata_device *adev, unsigned short speed, * PIO/MW_DMA cycle timing. */ - if (adev->id[ATA_ID_FIELD_VALID] & 2) { /* EIDE drive */ + if (id[ATA_ID_FIELD_VALID] & 2) { /* EIDE drive */ memset(&p, 0, sizeof(p)); + if (speed >= XFER_PIO_0 && speed <= XFER_SW_DMA_0) { - if (speed <= XFER_PIO_2) p.cycle = p.cyc8b = adev->id[ATA_ID_EIDE_PIO]; - else p.cycle = p.cyc8b = adev->id[ATA_ID_EIDE_PIO_IORDY]; - } else if (speed >= XFER_MW_DMA_0 && speed <= XFER_MW_DMA_2) { - p.cycle = adev->id[ATA_ID_EIDE_DMA_MIN]; - } + if (speed <= XFER_PIO_2) + p.cycle = p.cyc8b = id[ATA_ID_EIDE_PIO]; + else if ((speed <= XFER_PIO_4) || + (speed == XFER_PIO_5 && !ata_id_is_cfa(id))) + p.cycle = p.cyc8b = id[ATA_ID_EIDE_PIO_IORDY]; + } else if (speed >= XFER_MW_DMA_0 && speed <= XFER_MW_DMA_2) + p.cycle = id[ATA_ID_EIDE_DMA_MIN]; + ata_timing_merge(&p, t, t, ATA_TIMING_CYCLE | ATA_TIMING_CYC8B); } -- cgit v1.2.2 From d8b3d8cfe6240178ac717e143438bf51364311e4 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 18 Jan 2010 18:14:05 +0100 Subject: pata_ali: documentation fixes Signed-off-by: Bartlomiej Zolnierkiewicz Signed-off-by: Jeff Garzik --- drivers/ata/pata_ali.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/ata/pata_ali.c b/drivers/ata/pata_ali.c index 9434114b2ca8..63ba48c9af33 100644 --- a/drivers/ata/pata_ali.c +++ b/drivers/ata/pata_ali.c @@ -159,8 +159,7 @@ static void ali_fifo_control(struct ata_port *ap, struct ata_device *adev, int o * ali_program_modes - load mode registers * @ap: ALi channel to load * @adev: Device the timing is for - * @cmd: Command timing - * @data: Data timing + * @t: timing data * @ultra: UDMA timing or zero for off * * Loads the timing registers for cmd/data and disable UDMA if @@ -202,8 +201,7 @@ static void ali_program_modes(struct ata_port *ap, struct ata_device *adev, stru * @ap: ATA interface * @adev: ATA device * - * Program the ALi registers for PIO mode. FIXME: add timings for - * PIO5. + * Program the ALi registers for PIO mode. */ static void ali_set_piomode(struct ata_port *ap, struct ata_device *adev) @@ -237,7 +235,7 @@ static void ali_set_piomode(struct ata_port *ap, struct ata_device *adev) * @ap: ATA interface * @adev: ATA device * - * FIXME: MWDMA timings + * Program the ALi registers for DMA mode. */ static void ali_set_dmamode(struct ata_port *ap, struct ata_device *adev) -- cgit v1.2.2 From a2bd62207af4be8f5fe815ff90cc309056407829 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 18 Jan 2010 18:14:55 +0100 Subject: pata_cmd64x: fix PIO setup Fix incorrect handling of recovery clocks value == 16 resulting in overclocked recovery timings & potentially underclocked active timings. Signed-off-by: Bartlomiej Zolnierkiewicz Signed-off-by: Jeff Garzik --- drivers/ata/pata_cmd64x.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/ata/pata_cmd64x.c b/drivers/ata/pata_cmd64x.c index 0efb1f58f255..db08c9d1a333 100644 --- a/drivers/ata/pata_cmd64x.c +++ b/drivers/ata/pata_cmd64x.c @@ -2,6 +2,7 @@ * pata_cmd64x.c - CMD64x PATA for new ATA layer * (C) 2005 Red Hat Inc * Alan Cox + * (C) 2009-2010 Bartlomiej Zolnierkiewicz * * Based upon * linux/drivers/ide/pci/cmd64x.c Version 1.30 Sept 10, 2002 @@ -147,7 +148,9 @@ static void cmd64x_set_timing(struct ata_port *ap, struct ata_device *adev, u8 m /* Now convert the clocks into values we can actually stuff into the chip */ - if (t.recover > 1) + if (t.recover == 16) + t.recover = 0; + else if (t.recover > 1) t.recover--; else t.recover = 15; -- cgit v1.2.2 From d62f5576efc4886c0f3633c2652c3a924e043be9 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 18 Jan 2010 18:15:04 +0100 Subject: pata_cmd64x: fix handling of address setup timings Account for the requirements of the DMA mode currently used by the pair device. Signed-off-by: Bartlomiej Zolnierkiewicz Signed-off-by: Jeff Garzik --- drivers/ata/pata_cmd64x.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'drivers') diff --git a/drivers/ata/pata_cmd64x.c b/drivers/ata/pata_cmd64x.c index db08c9d1a333..0235a1d3c2fb 100644 --- a/drivers/ata/pata_cmd64x.c +++ b/drivers/ata/pata_cmd64x.c @@ -131,8 +131,14 @@ static void cmd64x_set_timing(struct ata_port *ap, struct ata_device *adev, u8 m if (pair) { struct ata_timing tp; + ata_timing_compute(pair, pair->pio_mode, &tp, T, 0); ata_timing_merge(&t, &tp, &t, ATA_TIMING_SETUP); + if (pair->dma_mode) { + ata_timing_compute(pair, pair->dma_mode, + &tp, T, 0); + ata_timing_merge(&tp, &t, &t, ATA_TIMING_SETUP); + } } } -- cgit v1.2.2 From 03a849e6ddb604ff6a220b78637ee8e122ffc796 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 18 Jan 2010 18:15:11 +0100 Subject: pata_cmd64x: cmd648_bmdma_stop() fix Clear the primary channel pending interrupt bit instead of the reserved one. Signed-off-by: Bartlomiej Zolnierkiewicz Signed-off-by: Jeff Garzik --- drivers/ata/pata_cmd64x.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/ata/pata_cmd64x.c b/drivers/ata/pata_cmd64x.c index 0235a1d3c2fb..7bc00d5fa600 100644 --- a/drivers/ata/pata_cmd64x.c +++ b/drivers/ata/pata_cmd64x.c @@ -40,7 +40,7 @@ enum { CFR = 0x50, - CFR_INTR_CH0 = 0x02, + CFR_INTR_CH0 = 0x04, CNTRL = 0x51, CNTRL_DIS_RA0 = 0x40, CNTRL_DIS_RA1 = 0x80, -- cgit v1.2.2 From c754d9b6e04371fb398cdd2f5e77be895126be20 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 18 Jan 2010 18:15:18 +0100 Subject: pata_cmd64x: remove unused definitions s/ARTIM2/ARTTIM23/ in cmd648_bmdma_stop() while at it Signed-off-by: Bartlomiej Zolnierkiewicz Signed-off-by: Jeff Garzik --- drivers/ata/pata_cmd64x.c | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/ata/pata_cmd64x.c b/drivers/ata/pata_cmd64x.c index 7bc00d5fa600..b40bf0f29975 100644 --- a/drivers/ata/pata_cmd64x.c +++ b/drivers/ata/pata_cmd64x.c @@ -41,10 +41,6 @@ enum { CFR = 0x50, CFR_INTR_CH0 = 0x04, - CNTRL = 0x51, - CNTRL_DIS_RA0 = 0x40, - CNTRL_DIS_RA1 = 0x80, - CNTRL_ENA_2ND = 0x08, CMDTIM = 0x52, ARTTIM0 = 0x53, DRWTIM0 = 0x54, @@ -54,9 +50,6 @@ enum { ARTTIM23_DIS_RA2 = 0x04, ARTTIM23_DIS_RA3 = 0x08, ARTTIM23_INTR_CH1 = 0x10, - ARTTIM2 = 0x57, - ARTTIM3 = 0x57, - DRWTIM23 = 0x58, DRWTIM2 = 0x58, BRST = 0x59, DRWTIM3 = 0x5b, @@ -64,14 +57,11 @@ enum { MRDMODE = 0x71, MRDMODE_INTR_CH0 = 0x04, MRDMODE_INTR_CH1 = 0x08, - MRDMODE_BLK_CH0 = 0x10, - MRDMODE_BLK_CH1 = 0x20, BMIDESR0 = 0x72, UDIDETCR0 = 0x73, DTPR0 = 0x74, BMIDECR1 = 0x78, BMIDECSR = 0x79, - BMIDESR1 = 0x7A, UDIDETCR1 = 0x7B, DTPR1 = 0x7C }; @@ -254,7 +244,7 @@ static void cmd648_bmdma_stop(struct ata_queued_cmd *qc) struct pci_dev *pdev = to_pci_dev(ap->host->dev); u8 dma_intr; int dma_mask = ap->port_no ? ARTTIM23_INTR_CH1 : CFR_INTR_CH0; - int dma_reg = ap->port_no ? ARTTIM2 : CFR; + int dma_reg = ap->port_no ? ARTTIM23 : CFR; ata_bmdma_stop(qc); -- cgit v1.2.2 From 8ebf473860e8166e3d4f152a02e22b9cdddcd440 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 18 Jan 2010 18:15:38 +0100 Subject: pata_cs5535: use correct values for PIO1 and PIO2 data timings There shouldn't be any problems with it as IDE cs5535 host driver has been using those values for years and they match values given in the (publicly available) datasheet. Signed-off-by: Bartlomiej Zolnierkiewicz Signed-off-by: Jeff Garzik --- drivers/ata/pata_cs5535.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/ata/pata_cs5535.c b/drivers/ata/pata_cs5535.c index 71cef9a962d4..c50c3a42b10b 100644 --- a/drivers/ata/pata_cs5535.c +++ b/drivers/ata/pata_cs5535.c @@ -100,7 +100,7 @@ static int cs5535_cable_detect(struct ata_port *ap) static void cs5535_set_piomode(struct ata_port *ap, struct ata_device *adev) { static const u16 pio_timings[5] = { - 0xF7F4, 0x53F3, 0x13F1, 0x5131, 0x1131 + 0xF7F4, 0xF173, 0x8141, 0x5131, 0x1131 }; static const u16 pio_cmd_timings[5] = { 0xF7F4, 0x53F3, 0x13F1, 0x5131, 0x1131 -- cgit v1.2.2 From 3403c24529ddfb4a47f5cfe8496370997f1b0758 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 18 Jan 2010 18:15:47 +0100 Subject: pata_cypress: fix PIO timings underclocking Timing registers should be programmed with the desired number of clocks minus one clock. Signed-off-by: Bartlomiej Zolnierkiewicz Signed-off-by: Jeff Garzik --- drivers/ata/pata_cypress.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/ata/pata_cypress.c b/drivers/ata/pata_cypress.c index 8fb040bf7361..ff6c37de5a12 100644 --- a/drivers/ata/pata_cypress.c +++ b/drivers/ata/pata_cypress.c @@ -62,14 +62,16 @@ static void cy82c693_set_piomode(struct ata_port *ap, struct ata_device *adev) return; } - time_16 = clamp_val(t.recover, 0, 15) | (clamp_val(t.active, 0, 15) << 4); - time_8 = clamp_val(t.act8b, 0, 15) | (clamp_val(t.rec8b, 0, 15) << 4); + time_16 = clamp_val(t.recover - 1, 0, 15) | + (clamp_val(t.active - 1, 0, 15) << 4); + time_8 = clamp_val(t.act8b - 1, 0, 15) | + (clamp_val(t.rec8b - 1, 0, 15) << 4); if (adev->devno == 0) { pci_read_config_dword(pdev, CY82_IDE_ADDRSETUP, &addr); addr &= ~0x0F; /* Mask bits */ - addr |= clamp_val(t.setup, 0, 15); + addr |= clamp_val(t.setup - 1, 0, 15); pci_write_config_dword(pdev, CY82_IDE_ADDRSETUP, addr); pci_write_config_byte(pdev, CY82_IDE_MASTER_IOR, time_16); @@ -79,7 +81,7 @@ static void cy82c693_set_piomode(struct ata_port *ap, struct ata_device *adev) pci_read_config_dword(pdev, CY82_IDE_ADDRSETUP, &addr); addr &= ~0xF0; /* Mask bits */ - addr |= (clamp_val(t.setup, 0, 15) << 4); + addr |= (clamp_val(t.setup - 1, 0, 15) << 4); pci_write_config_dword(pdev, CY82_IDE_ADDRSETUP, addr); pci_write_config_byte(pdev, CY82_IDE_SLAVE_IOR, time_16); -- cgit v1.2.2 From 73e2e3d0e9d4b5781c66eca8a901e6478c25ae7d Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 18 Jan 2010 18:16:03 +0100 Subject: pata_efar: fix secondary port support Signed-off-by: Bartlomiej Zolnierkiewicz Signed-off-by: Jeff Garzik --- drivers/ata/pata_efar.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/ata/pata_efar.c b/drivers/ata/pata_efar.c index b2e71e6473ed..89076d58111b 100644 --- a/drivers/ata/pata_efar.c +++ b/drivers/ata/pata_efar.c @@ -2,7 +2,7 @@ * pata_efar.c - EFAR PIIX clone controller driver * * (C) 2005 Red Hat - * (C) 2009 Bartlomiej Zolnierkiewicz + * (C) 2009-2010 Bartlomiej Zolnierkiewicz * * Some parts based on ata_piix.c by Jeff Garzik and others. * @@ -256,7 +256,7 @@ static int efar_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) .udma_mask = ATA_UDMA4, .port_ops = &efar_ops, }; - const struct ata_port_info *ppi[] = { &info, NULL }; + const struct ata_port_info *ppi[] = { &info, &info }; if (!printed_version++) dev_printk(KERN_DEBUG, &pdev->dev, -- cgit v1.2.2 From 8490377acc0869d660185bd4a9e360363d110a21 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 18 Jan 2010 18:16:38 +0100 Subject: pata_serverworks: fix PIO setup for the second channel Signed-off-by: Bartlomiej Zolnierkiewicz Signed-off-by: Jeff Garzik --- drivers/ata/pata_serverworks.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/ata/pata_serverworks.c b/drivers/ata/pata_serverworks.c index beaed12d50e4..9acabd2e336a 100644 --- a/drivers/ata/pata_serverworks.c +++ b/drivers/ata/pata_serverworks.c @@ -1,6 +1,7 @@ /* * pata_serverworks.c - Serverworks PATA for new ATA layer * (C) 2005 Red Hat Inc + * (C) 2010 Bartlomiej Zolnierkiewicz * * based upon * @@ -253,7 +254,7 @@ static void serverworks_set_piomode(struct ata_port *ap, struct ata_device *adev if (serverworks_is_csb(pdev)) { pci_read_config_word(pdev, 0x4A, &csb5_pio); csb5_pio &= ~(0x0F << devbits); - pci_write_config_byte(pdev, 0x4A, csb5_pio | (pio << devbits)); + pci_write_config_word(pdev, 0x4A, csb5_pio | (pio << devbits)); } } -- cgit v1.2.2 From cfcf9ee26a5991f0786d24b4bd334b103d06268e Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 18 Jan 2010 18:16:46 +0100 Subject: pata_serverworks: fix error message Signed-off-by: Bartlomiej Zolnierkiewicz Signed-off-by: Jeff Garzik --- drivers/ata/pata_serverworks.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/ata/pata_serverworks.c b/drivers/ata/pata_serverworks.c index 9acabd2e336a..c85976720a0c 100644 --- a/drivers/ata/pata_serverworks.c +++ b/drivers/ata/pata_serverworks.c @@ -328,7 +328,7 @@ static int serverworks_fixup_osb4(struct pci_dev *pdev) pci_dev_put(isa_dev); return 0; } - printk(KERN_WARNING "ata_serverworks: Unable to find bridge.\n"); + printk(KERN_WARNING DRV_NAME ": Unable to find bridge.\n"); return -ENODEV; } -- cgit v1.2.2 From f777582f4963413320ce5fe1d1d3651a32075c07 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 18 Jan 2010 18:17:03 +0100 Subject: pata_via: fix address setup timings underlocking Correct via_do_set_mode() documentation while at it. Signed-off-by: Bartlomiej Zolnierkiewicz Signed-off-by: Jeff Garzik --- drivers/ata/pata_via.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/ata/pata_via.c b/drivers/ata/pata_via.c index 0d97890af681..82e75a1f1b95 100644 --- a/drivers/ata/pata_via.c +++ b/drivers/ata/pata_via.c @@ -229,7 +229,7 @@ static int via_pre_reset(struct ata_link *link, unsigned long deadline) /** - * via_do_set_mode - set initial PIO mode data + * via_do_set_mode - set transfer mode data * @ap: ATA interface * @adev: ATA device * @mode: ATA mode being programmed @@ -273,7 +273,7 @@ static void via_do_set_mode(struct ata_port *ap, struct ata_device *adev, int mo pci_read_config_byte(pdev, 0x4C, &setup); setup &= ~(3 << shift); - setup |= clamp_val(t.setup, 1, 4) << shift; /* 1,4 or 1,4 - 1 FIXME */ + setup |= (clamp_val(t.setup, 1, 4) - 1) << shift; pci_write_config_byte(pdev, 0x4C, setup); } -- cgit v1.2.2 From 460f5318460a9a3b2562d8055b9fb1c60b768e1f Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 18 Jan 2010 18:17:12 +0100 Subject: pata_via: store UDMA masks in via_isa_bridges table * store UDMA masks in via_isa_bridges[] and while at it make "flags" field to be u8 instead of u16 * convert the driver to use UDMA masks from via_isa_bridges[] * remove no longer needed VIA_UDMA* defines Make some minor documentation and CodingStyle fixes while at it. Signed-off-by: Bartlomiej Zolnierkiewicz Signed-off-by: Jeff Garzik --- drivers/ata/pata_via.c | 204 +++++++++++++++++++++++-------------------------- 1 file changed, 94 insertions(+), 110 deletions(-) (limited to 'drivers') diff --git a/drivers/ata/pata_via.c b/drivers/ata/pata_via.c index 82e75a1f1b95..6356377231fd 100644 --- a/drivers/ata/pata_via.c +++ b/drivers/ata/pata_via.c @@ -22,6 +22,7 @@ * VIA VT8233c - UDMA100 * VIA VT8235 - UDMA133 * VIA VT8237 - UDMA133 + * VIA VT8237A - UDMA133 * VIA VT8237S - UDMA133 * VIA VT8251 - UDMA133 * @@ -64,26 +65,15 @@ #define DRV_NAME "pata_via" #define DRV_VERSION "0.3.4" -/* - * The following comes directly from Vojtech Pavlik's ide/pci/via82cxxx - * driver. - */ - enum { - VIA_UDMA = 0x007, - VIA_UDMA_NONE = 0x000, - VIA_UDMA_33 = 0x001, - VIA_UDMA_66 = 0x002, - VIA_UDMA_100 = 0x003, - VIA_UDMA_133 = 0x004, - VIA_BAD_PREQ = 0x010, /* Crashes if PREQ# till DDACK# set */ - VIA_BAD_CLK66 = 0x020, /* 66 MHz clock doesn't work correctly */ - VIA_SET_FIFO = 0x040, /* Needs to have FIFO split set */ - VIA_NO_UNMASK = 0x080, /* Doesn't work with IRQ unmasking on */ - VIA_BAD_ID = 0x100, /* Has wrong vendor ID (0x1107) */ - VIA_BAD_AST = 0x200, /* Don't touch Address Setup Timing */ - VIA_NO_ENABLES = 0x400, /* Has no enablebits */ - VIA_SATA_PATA = 0x800, /* SATA/PATA combined configuration */ + VIA_BAD_PREQ = 0x01, /* Crashes if PREQ# till DDACK# set */ + VIA_BAD_CLK66 = 0x02, /* 66 MHz clock doesn't work correctly */ + VIA_SET_FIFO = 0x04, /* Needs to have FIFO split set */ + VIA_NO_UNMASK = 0x08, /* Doesn't work with IRQ unmasking on */ + VIA_BAD_ID = 0x10, /* Has wrong vendor ID (0x1107) */ + VIA_BAD_AST = 0x20, /* Don't touch Address Setup Timing */ + VIA_NO_ENABLES = 0x40, /* Has no enablebits */ + VIA_SATA_PATA = 0x80, /* SATA/PATA combined configuration */ }; enum { @@ -99,40 +89,37 @@ static const struct via_isa_bridge { u16 id; u8 rev_min; u8 rev_max; - u16 flags; + u8 udma_mask; + u8 flags; } via_isa_bridges[] = { - { "vx855", PCI_DEVICE_ID_VIA_VX855, 0x00, 0x2f, - VIA_UDMA_133 | VIA_BAD_AST | VIA_SATA_PATA }, - { "vx800", PCI_DEVICE_ID_VIA_VX800, 0x00, 0x2f, VIA_UDMA_133 | - VIA_BAD_AST | VIA_SATA_PATA }, - { "vt8261", PCI_DEVICE_ID_VIA_8261, 0x00, 0x2f, - VIA_UDMA_133 | VIA_BAD_AST }, - { "vt8237s", PCI_DEVICE_ID_VIA_8237S, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST }, - { "vt8251", PCI_DEVICE_ID_VIA_8251, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST }, - { "cx700", PCI_DEVICE_ID_VIA_CX700, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST | VIA_SATA_PATA }, - { "vt6410", PCI_DEVICE_ID_VIA_6410, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST | VIA_NO_ENABLES }, - { "vt6415", PCI_DEVICE_ID_VIA_6415, 0x00, 0xff, VIA_UDMA_133 | VIA_BAD_AST | VIA_NO_ENABLES }, - { "vt8237a", PCI_DEVICE_ID_VIA_8237A, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST }, - { "vt8237", PCI_DEVICE_ID_VIA_8237, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST }, - { "vt8235", PCI_DEVICE_ID_VIA_8235, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST }, - { "vt8233a", PCI_DEVICE_ID_VIA_8233A, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST }, - { "vt8233c", PCI_DEVICE_ID_VIA_8233C_0, 0x00, 0x2f, VIA_UDMA_100 }, - { "vt8233", PCI_DEVICE_ID_VIA_8233_0, 0x00, 0x2f, VIA_UDMA_100 }, - { "vt8231", PCI_DEVICE_ID_VIA_8231, 0x00, 0x2f, VIA_UDMA_100 }, - { "vt82c686b", PCI_DEVICE_ID_VIA_82C686, 0x40, 0x4f, VIA_UDMA_100 }, - { "vt82c686a", PCI_DEVICE_ID_VIA_82C686, 0x10, 0x2f, VIA_UDMA_66 }, - { "vt82c686", PCI_DEVICE_ID_VIA_82C686, 0x00, 0x0f, VIA_UDMA_33 | VIA_BAD_CLK66 }, - { "vt82c596b", PCI_DEVICE_ID_VIA_82C596, 0x10, 0x2f, VIA_UDMA_66 }, - { "vt82c596a", PCI_DEVICE_ID_VIA_82C596, 0x00, 0x0f, VIA_UDMA_33 | VIA_BAD_CLK66 }, - { "vt82c586b", PCI_DEVICE_ID_VIA_82C586_0, 0x47, 0x4f, VIA_UDMA_33 | VIA_SET_FIFO }, - { "vt82c586b", PCI_DEVICE_ID_VIA_82C586_0, 0x40, 0x46, VIA_UDMA_33 | VIA_SET_FIFO | VIA_BAD_PREQ }, - { "vt82c586b", PCI_DEVICE_ID_VIA_82C586_0, 0x30, 0x3f, VIA_UDMA_33 | VIA_SET_FIFO }, - { "vt82c586a", PCI_DEVICE_ID_VIA_82C586_0, 0x20, 0x2f, VIA_UDMA_33 | VIA_SET_FIFO }, - { "vt82c586", PCI_DEVICE_ID_VIA_82C586_0, 0x00, 0x0f, VIA_UDMA_NONE | VIA_SET_FIFO }, - { "vt82c576", PCI_DEVICE_ID_VIA_82C576, 0x00, 0x2f, VIA_UDMA_NONE | VIA_SET_FIFO | VIA_NO_UNMASK }, - { "vt82c576", PCI_DEVICE_ID_VIA_82C576, 0x00, 0x2f, VIA_UDMA_NONE | VIA_SET_FIFO | VIA_NO_UNMASK | VIA_BAD_ID }, - { "vtxxxx", PCI_DEVICE_ID_VIA_ANON, 0x00, 0x2f, - VIA_UDMA_133 | VIA_BAD_AST }, + { "vx855", PCI_DEVICE_ID_VIA_VX855, 0x00, 0x2f, ATA_UDMA6, VIA_BAD_AST | VIA_SATA_PATA }, + { "vx800", PCI_DEVICE_ID_VIA_VX800, 0x00, 0x2f, ATA_UDMA6, VIA_BAD_AST | VIA_SATA_PATA }, + { "vt8261", PCI_DEVICE_ID_VIA_8261, 0x00, 0x2f, ATA_UDMA6, VIA_BAD_AST }, + { "vt8237s", PCI_DEVICE_ID_VIA_8237S, 0x00, 0x2f, ATA_UDMA6, VIA_BAD_AST }, + { "vt8251", PCI_DEVICE_ID_VIA_8251, 0x00, 0x2f, ATA_UDMA6, VIA_BAD_AST }, + { "cx700", PCI_DEVICE_ID_VIA_CX700, 0x00, 0x2f, ATA_UDMA6, VIA_BAD_AST | VIA_SATA_PATA }, + { "vt6410", PCI_DEVICE_ID_VIA_6410, 0x00, 0x2f, ATA_UDMA6, VIA_BAD_AST | VIA_NO_ENABLES }, + { "vt6415", PCI_DEVICE_ID_VIA_6415, 0x00, 0xff, ATA_UDMA6, VIA_BAD_AST | VIA_NO_ENABLES }, + { "vt8237a", PCI_DEVICE_ID_VIA_8237A, 0x00, 0x2f, ATA_UDMA6, VIA_BAD_AST }, + { "vt8237", PCI_DEVICE_ID_VIA_8237, 0x00, 0x2f, ATA_UDMA6, VIA_BAD_AST }, + { "vt8235", PCI_DEVICE_ID_VIA_8235, 0x00, 0x2f, ATA_UDMA6, VIA_BAD_AST }, + { "vt8233a", PCI_DEVICE_ID_VIA_8233A, 0x00, 0x2f, ATA_UDMA6, VIA_BAD_AST }, + { "vt8233c", PCI_DEVICE_ID_VIA_8233C_0, 0x00, 0x2f, ATA_UDMA5, }, + { "vt8233", PCI_DEVICE_ID_VIA_8233_0, 0x00, 0x2f, ATA_UDMA5, }, + { "vt8231", PCI_DEVICE_ID_VIA_8231, 0x00, 0x2f, ATA_UDMA5, }, + { "vt82c686b", PCI_DEVICE_ID_VIA_82C686, 0x40, 0x4f, ATA_UDMA5, }, + { "vt82c686a", PCI_DEVICE_ID_VIA_82C686, 0x10, 0x2f, ATA_UDMA4, }, + { "vt82c686", PCI_DEVICE_ID_VIA_82C686, 0x00, 0x0f, ATA_UDMA2, VIA_BAD_CLK66 }, + { "vt82c596b", PCI_DEVICE_ID_VIA_82C596, 0x10, 0x2f, ATA_UDMA4, }, + { "vt82c596a", PCI_DEVICE_ID_VIA_82C596, 0x00, 0x0f, ATA_UDMA2, VIA_BAD_CLK66 }, + { "vt82c586b", PCI_DEVICE_ID_VIA_82C586_0, 0x47, 0x4f, ATA_UDMA2, VIA_SET_FIFO }, + { "vt82c586b", PCI_DEVICE_ID_VIA_82C586_0, 0x40, 0x46, ATA_UDMA2, VIA_SET_FIFO | VIA_BAD_PREQ }, + { "vt82c586b", PCI_DEVICE_ID_VIA_82C586_0, 0x30, 0x3f, ATA_UDMA2, VIA_SET_FIFO }, + { "vt82c586a", PCI_DEVICE_ID_VIA_82C586_0, 0x20, 0x2f, ATA_UDMA2, VIA_SET_FIFO }, + { "vt82c586", PCI_DEVICE_ID_VIA_82C586_0, 0x00, 0x0f, 0x00, VIA_SET_FIFO }, + { "vt82c576", PCI_DEVICE_ID_VIA_82C576, 0x00, 0x2f, 0x00, VIA_SET_FIFO | VIA_NO_UNMASK }, + { "vt82c576", PCI_DEVICE_ID_VIA_82C576, 0x00, 0x2f, 0x00, VIA_SET_FIFO | VIA_NO_UNMASK | VIA_BAD_ID }, + { "vtxxxx", PCI_DEVICE_ID_VIA_ANON, 0x00, 0x2f, ATA_UDMA6, VIA_BAD_AST }, { NULL } }; @@ -191,10 +178,10 @@ static int via_cable_detect(struct ata_port *ap) { return ATA_CBL_SATA; /* Early chips are 40 wire */ - if ((config->flags & VIA_UDMA) < VIA_UDMA_66) + if (config->udma_mask < ATA_UDMA4) return ATA_CBL_PATA40; /* UDMA 66 chips have only drive side logic */ - else if ((config->flags & VIA_UDMA) < VIA_UDMA_100) + else if (config->udma_mask < ATA_UDMA5) return ATA_CBL_PATA_UNK; /* UDMA 100 or later */ pci_read_config_dword(pdev, 0x50, &ata66); @@ -233,7 +220,6 @@ static int via_pre_reset(struct ata_link *link, unsigned long deadline) * @ap: ATA interface * @adev: ATA device * @mode: ATA mode being programmed - * @tdiv: Clocks per PCI clock * @set_ast: Set to program address setup * @udma_type: UDMA mode/format of registers * @@ -244,17 +230,27 @@ static int via_pre_reset(struct ata_link *link, unsigned long deadline) * on the two channels. */ -static void via_do_set_mode(struct ata_port *ap, struct ata_device *adev, int mode, int tdiv, int set_ast, int udma_type) +static void via_do_set_mode(struct ata_port *ap, struct ata_device *adev, + int mode, int set_ast, int udma_type) { struct pci_dev *pdev = to_pci_dev(ap->host->dev); struct ata_device *peer = ata_dev_pair(adev); struct ata_timing t, p; - static int via_clock = 33333; /* Bus clock in kHZ - ought to be tunable one day */ + static int via_clock = 33333; /* Bus clock in kHZ */ unsigned long T = 1000000000 / via_clock; - unsigned long UT = T/tdiv; + unsigned long UT = T; int ut; int offset = 3 - (2*ap->port_no) - adev->devno; + switch (udma_type) { + case ATA_UDMA4: + UT = T / 2; break; + case ATA_UDMA5: + UT = T / 3; break; + case ATA_UDMA6: + UT = T / 4; break; + } + /* Calculate the timing values we require */ ata_timing_compute(adev, mode, &t, T, UT); @@ -284,22 +280,20 @@ static void via_do_set_mode(struct ata_port *ap, struct ata_device *adev, int mo ((clamp_val(t.active, 1, 16) - 1) << 4) | (clamp_val(t.recover, 1, 16) - 1)); /* Load the UDMA bits according to type */ - switch(udma_type) { - default: - /* BUG() ? */ - /* fall through */ - case 33: - ut = t.udma ? (0xe0 | (clamp_val(t.udma, 2, 5) - 2)) : 0x03; - break; - case 66: - ut = t.udma ? (0xe8 | (clamp_val(t.udma, 2, 9) - 2)) : 0x0f; - break; - case 100: - ut = t.udma ? (0xe0 | (clamp_val(t.udma, 2, 9) - 2)) : 0x07; - break; - case 133: - ut = t.udma ? (0xe0 | (clamp_val(t.udma, 2, 9) - 2)) : 0x07; - break; + switch (udma_type) { + case ATA_UDMA2: + default: + ut = t.udma ? (0xe0 | (clamp_val(t.udma, 2, 5) - 2)) : 0x03; + break; + case ATA_UDMA4: + ut = t.udma ? (0xe8 | (clamp_val(t.udma, 2, 9) - 2)) : 0x0f; + break; + case ATA_UDMA5: + ut = t.udma ? (0xe0 | (clamp_val(t.udma, 2, 9) - 2)) : 0x07; + break; + case ATA_UDMA6: + ut = t.udma ? (0xe0 | (clamp_val(t.udma, 2, 9) - 2)) : 0x07; + break; } /* Set UDMA unless device is not UDMA capable */ @@ -325,22 +319,16 @@ static void via_set_piomode(struct ata_port *ap, struct ata_device *adev) { const struct via_isa_bridge *config = ap->host->private_data; int set_ast = (config->flags & VIA_BAD_AST) ? 0 : 1; - int mode = config->flags & VIA_UDMA; - static u8 tclock[5] = { 1, 1, 2, 3, 4 }; - static u8 udma[5] = { 0, 33, 66, 100, 133 }; - via_do_set_mode(ap, adev, adev->pio_mode, tclock[mode], set_ast, udma[mode]); + via_do_set_mode(ap, adev, adev->pio_mode, set_ast, config->udma_mask); } static void via_set_dmamode(struct ata_port *ap, struct ata_device *adev) { const struct via_isa_bridge *config = ap->host->private_data; int set_ast = (config->flags & VIA_BAD_AST) ? 0 : 1; - int mode = config->flags & VIA_UDMA; - static u8 tclock[5] = { 1, 1, 2, 3, 4 }; - static u8 udma[5] = { 0, 33, 66, 100, 133 }; - via_do_set_mode(ap, adev, adev->dma_mode, tclock[mode], set_ast, udma[mode]); + via_do_set_mode(ap, adev, adev->dma_mode, set_ast, config->udma_mask); } /** @@ -604,33 +592,29 @@ static int via_init_one(struct pci_dev *pdev, const struct pci_device_id *id) via_config_fifo(pdev, config->flags); /* Clock set up */ - switch(config->flags & VIA_UDMA) { - case VIA_UDMA_NONE: - if (config->flags & VIA_NO_UNMASK) - ppi[0] = &via_mwdma_info_borked; - else - ppi[0] = &via_mwdma_info; - break; - case VIA_UDMA_33: - ppi[0] = &via_udma33_info; - break; - case VIA_UDMA_66: - ppi[0] = &via_udma66_info; - /* The 66 MHz devices require we enable the clock */ - pci_read_config_dword(pdev, 0x50, &timing); - timing |= 0x80008; - pci_write_config_dword(pdev, 0x50, timing); - break; - case VIA_UDMA_100: - ppi[0] = &via_udma100_info; - break; - case VIA_UDMA_133: - ppi[0] = &via_udma133_info; - break; - default: - WARN_ON(1); - return -ENODEV; - } + switch (config->udma_mask) { + case 0x00: + if (config->flags & VIA_NO_UNMASK) + ppi[0] = &via_mwdma_info_borked; + else + ppi[0] = &via_mwdma_info; + break; + case ATA_UDMA2: + ppi[0] = &via_udma33_info; + break; + case ATA_UDMA4: + ppi[0] = &via_udma66_info; + break; + case ATA_UDMA5: + ppi[0] = &via_udma100_info; + break; + case ATA_UDMA6: + ppi[0] = &via_udma133_info; + break; + default: + WARN_ON(1); + return -ENODEV; + } if (config->flags & VIA_BAD_CLK66) { /* Disable the 66MHz clock on problem devices */ @@ -667,7 +651,7 @@ static int via_reinit_one(struct pci_dev *pdev) via_config_fifo(pdev, config->flags); - if ((config->flags & VIA_UDMA) == VIA_UDMA_66) { + if (config->udma_mask == ATA_UDMA4) { /* The 66 MHz devices require we enable the clock */ pci_read_config_dword(pdev, 0x50, &timing); timing |= 0x80008; -- cgit v1.2.2 From 429e3861f9d5682c5bc5f237345f8962daf51bbc Mon Sep 17 00:00:00 2001 From: Jeff Garzik Date: Thu, 4 Feb 2010 01:09:54 -0500 Subject: [libata] pata_at91: fix backslash-continued string Noticed and rough patch by Joe Perches. Signed-off-by: Jeff Garzik --- drivers/ata/pata_at91.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/ata/pata_at91.c b/drivers/ata/pata_at91.c index 41c94b1ae493..376dd380b43c 100644 --- a/drivers/ata/pata_at91.c +++ b/drivers/ata/pata_at91.c @@ -153,8 +153,8 @@ static void pata_at91_set_piomode(struct ata_port *ap, struct ata_device *adev) /* Compute ATA timing and set it to SMC */ ret = ata_timing_compute(adev, adev->pio_mode, &timing, 1000, 0); if (ret) { - dev_warn(ap->dev, "Failed to compute ATA timing %d, \ - set PIO_0 timing\n", ret); + dev_warn(ap->dev, "Failed to compute ATA timing %d, " + "set PIO_0 timing\n", ret); set_smc_timing(ap->dev, info, &initial_timing); } else { set_smc_timing(ap->dev, info, &timing); -- cgit v1.2.2 From a75032e8772d13dab5e3501413d7e14a148281b4 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Sat, 13 Feb 2010 14:35:53 +0100 Subject: pata_pdc202xx_old: fix UDMA mode for Promise UDMA33 cards On Monday 04 January 2010 02:30:24 pm Russell King wrote: > Found the problem - getting rid of the read of the alt status register > after the command has been written fixes the UDMA CRC errors on write: > > @@ -676,7 +676,8 @@ void ata_sff_exec_command(struct ata_port *ap, const struct > ata_taskfile *tf) > DPRINTK("ata%u: cmd 0x%X\n", ap->print_id, tf->command); > > iowrite8(tf->command, ap->ioaddr.command_addr); > - ata_sff_pause(ap); > + ndelay(400); > +// ata_sff_pause(ap); > } > EXPORT_SYMBOL_GPL(ata_sff_exec_command); > > > This rather makes sense. The PDC20247 handles the UDMA part of the > protocol. It has no way to tell the PDC20246 to wait while it suspends > UDMA, so that a normal register access can take place - the 246 ploughs > on with the register access without any regard to the state of the 247. > > If the drive immediately starts the UDMA protocol after a write to the > command register (as it probably will for the DMA WRITE command), then > we'll be accessing the taskfile in the middle of the UDMA setup, which > can't be good. It's certainly a violation of the ATA specs. Fix it by adding custom ->sff_exec_command method for UDMA33 chipsets. Debugged-by: Russell King Signed-off-by: Bartlomiej Zolnierkiewicz Signed-off-by: Jeff Garzik --- drivers/ata/pata_pdc202xx_old.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/ata/pata_pdc202xx_old.c b/drivers/ata/pata_pdc202xx_old.c index 2f3c9bed63d9..8d25bd59a16e 100644 --- a/drivers/ata/pata_pdc202xx_old.c +++ b/drivers/ata/pata_pdc202xx_old.c @@ -2,7 +2,7 @@ * pata_pdc202xx_old.c - Promise PDC202xx PATA for new ATA layer * (C) 2005 Red Hat Inc * Alan Cox - * (C) 2007,2009 Bartlomiej Zolnierkiewicz + * (C) 2007,2009,2010 Bartlomiej Zolnierkiewicz * * Based in part on linux/drivers/ide/pci/pdc202xx_old.c * @@ -35,6 +35,15 @@ static int pdc2026x_cable_detect(struct ata_port *ap) return ATA_CBL_PATA80; } +static void pdc20246_exec_command(struct ata_port *ap, + const struct ata_taskfile *tf) +{ + DPRINTK("ata%u: cmd 0x%X\n", ap->print_id, tf->command); + + iowrite8(tf->command, ap->ioaddr.command_addr); + ndelay(400); +} + /** * pdc202xx_configure_piomode - set chip PIO timing * @ap: ATA interface @@ -271,6 +280,8 @@ static struct ata_port_operations pdc2024x_port_ops = { .cable_detect = ata_cable_40wire, .set_piomode = pdc202xx_set_piomode, .set_dmamode = pdc202xx_set_dmamode, + + .sff_exec_command = pdc20246_exec_command, }; static struct ata_port_operations pdc2026x_port_ops = { -- cgit v1.2.2 From 750e519da7b3f470fe1b5b55c8d8f52d6d6371e4 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Sat, 13 Feb 2010 17:43:17 -0500 Subject: pata_pdc202xx_old: fix UDMA mode for PDC2026x chipsets PDC2026x chipsets need the same treatment as PDC20246 one. This is completely untested but will hopefully fix UDMA issues that people have been reporting against pata_pdc202xx_old for the last couple of years. Signed-off-by: Bartlomiej Zolnierkiewicz Signed-off-by: Jeff Garzik --- drivers/ata/pata_pdc202xx_old.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/ata/pata_pdc202xx_old.c b/drivers/ata/pata_pdc202xx_old.c index 8d25bd59a16e..29111205185a 100644 --- a/drivers/ata/pata_pdc202xx_old.c +++ b/drivers/ata/pata_pdc202xx_old.c @@ -35,7 +35,7 @@ static int pdc2026x_cable_detect(struct ata_port *ap) return ATA_CBL_PATA80; } -static void pdc20246_exec_command(struct ata_port *ap, +static void pdc202xx_exec_command(struct ata_port *ap, const struct ata_taskfile *tf) { DPRINTK("ata%u: cmd 0x%X\n", ap->print_id, tf->command); @@ -281,7 +281,7 @@ static struct ata_port_operations pdc2024x_port_ops = { .set_piomode = pdc202xx_set_piomode, .set_dmamode = pdc202xx_set_dmamode, - .sff_exec_command = pdc20246_exec_command, + .sff_exec_command = pdc202xx_exec_command, }; static struct ata_port_operations pdc2026x_port_ops = { @@ -295,6 +295,8 @@ static struct ata_port_operations pdc2026x_port_ops = { .dev_config = pdc2026x_dev_config, .port_start = pdc2026x_port_start, + + .sff_exec_command = pdc202xx_exec_command, }; static int pdc202xx_init_one(struct pci_dev *dev, const struct pci_device_id *id) -- cgit v1.2.2 From 96780078f35648050fef808f49a0ffff0360bb57 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Mon, 8 Feb 2010 10:04:54 +0000 Subject: libata: Allow pata_legacy to be built on non-ISA but PCI systems This is needed for some unsupported hardware setups on strange 64bit mainboards where crazy stuff has been done like putting flash ata adapters on the LPC bus, or where the real hardware is hidden/confused. Signed-off-by: Alan Cox Signed-off-by: Jeff Garzik --- drivers/ata/Kconfig | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig index 56c6374a3989..01c52c415bdc 100644 --- a/drivers/ata/Kconfig +++ b/drivers/ata/Kconfig @@ -446,9 +446,9 @@ config PATA_JMICRON config PATA_LEGACY tristate "Legacy ISA PATA support (Experimental)" - depends on ISA && EXPERIMENTAL + depends on (ISA || PCI) && EXPERIMENTAL help - This option enables support for ISA/VLB bus legacy PATA + This option enables support for ISA/VLB/PCI bus legacy PATA ports and allows them to be accessed via the new ATA layer. If unsure, say N. -- cgit v1.2.2 From cb6643e1c38b6bd5c1594f0a45d8cf6943a6f934 Mon Sep 17 00:00:00 2001 From: Christoph Egger Date: Fri, 5 Feb 2010 16:26:35 +0100 Subject: [libata] pata_marvell: CONFIG_AHCI is really CONFIG_SATA_AHCI The marvell driver comtains a fallback to ahci for the sata ports which is incorrectly checked as CONFIG_AHCI while the only AHCI config item is actually called SATA_AHCI (which also sounds sensible considering it's a fallback for the sata ports). Signed-off-by: Christoph Egger Signed-off-by: Jeff Garzik --- drivers/ata/pata_marvell.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/ata/pata_marvell.c b/drivers/ata/pata_marvell.c index 950da39cae3d..b351d81813f3 100644 --- a/drivers/ata/pata_marvell.c +++ b/drivers/ata/pata_marvell.c @@ -147,7 +147,7 @@ static int marvell_init_one (struct pci_dev *pdev, const struct pci_device_id *i if (pdev->device == 0x6101) ppi[1] = &ata_dummy_port_info; -#if defined(CONFIG_AHCI) || defined(CONFIG_AHCI_MODULE) +#if defined(CONFIG_SATA_AHCI) || defined(CONFIG_SATA_AHCI_MODULE) if (!marvell_pata_active(pdev)) { printk(KERN_INFO DRV_NAME ": PATA port not active, deferring to AHCI driver.\n"); return -ENODEV; -- cgit v1.2.2 From 16ea0fc98d53c72cb4e1a9edcb685a87e3a81430 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Tue, 23 Feb 2010 02:26:06 -0500 Subject: libata: Pass host flags into the pci helper This allows parallel scan and the like to be set without having to stop using the existing full helper functions. This patch merely adds the argument and fixes up the callers. It doesn't undo the special cases already in the tree or add any new parallel callers. Signed-off-by: Alan Cox Signed-off-by: Jeff Garzik --- drivers/ata/ata_generic.c | 2 +- drivers/ata/libata-sff.c | 6 ++++-- drivers/ata/pata_acpi.c | 2 +- drivers/ata/pata_ali.c | 2 +- drivers/ata/pata_amd.c | 2 +- drivers/ata/pata_artop.c | 2 +- drivers/ata/pata_atiixp.c | 2 +- drivers/ata/pata_cmd640.c | 2 +- drivers/ata/pata_cmd64x.c | 2 +- drivers/ata/pata_cs5530.c | 2 +- drivers/ata/pata_cs5535.c | 2 +- drivers/ata/pata_cs5536.c | 2 +- drivers/ata/pata_cypress.c | 2 +- drivers/ata/pata_efar.c | 2 +- drivers/ata/pata_hpt366.c | 2 +- drivers/ata/pata_hpt37x.c | 2 +- drivers/ata/pata_hpt3x2n.c | 2 +- drivers/ata/pata_it8213.c | 2 +- drivers/ata/pata_it821x.c | 2 +- drivers/ata/pata_jmicron.c | 2 +- drivers/ata/pata_marvell.c | 2 +- drivers/ata/pata_netcell.c | 2 +- drivers/ata/pata_ns87410.c | 2 +- drivers/ata/pata_ns87415.c | 2 +- drivers/ata/pata_oldpiix.c | 2 +- drivers/ata/pata_opti.c | 2 +- drivers/ata/pata_optidma.c | 2 +- drivers/ata/pata_pdc202xx_old.c | 2 +- drivers/ata/pata_piccolo.c | 2 +- drivers/ata/pata_radisys.c | 2 +- drivers/ata/pata_rz1000.c | 2 +- drivers/ata/pata_sc1200.c | 2 +- drivers/ata/pata_serverworks.c | 2 +- drivers/ata/pata_sil680.c | 2 +- drivers/ata/pata_sis.c | 2 +- drivers/ata/pata_sl82c105.c | 2 +- drivers/ata/pata_triflex.c | 2 +- drivers/ata/pata_via.c | 2 +- drivers/staging/phison/phison.c | 2 +- 39 files changed, 42 insertions(+), 40 deletions(-) (limited to 'drivers') diff --git a/drivers/ata/ata_generic.c b/drivers/ata/ata_generic.c index 12e26c3c68e3..33fb614f9784 100644 --- a/drivers/ata/ata_generic.c +++ b/drivers/ata/ata_generic.c @@ -155,7 +155,7 @@ static int ata_generic_init_one(struct pci_dev *dev, const struct pci_device_id return rc; pcim_pin_device(dev); } - return ata_pci_sff_init_one(dev, ppi, &generic_sht, NULL); + return ata_pci_sff_init_one(dev, ppi, &generic_sht, NULL, 0); } static struct pci_device_id ata_generic[] = { diff --git a/drivers/ata/libata-sff.c b/drivers/ata/libata-sff.c index c2661ea70330..02441fd57e9e 100644 --- a/drivers/ata/libata-sff.c +++ b/drivers/ata/libata-sff.c @@ -3037,6 +3037,7 @@ EXPORT_SYMBOL_GPL(ata_pci_sff_activate_host); * @ppi: array of port_info, must be enough for two ports * @sht: scsi_host_template to use when registering the host * @host_priv: host private_data + * @hflag: host flags * * This is a helper function which can be called from a driver's * xxx_init_one() probe function if the hardware uses traditional @@ -3057,8 +3058,8 @@ EXPORT_SYMBOL_GPL(ata_pci_sff_activate_host); * Zero on success, negative on errno-based value on error. */ int ata_pci_sff_init_one(struct pci_dev *pdev, - const struct ata_port_info * const *ppi, - struct scsi_host_template *sht, void *host_priv) + const struct ata_port_info * const *ppi, + struct scsi_host_template *sht, void *host_priv, int hflag) { struct device *dev = &pdev->dev; const struct ata_port_info *pi = NULL; @@ -3093,6 +3094,7 @@ int ata_pci_sff_init_one(struct pci_dev *pdev, if (rc) goto out; host->private_data = host_priv; + host->flags |= hflag; pci_set_master(pdev); rc = ata_pci_sff_activate_host(host, ata_sff_interrupt, sht); diff --git a/drivers/ata/pata_acpi.c b/drivers/ata/pata_acpi.c index d8f35fe44421..294f3020a78a 100644 --- a/drivers/ata/pata_acpi.c +++ b/drivers/ata/pata_acpi.c @@ -259,7 +259,7 @@ static int pacpi_init_one (struct pci_dev *pdev, const struct pci_device_id *id) return rc; pcim_pin_device(pdev); } - return ata_pci_sff_init_one(pdev, ppi, &pacpi_sht, NULL); + return ata_pci_sff_init_one(pdev, ppi, &pacpi_sht, NULL, 0); } static const struct pci_device_id pacpi_pci_tbl[] = { diff --git a/drivers/ata/pata_ali.c b/drivers/ata/pata_ali.c index 63ba48c9af33..dc61b72f751c 100644 --- a/drivers/ata/pata_ali.c +++ b/drivers/ata/pata_ali.c @@ -583,7 +583,7 @@ static int ali_init_one(struct pci_dev *pdev, const struct pci_device_id *id) ppi[0] = &info_20_udma; } - return ata_pci_sff_init_one(pdev, ppi, &ali_sht, NULL); + return ata_pci_sff_init_one(pdev, ppi, &ali_sht, NULL, 0); } #ifdef CONFIG_PM diff --git a/drivers/ata/pata_amd.c b/drivers/ata/pata_amd.c index 567f3f72774e..d95eca9c547e 100644 --- a/drivers/ata/pata_amd.c +++ b/drivers/ata/pata_amd.c @@ -574,7 +574,7 @@ static int amd_init_one(struct pci_dev *pdev, const struct pci_device_id *id) } /* And fire it up */ - return ata_pci_sff_init_one(pdev, ppi, &amd_sht, hpriv); + return ata_pci_sff_init_one(pdev, ppi, &amd_sht, hpriv, 0); } #ifdef CONFIG_PM diff --git a/drivers/ata/pata_artop.c b/drivers/ata/pata_artop.c index d332cfdb0f30..4d066d6c30fa 100644 --- a/drivers/ata/pata_artop.c +++ b/drivers/ata/pata_artop.c @@ -421,7 +421,7 @@ static int artop_init_one (struct pci_dev *pdev, const struct pci_device_id *id) BUG_ON(ppi[0] == NULL); - return ata_pci_sff_init_one(pdev, ppi, &artop_sht, NULL); + return ata_pci_sff_init_one(pdev, ppi, &artop_sht, NULL, 0); } static const struct pci_device_id artop_pci_tbl[] = { diff --git a/drivers/ata/pata_atiixp.c b/drivers/ata/pata_atiixp.c index ae4454d4e955..f697b5b880d3 100644 --- a/drivers/ata/pata_atiixp.c +++ b/drivers/ata/pata_atiixp.c @@ -237,7 +237,7 @@ static int atiixp_init_one(struct pci_dev *pdev, const struct pci_device_id *id) if (!pci_test_config_bits(pdev, &atiixp_enable_bits[i])) ppi[i] = &ata_dummy_port_info; - return ata_pci_sff_init_one(pdev, ppi, &atiixp_sht, NULL); + return ata_pci_sff_init_one(pdev, ppi, &atiixp_sht, NULL, 0); } static const struct pci_device_id atiixp[] = { diff --git a/drivers/ata/pata_cmd640.c b/drivers/ata/pata_cmd640.c index 5acf9fa9b39f..6cd5d5dd9e3b 100644 --- a/drivers/ata/pata_cmd640.c +++ b/drivers/ata/pata_cmd640.c @@ -223,7 +223,7 @@ static int cmd640_init_one(struct pci_dev *pdev, const struct pci_device_id *id) cmd640_hardware_init(pdev); - return ata_pci_sff_init_one(pdev, ppi, &cmd640_sht, NULL); + return ata_pci_sff_init_one(pdev, ppi, &cmd640_sht, NULL, 0); } #ifdef CONFIG_PM diff --git a/drivers/ata/pata_cmd64x.c b/drivers/ata/pata_cmd64x.c index b40bf0f29975..4c81a71b8877 100644 --- a/drivers/ata/pata_cmd64x.c +++ b/drivers/ata/pata_cmd64x.c @@ -367,7 +367,7 @@ static int cmd64x_init_one(struct pci_dev *pdev, const struct pci_device_id *id) pci_write_config_byte(pdev, UDIDETCR0, 0xF0); #endif - return ata_pci_sff_init_one(pdev, ppi, &cmd64x_sht, NULL); + return ata_pci_sff_init_one(pdev, ppi, &cmd64x_sht, NULL, 0); } #ifdef CONFIG_PM diff --git a/drivers/ata/pata_cs5530.c b/drivers/ata/pata_cs5530.c index c974b05e4129..738ad2e14a97 100644 --- a/drivers/ata/pata_cs5530.c +++ b/drivers/ata/pata_cs5530.c @@ -324,7 +324,7 @@ static int cs5530_init_one(struct pci_dev *pdev, const struct pci_device_id *id) ppi[1] = &info_palmax_secondary; /* Now kick off ATA set up */ - return ata_pci_sff_init_one(pdev, ppi, &cs5530_sht, NULL); + return ata_pci_sff_init_one(pdev, ppi, &cs5530_sht, NULL, 0); } #ifdef CONFIG_PM diff --git a/drivers/ata/pata_cs5535.c b/drivers/ata/pata_cs5535.c index c50c3a42b10b..a02e6459fdcc 100644 --- a/drivers/ata/pata_cs5535.c +++ b/drivers/ata/pata_cs5535.c @@ -198,7 +198,7 @@ static int cs5535_init_one(struct pci_dev *dev, const struct pci_device_id *id) rdmsr(ATAC_CH0D1_PIO, timings, dummy); if (CS5535_BAD_PIO(timings)) wrmsr(ATAC_CH0D1_PIO, 0xF7F4F7F4UL, 0); - return ata_pci_sff_init_one(dev, ppi, &cs5535_sht, NULL); + return ata_pci_sff_init_one(dev, ppi, &cs5535_sht, NULL, 0); } static const struct pci_device_id cs5535[] = { diff --git a/drivers/ata/pata_cs5536.c b/drivers/ata/pata_cs5536.c index ffee3978ec83..914ae3506ff5 100644 --- a/drivers/ata/pata_cs5536.c +++ b/drivers/ata/pata_cs5536.c @@ -260,7 +260,7 @@ static int cs5536_init_one(struct pci_dev *dev, const struct pci_device_id *id) return -ENODEV; } - return ata_pci_sff_init_one(dev, ppi, &cs5536_sht, NULL); + return ata_pci_sff_init_one(dev, ppi, &cs5536_sht, NULL, 0); } static const struct pci_device_id cs5536[] = { diff --git a/drivers/ata/pata_cypress.c b/drivers/ata/pata_cypress.c index ff6c37de5a12..0fcc096b8dac 100644 --- a/drivers/ata/pata_cypress.c +++ b/drivers/ata/pata_cypress.c @@ -138,7 +138,7 @@ static int cy82c693_init_one(struct pci_dev *pdev, const struct pci_device_id *i if (PCI_FUNC(pdev->devfn) != 1) return -ENODEV; - return ata_pci_sff_init_one(pdev, ppi, &cy82c693_sht, NULL); + return ata_pci_sff_init_one(pdev, ppi, &cy82c693_sht, NULL, 0); } static const struct pci_device_id cy82c693[] = { diff --git a/drivers/ata/pata_efar.c b/drivers/ata/pata_efar.c index 89076d58111b..5556163c80de 100644 --- a/drivers/ata/pata_efar.c +++ b/drivers/ata/pata_efar.c @@ -262,7 +262,7 @@ static int efar_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n"); - return ata_pci_sff_init_one(pdev, ppi, &efar_sht, NULL); + return ata_pci_sff_init_one(pdev, ppi, &efar_sht, NULL, 0); } static const struct pci_device_id efar_pci_tbl[] = { diff --git a/drivers/ata/pata_hpt366.c b/drivers/ata/pata_hpt366.c index 3ec88f2c8665..af49bfb57247 100644 --- a/drivers/ata/pata_hpt366.c +++ b/drivers/ata/pata_hpt366.c @@ -361,7 +361,7 @@ static int hpt36x_init_one(struct pci_dev *dev, const struct pci_device_id *id) break; } /* Now kick off ATA set up */ - return ata_pci_sff_init_one(dev, ppi, &hpt36x_sht, hpriv); + return ata_pci_sff_init_one(dev, ppi, &hpt36x_sht, hpriv, 0); } #ifdef CONFIG_PM diff --git a/drivers/ata/pata_hpt37x.c b/drivers/ata/pata_hpt37x.c index 228dc1a8992f..8839307a64cf 100644 --- a/drivers/ata/pata_hpt37x.c +++ b/drivers/ata/pata_hpt37x.c @@ -987,7 +987,7 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id) } /* Now kick off ATA set up */ - return ata_pci_sff_init_one(dev, ppi, &hpt37x_sht, private_data); + return ata_pci_sff_init_one(dev, ppi, &hpt37x_sht, private_data, 0); } static const struct pci_device_id hpt37x[] = { diff --git a/drivers/ata/pata_hpt3x2n.c b/drivers/ata/pata_hpt3x2n.c index 4a291221f277..01457b266f3d 100644 --- a/drivers/ata/pata_hpt3x2n.c +++ b/drivers/ata/pata_hpt3x2n.c @@ -548,7 +548,7 @@ static int hpt3x2n_init_one(struct pci_dev *dev, const struct pci_device_id *id) outb(inb(iobase + 0x9c) | 0x04, iobase + 0x9c); /* Now kick off ATA set up */ - return ata_pci_sff_init_one(dev, ppi, &hpt3x2n_sht, hpriv); + return ata_pci_sff_init_one(dev, ppi, &hpt3x2n_sht, hpriv, 0); } static const struct pci_device_id hpt3x2n[] = { diff --git a/drivers/ata/pata_it8213.c b/drivers/ata/pata_it8213.c index 8f3325adceb3..f971f0de88e6 100644 --- a/drivers/ata/pata_it8213.c +++ b/drivers/ata/pata_it8213.c @@ -273,7 +273,7 @@ static int it8213_init_one (struct pci_dev *pdev, const struct pci_device_id *en dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n"); - return ata_pci_sff_init_one(pdev, ppi, &it8213_sht, NULL); + return ata_pci_sff_init_one(pdev, ppi, &it8213_sht, NULL, 0); } static const struct pci_device_id it8213_pci_tbl[] = { diff --git a/drivers/ata/pata_it821x.c b/drivers/ata/pata_it821x.c index edc5c1fed150..9bde1cb5f981 100644 --- a/drivers/ata/pata_it821x.c +++ b/drivers/ata/pata_it821x.c @@ -932,7 +932,7 @@ static int it821x_init_one(struct pci_dev *pdev, const struct pci_device_id *id) else ppi[0] = &info_smart; } - return ata_pci_sff_init_one(pdev, ppi, &it821x_sht, NULL); + return ata_pci_sff_init_one(pdev, ppi, &it821x_sht, NULL, 0); } #ifdef CONFIG_PM diff --git a/drivers/ata/pata_jmicron.c b/drivers/ata/pata_jmicron.c index 3a1474ac8838..565e01e6ac7c 100644 --- a/drivers/ata/pata_jmicron.c +++ b/drivers/ata/pata_jmicron.c @@ -144,7 +144,7 @@ static int jmicron_init_one (struct pci_dev *pdev, const struct pci_device_id *i }; const struct ata_port_info *ppi[] = { &info, NULL }; - return ata_pci_sff_init_one(pdev, ppi, &jmicron_sht, NULL); + return ata_pci_sff_init_one(pdev, ppi, &jmicron_sht, NULL, 0); } static const struct pci_device_id jmicron_pci_tbl[] = { diff --git a/drivers/ata/pata_marvell.c b/drivers/ata/pata_marvell.c index b351d81813f3..e8ca02e5a71d 100644 --- a/drivers/ata/pata_marvell.c +++ b/drivers/ata/pata_marvell.c @@ -153,7 +153,7 @@ static int marvell_init_one (struct pci_dev *pdev, const struct pci_device_id *i return -ENODEV; } #endif - return ata_pci_sff_init_one(pdev, ppi, &marvell_sht, NULL); + return ata_pci_sff_init_one(pdev, ppi, &marvell_sht, NULL, 0); } static const struct pci_device_id marvell_pci_tbl[] = { diff --git a/drivers/ata/pata_netcell.c b/drivers/ata/pata_netcell.c index f0d52f72f5bb..94f979a7f4f7 100644 --- a/drivers/ata/pata_netcell.c +++ b/drivers/ata/pata_netcell.c @@ -82,7 +82,7 @@ static int netcell_init_one (struct pci_dev *pdev, const struct pci_device_id *e ata_pci_bmdma_clear_simplex(pdev); /* And let the library code do the work */ - return ata_pci_sff_init_one(pdev, port_info, &netcell_sht, NULL); + return ata_pci_sff_init_one(pdev, port_info, &netcell_sht, NULL, 0); } static const struct pci_device_id netcell_pci_tbl[] = { diff --git a/drivers/ata/pata_ns87410.c b/drivers/ata/pata_ns87410.c index ca53fac06717..2110863bb3db 100644 --- a/drivers/ata/pata_ns87410.c +++ b/drivers/ata/pata_ns87410.c @@ -148,7 +148,7 @@ static int ns87410_init_one(struct pci_dev *dev, const struct pci_device_id *id) .port_ops = &ns87410_port_ops }; const struct ata_port_info *ppi[] = { &info, NULL }; - return ata_pci_sff_init_one(dev, ppi, &ns87410_sht, NULL); + return ata_pci_sff_init_one(dev, ppi, &ns87410_sht, NULL, 0); } static const struct pci_device_id ns87410[] = { diff --git a/drivers/ata/pata_ns87415.c b/drivers/ata/pata_ns87415.c index 061aa1c41a48..830431f036a1 100644 --- a/drivers/ata/pata_ns87415.c +++ b/drivers/ata/pata_ns87415.c @@ -380,7 +380,7 @@ static int ns87415_init_one (struct pci_dev *pdev, const struct pci_device_id *e ns87415_fixup(pdev); - return ata_pci_sff_init_one(pdev, ppi, &ns87415_sht, NULL); + return ata_pci_sff_init_one(pdev, ppi, &ns87415_sht, NULL, 0); } static const struct pci_device_id ns87415_pci_tbl[] = { diff --git a/drivers/ata/pata_oldpiix.c b/drivers/ata/pata_oldpiix.c index 9a8687db6b2d..5f6aba7eb0dd 100644 --- a/drivers/ata/pata_oldpiix.c +++ b/drivers/ata/pata_oldpiix.c @@ -248,7 +248,7 @@ static int oldpiix_init_one (struct pci_dev *pdev, const struct pci_device_id *e dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n"); - return ata_pci_sff_init_one(pdev, ppi, &oldpiix_sht, NULL); + return ata_pci_sff_init_one(pdev, ppi, &oldpiix_sht, NULL, 0); } static const struct pci_device_id oldpiix_pci_tbl[] = { diff --git a/drivers/ata/pata_opti.c b/drivers/ata/pata_opti.c index 99eddda2d2e5..00c5a02a94fc 100644 --- a/drivers/ata/pata_opti.c +++ b/drivers/ata/pata_opti.c @@ -172,7 +172,7 @@ static int opti_init_one(struct pci_dev *dev, const struct pci_device_id *id) if (!printed_version++) dev_printk(KERN_DEBUG, &dev->dev, "version " DRV_VERSION "\n"); - return ata_pci_sff_init_one(dev, ppi, &opti_sht, NULL); + return ata_pci_sff_init_one(dev, ppi, &opti_sht, NULL, 0); } static const struct pci_device_id opti[] = { diff --git a/drivers/ata/pata_optidma.c b/drivers/ata/pata_optidma.c index 86885a445f97..76b7d12b1e8d 100644 --- a/drivers/ata/pata_optidma.c +++ b/drivers/ata/pata_optidma.c @@ -429,7 +429,7 @@ static int optidma_init_one(struct pci_dev *dev, const struct pci_device_id *id) if (optiplus_with_udma(dev)) ppi[0] = &info_82c700_udma; - return ata_pci_sff_init_one(dev, ppi, &optidma_sht, NULL); + return ata_pci_sff_init_one(dev, ppi, &optidma_sht, NULL, 0); } static const struct pci_device_id optidma[] = { diff --git a/drivers/ata/pata_pdc202xx_old.c b/drivers/ata/pata_pdc202xx_old.c index 29111205185a..9ac0897cf8b0 100644 --- a/drivers/ata/pata_pdc202xx_old.c +++ b/drivers/ata/pata_pdc202xx_old.c @@ -337,7 +337,7 @@ static int pdc202xx_init_one(struct pci_dev *dev, const struct pci_device_id *id return -ENODEV; } } - return ata_pci_sff_init_one(dev, ppi, &pdc202xx_sht, NULL); + return ata_pci_sff_init_one(dev, ppi, &pdc202xx_sht, NULL, 0); } static const struct pci_device_id pdc202xx[] = { diff --git a/drivers/ata/pata_piccolo.c b/drivers/ata/pata_piccolo.c index bfe0180f3efa..981615414849 100644 --- a/drivers/ata/pata_piccolo.c +++ b/drivers/ata/pata_piccolo.c @@ -95,7 +95,7 @@ static int ata_tosh_init_one(struct pci_dev *dev, const struct pci_device_id *id }; const struct ata_port_info *ppi[] = { &info, &ata_dummy_port_info }; /* Just one port for the moment */ - return ata_pci_sff_init_one(dev, ppi, &tosh_sht, NULL); + return ata_pci_sff_init_one(dev, ppi, &tosh_sht, NULL, 0); } static struct pci_device_id ata_tosh[] = { diff --git a/drivers/ata/pata_radisys.c b/drivers/ata/pata_radisys.c index 4fd25e737d9a..fc9602229acb 100644 --- a/drivers/ata/pata_radisys.c +++ b/drivers/ata/pata_radisys.c @@ -227,7 +227,7 @@ static int radisys_init_one (struct pci_dev *pdev, const struct pci_device_id *e dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n"); - return ata_pci_sff_init_one(pdev, ppi, &radisys_sht, NULL); + return ata_pci_sff_init_one(pdev, ppi, &radisys_sht, NULL, 0); } static const struct pci_device_id radisys_pci_tbl[] = { diff --git a/drivers/ata/pata_rz1000.c b/drivers/ata/pata_rz1000.c index 2932998fc4c6..4a454a88aa9d 100644 --- a/drivers/ata/pata_rz1000.c +++ b/drivers/ata/pata_rz1000.c @@ -95,7 +95,7 @@ static int rz1000_init_one (struct pci_dev *pdev, const struct pci_device_id *en printk_once(KERN_DEBUG DRV_NAME " version " DRV_VERSION "\n"); if (rz1000_fifo_disable(pdev) == 0) - return ata_pci_sff_init_one(pdev, ppi, &rz1000_sht, NULL); + return ata_pci_sff_init_one(pdev, ppi, &rz1000_sht, NULL, 0); printk(KERN_ERR DRV_NAME ": failed to disable read-ahead on chipset..\n"); /* Not safe to use so skip */ diff --git a/drivers/ata/pata_sc1200.c b/drivers/ata/pata_sc1200.c index 3bbed8322ecf..dfecc6f964b0 100644 --- a/drivers/ata/pata_sc1200.c +++ b/drivers/ata/pata_sc1200.c @@ -237,7 +237,7 @@ static int sc1200_init_one(struct pci_dev *dev, const struct pci_device_id *id) }; const struct ata_port_info *ppi[] = { &info, NULL }; - return ata_pci_sff_init_one(dev, ppi, &sc1200_sht, NULL); + return ata_pci_sff_init_one(dev, ppi, &sc1200_sht, NULL, 0); } static const struct pci_device_id sc1200[] = { diff --git a/drivers/ata/pata_serverworks.c b/drivers/ata/pata_serverworks.c index c85976720a0c..9524d54035f7 100644 --- a/drivers/ata/pata_serverworks.c +++ b/drivers/ata/pata_serverworks.c @@ -460,7 +460,7 @@ static int serverworks_init_one(struct pci_dev *pdev, const struct pci_device_id if (pdev->device == PCI_DEVICE_ID_SERVERWORKS_CSB5IDE) ata_pci_bmdma_clear_simplex(pdev); - return ata_pci_sff_init_one(pdev, ppi, &serverworks_sht, NULL); + return ata_pci_sff_init_one(pdev, ppi, &serverworks_sht, NULL, 0); } #ifdef CONFIG_PM diff --git a/drivers/ata/pata_sil680.c b/drivers/ata/pata_sil680.c index a2ace48a4610..c6c589c23ffc 100644 --- a/drivers/ata/pata_sil680.c +++ b/drivers/ata/pata_sil680.c @@ -356,7 +356,7 @@ static int __devinit sil680_init_one(struct pci_dev *pdev, IRQF_SHARED, &sil680_sht); use_ioports: - return ata_pci_sff_init_one(pdev, ppi, &sil680_sht, NULL); + return ata_pci_sff_init_one(pdev, ppi, &sil680_sht, NULL, 0); } #ifdef CONFIG_PM diff --git a/drivers/ata/pata_sis.c b/drivers/ata/pata_sis.c index 5c30d56dec84..b6708032f321 100644 --- a/drivers/ata/pata_sis.c +++ b/drivers/ata/pata_sis.c @@ -826,7 +826,7 @@ static int sis_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) sis_fixup(pdev, chipset); - return ata_pci_sff_init_one(pdev, ppi, &sis_sht, chipset); + return ata_pci_sff_init_one(pdev, ppi, &sis_sht, chipset, 0); } #ifdef CONFIG_PM diff --git a/drivers/ata/pata_sl82c105.c b/drivers/ata/pata_sl82c105.c index 29f733c32066..733b042a7469 100644 --- a/drivers/ata/pata_sl82c105.c +++ b/drivers/ata/pata_sl82c105.c @@ -316,7 +316,7 @@ static int sl82c105_init_one(struct pci_dev *dev, const struct pci_device_id *id val |= CTRL_P0EN | CTRL_P0F16 | CTRL_P1F16; pci_write_config_dword(dev, 0x40, val); - return ata_pci_sff_init_one(dev, ppi, &sl82c105_sht, NULL); + return ata_pci_sff_init_one(dev, ppi, &sl82c105_sht, NULL, 0); } static const struct pci_device_id sl82c105[] = { diff --git a/drivers/ata/pata_triflex.c b/drivers/ata/pata_triflex.c index f1f13ff222fd..48f50600ed2a 100644 --- a/drivers/ata/pata_triflex.c +++ b/drivers/ata/pata_triflex.c @@ -201,7 +201,7 @@ static int triflex_init_one(struct pci_dev *dev, const struct pci_device_id *id) if (!printed_version++) dev_printk(KERN_DEBUG, &dev->dev, "version " DRV_VERSION "\n"); - return ata_pci_sff_init_one(dev, ppi, &triflex_sht, NULL); + return ata_pci_sff_init_one(dev, ppi, &triflex_sht, NULL, 0); } static const struct pci_device_id triflex[] = { diff --git a/drivers/ata/pata_via.c b/drivers/ata/pata_via.c index 6356377231fd..3059ec017de3 100644 --- a/drivers/ata/pata_via.c +++ b/drivers/ata/pata_via.c @@ -624,7 +624,7 @@ static int via_init_one(struct pci_dev *pdev, const struct pci_device_id *id) } /* We have established the device type, now fire it up */ - return ata_pci_sff_init_one(pdev, ppi, &via_sht, (void *)config); + return ata_pci_sff_init_one(pdev, ppi, &via_sht, (void *)config, 0); } #ifdef CONFIG_PM diff --git a/drivers/staging/phison/phison.c b/drivers/staging/phison/phison.c index 3817d7497049..fcba78d21636 100644 --- a/drivers/staging/phison/phison.c +++ b/drivers/staging/phison/phison.c @@ -62,7 +62,7 @@ static int phison_init_one(struct pci_dev *pdev, const struct pci_device_id *id) }; const struct ata_port_info *ppi[] = { &info, NULL }; - ret = ata_pci_sff_init_one(pdev, ppi, &phison_sht, NULL); + ret = ata_pci_sff_init_one(pdev, ppi, &phison_sht, NULL, 0); dev_dbg(&pdev->dev, "phison_init_one(), ret = %x\n", ret); -- cgit v1.2.2 From 303f1a76ae792885af8a4a0e784e22e31e850e9a Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Wed, 17 Feb 2010 13:16:58 +0000 Subject: [libata] pata_efar: add locking for parallel scanning Add clearing of UDMA enable bit also for PIO modes and then add extra locking for parallel scanning. This is similar change as commit 60c3be3 for ata_piix host driver and while pata_efar doesn't enable parallel scan yet the race could probably also be triggered by requesting re-scanning of both ports at the same time using SCSI sysfs interface. [Ported to current kernel without other patch dependancies by Alan Cox] Original is Signed-off-by: Bartlomiej Zolnierkiewicz This one is Signed-off-by: Alan Cox Signed-off-by: Jeff Garzik --- drivers/ata/pata_efar.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'drivers') diff --git a/drivers/ata/pata_efar.c b/drivers/ata/pata_efar.c index 5556163c80de..1617421f7e76 100644 --- a/drivers/ata/pata_efar.c +++ b/drivers/ata/pata_efar.c @@ -68,6 +68,8 @@ static int efar_cable_detect(struct ata_port *ap) return ATA_CBL_PATA80; } +static DEFINE_SPINLOCK(efar_lock); + /** * efar_set_piomode - Initialize host controller PATA PIO timings * @ap: Port whose timings we are configuring @@ -84,7 +86,9 @@ static void efar_set_piomode (struct ata_port *ap, struct ata_device *adev) unsigned int pio = adev->pio_mode - XFER_PIO_0; struct pci_dev *dev = to_pci_dev(ap->host->dev); unsigned int idetm_port= ap->port_no ? 0x42 : 0x40; + unsigned long flags; u16 idetm_data; + u8 udma_enable; int control = 0; /* @@ -107,6 +111,8 @@ static void efar_set_piomode (struct ata_port *ap, struct ata_device *adev) if (adev->class == ATA_DEV_ATA) control |= 4; /* PPE */ + spin_lock_irqsave(&efar_lock, flags); + pci_read_config_word(dev, idetm_port, &idetm_data); /* Set PPE, IE, and TIME as appropriate */ @@ -131,6 +137,11 @@ static void efar_set_piomode (struct ata_port *ap, struct ata_device *adev) idetm_data |= 0x4000; /* Ensure SITRE is set */ pci_write_config_word(dev, idetm_port, idetm_data); + + pci_read_config_byte(dev, 0x48, &udma_enable); + udma_enable &= ~(1 << (2 * ap->port_no + adev->devno)); + pci_write_config_byte(dev, 0x48, udma_enable); + spin_unlock_irqrestore(&efar_lock, flags); } /** @@ -151,6 +162,7 @@ static void efar_set_dmamode (struct ata_port *ap, struct ata_device *adev) u16 master_data; u8 speed = adev->dma_mode; int devid = adev->devno + 2 * ap->port_no; + unsigned long flags; u8 udma_enable; static const /* ISP RTC */ @@ -160,6 +172,8 @@ static void efar_set_dmamode (struct ata_port *ap, struct ata_device *adev) { 2, 1 }, { 2, 3 }, }; + spin_lock_irqsave(&efar_lock, flags); + pci_read_config_word(dev, master_port, &master_data); pci_read_config_byte(dev, 0x48, &udma_enable); @@ -217,6 +231,7 @@ static void efar_set_dmamode (struct ata_port *ap, struct ata_device *adev) pci_write_config_word(dev, master_port, master_data); } pci_write_config_byte(dev, 0x48, udma_enable); + spin_unlock_irqrestore(&efar_lock, flags); } static struct scsi_host_template efar_sht = { -- cgit v1.2.2 From e99846f18f03badd1bbd4fda79e6ec325e3b9058 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Wed, 17 Feb 2010 13:17:31 +0000 Subject: [libata] pata_atiixp: add locking for parallel scanning This is similar change as commit 60c3be3 for ata_piix host driver and while pata_atiixp doesn't enable parallel scan yet the race could probably also be triggered by requesting re-scanning of both ports at the same time using SCSI sysfs interface. [Ported to current tree without other patch dependancies by Alan Cox] Original is Signed-off-by: Bartlomiej Zolnierkiewicz This one is Signed-off-by: Alan Cox Signed-off-by: Jeff Garzik --- drivers/ata/pata_atiixp.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/ata/pata_atiixp.c b/drivers/ata/pata_atiixp.c index f697b5b880d3..9ad3b4ce1ca5 100644 --- a/drivers/ata/pata_atiixp.c +++ b/drivers/ata/pata_atiixp.c @@ -1,7 +1,7 @@ /* * pata_atiixp.c - ATI PATA for new ATA layer * (C) 2005 Red Hat Inc - * (C) 2009 Bartlomiej Zolnierkiewicz + * (C) 2009-2010 Bartlomiej Zolnierkiewicz * * Based on * @@ -46,6 +46,8 @@ static int atiixp_cable_detect(struct ata_port *ap) return ATA_CBL_PATA40; } +static DEFINE_SPINLOCK(atiixp_lock); + /** * atiixp_set_pio_timing - set initial PIO mode data * @ap: ATA interface @@ -88,7 +90,10 @@ static void atiixp_set_pio_timing(struct ata_port *ap, struct ata_device *adev, static void atiixp_set_piomode(struct ata_port *ap, struct ata_device *adev) { + unsigned long flags; + spin_lock_irqsave(&atiixp_lock, flags); atiixp_set_pio_timing(ap, adev, adev->pio_mode - XFER_PIO_0); + spin_unlock_irqrestore(&atiixp_lock, flags); } /** @@ -108,6 +113,9 @@ static void atiixp_set_dmamode(struct ata_port *ap, struct ata_device *adev) int dma = adev->dma_mode; int dn = 2 * ap->port_no + adev->devno; int wanted_pio; + unsigned long flags; + + spin_lock_irqsave(&atiixp_lock, flags); if (adev->dma_mode >= XFER_UDMA_0) { u16 udma_mode_data; @@ -145,6 +153,7 @@ static void atiixp_set_dmamode(struct ata_port *ap, struct ata_device *adev) if (adev->pio_mode != wanted_pio) atiixp_set_pio_timing(ap, adev, wanted_pio); + spin_unlock_irqrestore(&atiixp_lock, flags); } /** -- cgit v1.2.2 From 1d3a8118b049252a84641b6643066bda0da0d316 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Wed, 17 Feb 2010 13:17:44 +0000 Subject: pata_atiixp: enable parallel scan This was originally proposed by Bartlomiej but as a device specific expansion of the init_one function rather than making the helper more generic. Enable the parallel scan via the generic flags. Signed-off-by: Alan Cox Signed-off-by: Jeff Garzik --- drivers/ata/pata_atiixp.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/ata/pata_atiixp.c b/drivers/ata/pata_atiixp.c index 9ad3b4ce1ca5..cbaf2eddac6b 100644 --- a/drivers/ata/pata_atiixp.c +++ b/drivers/ata/pata_atiixp.c @@ -246,7 +246,8 @@ static int atiixp_init_one(struct pci_dev *pdev, const struct pci_device_id *id) if (!pci_test_config_bits(pdev, &atiixp_enable_bits[i])) ppi[i] = &ata_dummy_port_info; - return ata_pci_sff_init_one(pdev, ppi, &atiixp_sht, NULL, 0); + return ata_pci_sff_init_one(pdev, ppi, &atiixp_sht, NULL, + ATA_HOST_PARALLEL_SCAN); } static const struct pci_device_id atiixp[] = { -- cgit v1.2.2 From 7e044a12c73f474e59f1ddecf08d6781c7830f0f Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Wed, 17 Feb 2010 13:17:52 +0000 Subject: pata_efar: Enable parallel scanning Again originally proposed by Bartlomiej but this does it by using the generic helper logic instead. Signed-off-by: Alan Cox Signed-off-by: Jeff Garzik --- drivers/ata/pata_efar.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/ata/pata_efar.c b/drivers/ata/pata_efar.c index 1617421f7e76..3bac0e079691 100644 --- a/drivers/ata/pata_efar.c +++ b/drivers/ata/pata_efar.c @@ -277,7 +277,8 @@ static int efar_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n"); - return ata_pci_sff_init_one(pdev, ppi, &efar_sht, NULL, 0); + return ata_pci_sff_init_one(pdev, ppi, &efar_sht, NULL, + ATA_HOST_PARALLEL_SCAN); } static const struct pci_device_id efar_pci_tbl[] = { -- cgit v1.2.2 From a55ab496ea9c820b7192c15ef1fbf3291edfe638 Mon Sep 17 00:00:00 2001 From: Bart Hartgers Date: Sun, 14 Feb 2010 13:04:50 +0100 Subject: sata_via: Delay on vt6420 when starting ATAPI DMA write When writing a disc on certain lite-on dvd-writers (also rebadged as optiarc/LG/...) connected to a vt6420, the ATAPI CDB ends up in the datastream and on the disc, causing silent corruption. Delaying between sending the CDB and starting DMA seems to prevent this. I do not know if there are burners that do not suffer from this, but the patch should be safe for those as well. There are many reports of this issue, but AFAICT no solution was found before. For example: http://lkml.indiana.edu/hypermail/linux/kernel/0802.3/0561.html Signed-off-by: Bart Hartgers Signed-off-by: Jeff Garzik --- drivers/ata/sata_via.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/ata/sata_via.c b/drivers/ata/sata_via.c index 2a17fa375164..08f65492cc81 100644 --- a/drivers/ata/sata_via.c +++ b/drivers/ata/sata_via.c @@ -40,11 +40,13 @@ #include #include #include +#include +#include #include #include #define DRV_NAME "sata_via" -#define DRV_VERSION "2.5" +#define DRV_VERSION "2.6" /* * vt8251 is different from other sata controllers of VIA. It has two @@ -80,6 +82,7 @@ static int vt8251_scr_write(struct ata_link *link, unsigned int scr, u32 val); static void svia_tf_load(struct ata_port *ap, const struct ata_taskfile *tf); static void svia_noop_freeze(struct ata_port *ap); static int vt6420_prereset(struct ata_link *link, unsigned long deadline); +static void vt6420_bmdma_start(struct ata_queued_cmd *qc); static int vt6421_pata_cable_detect(struct ata_port *ap); static void vt6421_set_pio_mode(struct ata_port *ap, struct ata_device *adev); static void vt6421_set_dma_mode(struct ata_port *ap, struct ata_device *adev); @@ -121,6 +124,7 @@ static struct ata_port_operations vt6420_sata_ops = { .inherits = &svia_base_ops, .freeze = svia_noop_freeze, .prereset = vt6420_prereset, + .bmdma_start = vt6420_bmdma_start, }; static struct ata_port_operations vt6421_pata_ops = { @@ -377,6 +381,17 @@ static int vt6420_prereset(struct ata_link *link, unsigned long deadline) return 0; } +static void vt6420_bmdma_start(struct ata_queued_cmd *qc) +{ + struct ata_port *ap = qc->ap; + if ((qc->tf.command == ATA_CMD_PACKET) && + (qc->scsicmd->sc_data_direction == DMA_TO_DEVICE)) { + /* Prevents corruption on some ATAPI burners */ + ata_sff_pause(ap); + } + ata_bmdma_start(qc); +} + static int vt6421_pata_cable_detect(struct ata_port *ap) { struct pci_dev *pdev = to_pci_dev(ap->host->dev); -- cgit v1.2.2 From 21df20fcfb4e88f4cd4991e9e67de549e6480adf Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Tue, 2 Mar 2010 12:13:55 +0200 Subject: OMAP: DSS2: Taal: Fix TE when resuming TE was not initialized properly on power on, which broke TE when resuming from suspend. Signed-off-by: Tomi Valkeinen --- drivers/video/omap2/displays/panel-taal.c | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/video/omap2/displays/panel-taal.c b/drivers/video/omap2/displays/panel-taal.c index 2b5777621779..fcd6a61a91eb 100644 --- a/drivers/video/omap2/displays/panel-taal.c +++ b/drivers/video/omap2/displays/panel-taal.c @@ -63,6 +63,8 @@ /* #define TAAL_USE_ESD_CHECK */ #define TAAL_ESD_CHECK_PERIOD msecs_to_jiffies(5000) +static int _taal_enable_te(struct omap_dss_device *dssdev, bool enable); + struct taal_data { struct backlight_device *bldev; @@ -666,6 +668,10 @@ static int taal_power_on(struct omap_dss_device *dssdev) taal_dcs_write_0(DCS_DISPLAY_ON); + r = _taal_enable_te(dssdev, td->te_enabled); + if (r) + goto err; + #ifdef TAAL_USE_ESD_CHECK queue_delayed_work(td->esd_wq, &td->esd_work, TAAL_ESD_CHECK_PERIOD); #endif @@ -828,13 +834,11 @@ static int taal_sync(struct omap_dss_device *dssdev) return 0; } -static int taal_enable_te(struct omap_dss_device *dssdev, bool enable) +static int _taal_enable_te(struct omap_dss_device *dssdev, bool enable) { struct taal_data *td = dev_get_drvdata(&dssdev->dev); int r; - dsi_bus_lock(); - td->te_enabled = enable; if (enable) @@ -848,6 +852,17 @@ static int taal_enable_te(struct omap_dss_device *dssdev, bool enable) * Panel bug? Needs more studying */ msleep(100); + return r; +} + +static int taal_enable_te(struct omap_dss_device *dssdev, bool enable) +{ + int r; + + dsi_bus_lock(); + + r = _taal_enable_te(dssdev, enable); + dsi_bus_unlock(); return r; -- cgit v1.2.2 From 48a29516e8b0b8cd59f5afec90a14f49dd9cf967 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Tue, 2 Mar 2010 22:46:10 +0000 Subject: cpmac: use after free The original code dereferenced "cpmac_mii" after calling "mdiobus_free(cpmac_mii);" Signed-off-by: Dan Carpenter Reviewed-by: Jiri Pirko Signed-off-by: David S. Miller --- drivers/net/cpmac.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/cpmac.c b/drivers/net/cpmac.c index b85c81f60d10..9d489421535e 100644 --- a/drivers/net/cpmac.c +++ b/drivers/net/cpmac.c @@ -1290,8 +1290,8 @@ void __devexit cpmac_exit(void) { platform_driver_unregister(&cpmac_driver); mdiobus_unregister(cpmac_mii); - mdiobus_free(cpmac_mii); iounmap(cpmac_mii->priv); + mdiobus_free(cpmac_mii); } module_init(cpmac_init); -- cgit v1.2.2 From 9fe969345b10931319b3f1e7034fbdeb786de234 Mon Sep 17 00:00:00 2001 From: Sarveshwar Bandi Date: Tue, 2 Mar 2010 22:37:28 +0000 Subject: be2net: download NCSI section during firmware update Adding code to update NCSI section while updating firmware on the controller. Signed-off-by: Sarveshwar Bandi Signed-off-by: David S. Miller --- drivers/net/benet/be_hw.h | 5 +++-- drivers/net/benet/be_main.c | 14 +++++++++++--- 2 files changed, 14 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/net/benet/be_hw.h b/drivers/net/benet/be_hw.h index 5ffb149181ad..2d4a4b827637 100644 --- a/drivers/net/benet/be_hw.h +++ b/drivers/net/benet/be_hw.h @@ -114,8 +114,7 @@ #define IMG_TYPE_ISCSI_BACKUP 9 #define IMG_TYPE_FCOE_FW_ACTIVE 10 #define IMG_TYPE_FCOE_FW_BACKUP 11 -#define IMG_TYPE_NCSI_BITFILE 13 -#define IMG_TYPE_NCSI_8051 14 +#define IMG_TYPE_NCSI_FW 13 #define FLASHROM_OPER_FLASH 1 #define FLASHROM_OPER_SAVE 2 @@ -127,6 +126,7 @@ #define FLASH_IMAGE_MAX_SIZE_g3 (2097152) /* Max fw image size */ #define FLASH_BIOS_IMAGE_MAX_SIZE_g3 (524288) /* Max OPTION ROM img sz */ #define FLASH_REDBOOT_IMAGE_MAX_SIZE_g3 (1048576) /* Max Redboot image sz */ +#define FLASH_NCSI_IMAGE_MAX_SIZE_g3 (262144) /* Max NSCI image sz */ #define FLASH_NCSI_MAGIC (0x16032009) #define FLASH_NCSI_DISABLED (0) @@ -144,6 +144,7 @@ #define FLASH_FCoE_BIOS_START_g2 (524288) #define FLASH_REDBOOT_START_g2 (0) +#define FLASH_NCSI_START_g3 (15990784) #define FLASH_iSCSI_PRIMARY_IMAGE_START_g3 (2097152) #define FLASH_iSCSI_BACKUP_IMAGE_START_g3 (4194304) #define FLASH_FCoE_PRIMARY_IMAGE_START_g3 (6291456) diff --git a/drivers/net/benet/be_main.c b/drivers/net/benet/be_main.c index a703ed8e24fe..22f787f2a30b 100644 --- a/drivers/net/benet/be_main.c +++ b/drivers/net/benet/be_main.c @@ -1880,8 +1880,9 @@ static int be_flash_data(struct be_adapter *adapter, const u8 *p = fw->data; struct be_cmd_write_flashrom *req = flash_cmd->va; struct flash_comp *pflashcomp; + int num_comp; - struct flash_comp gen3_flash_types[8] = { + struct flash_comp gen3_flash_types[9] = { { FLASH_iSCSI_PRIMARY_IMAGE_START_g3, IMG_TYPE_ISCSI_ACTIVE, FLASH_IMAGE_MAX_SIZE_g3}, { FLASH_REDBOOT_START_g3, IMG_TYPE_REDBOOT, @@ -1897,7 +1898,9 @@ static int be_flash_data(struct be_adapter *adapter, { FLASH_FCoE_PRIMARY_IMAGE_START_g3, IMG_TYPE_FCOE_FW_ACTIVE, FLASH_IMAGE_MAX_SIZE_g3}, { FLASH_FCoE_BACKUP_IMAGE_START_g3, IMG_TYPE_FCOE_FW_BACKUP, - FLASH_IMAGE_MAX_SIZE_g3} + FLASH_IMAGE_MAX_SIZE_g3}, + { FLASH_NCSI_START_g3, IMG_TYPE_NCSI_FW, + FLASH_NCSI_IMAGE_MAX_SIZE_g3} }; struct flash_comp gen2_flash_types[8] = { { FLASH_iSCSI_PRIMARY_IMAGE_START_g2, IMG_TYPE_ISCSI_ACTIVE, @@ -1921,11 +1924,16 @@ static int be_flash_data(struct be_adapter *adapter, if (adapter->generation == BE_GEN3) { pflashcomp = gen3_flash_types; filehdr_size = sizeof(struct flash_file_hdr_g3); + num_comp = 9; } else { pflashcomp = gen2_flash_types; filehdr_size = sizeof(struct flash_file_hdr_g2); + num_comp = 8; } - for (i = 0; i < 8; i++) { + for (i = 0; i < num_comp; i++) { + if ((pflashcomp[i].optype == IMG_TYPE_NCSI_FW) && + memcmp(adapter->fw_ver, "3.102.148.0", 11) < 0) + continue; if ((pflashcomp[i].optype == IMG_TYPE_REDBOOT) && (!be_flash_redboot(adapter, fw->data, pflashcomp[i].offset, pflashcomp[i].size, -- cgit v1.2.2 From bf829370a8d664d87a61697c8a0d6d780c336aa4 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Tue, 2 Mar 2010 22:22:41 +0000 Subject: cassini: fix off by one There are only 6 link_modes. Signed-off-by: Dan Carpenter Signed-off-by: David S. Miller --- drivers/net/cassini.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/cassini.c b/drivers/net/cassini.c index 7cbcfb0ade1c..9bd155e4111c 100644 --- a/drivers/net/cassini.c +++ b/drivers/net/cassini.c @@ -5072,7 +5072,7 @@ static int __devinit cas_init_one(struct pci_dev *pdev, INIT_WORK(&cp->reset_task, cas_reset_task); /* Default link parameters */ - if (link_mode >= 0 && link_mode <= 6) + if (link_mode >= 0 && link_mode < 6) cp->link_cntl = link_modes[link_mode]; else cp->link_cntl = BMCR_ANENABLE; -- cgit v1.2.2 From 4d27b87785a743fdae653d395a3a4e763269c53c Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Tue, 2 Mar 2010 21:07:24 +0000 Subject: davinci_emac: off by one This off by one error was found by smatch. drivers/net/davinci_emac.c +2390 emac_dev_open(13) error: buffer overflow 'priv->mac_addr' 6 <= 6 Signed-off-by: Dan Carpenter Signed-off-by: David S. Miller --- drivers/net/davinci_emac.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/davinci_emac.c b/drivers/net/davinci_emac.c index 1ac9440eb3fb..32960b9b02ae 100644 --- a/drivers/net/davinci_emac.c +++ b/drivers/net/davinci_emac.c @@ -2385,7 +2385,7 @@ static int emac_dev_open(struct net_device *ndev) struct emac_priv *priv = netdev_priv(ndev); netif_carrier_off(ndev); - for (cnt = 0; cnt <= ETH_ALEN; cnt++) + for (cnt = 0; cnt < ETH_ALEN; cnt++) ndev->dev_addr[cnt] = priv->mac_addr[cnt]; /* Configuration items */ -- cgit v1.2.2 From 4c020a961a812ffae9846b917304cea504c3a733 Mon Sep 17 00:00:00 2001 From: David Dillow Date: Wed, 3 Mar 2010 16:33:10 +0000 Subject: r8169: use correct barrier between cacheable and non-cacheable memory r8169 needs certain writes to be visible to other CPUs or the NIC before touching the hardware, but was using smp_wmb() which is only required to order cacheable memory access. Switch to wmb() which is required to order both cacheable and non-cacheable memory. Noticed by Catalin Marinas and Paul Mackerras. Signed-off-by: David Dillow Signed-off-by: David S. Miller --- drivers/net/r8169.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c index dfc3573c91bb..9d3ebf3e975e 100644 --- a/drivers/net/r8169.c +++ b/drivers/net/r8169.c @@ -4270,7 +4270,7 @@ static netdev_tx_t rtl8169_start_xmit(struct sk_buff *skb, tp->cur_tx += frags + 1; - smp_wmb(); + wmb(); RTL_W8(TxPoll, NPQ); /* set polling bit */ @@ -4621,7 +4621,7 @@ static int rtl8169_poll(struct napi_struct *napi, int budget) * until it does. */ tp->intr_mask = 0xffff; - smp_wmb(); + wmb(); RTL_W16(IntrMask, tp->intr_event); } -- cgit v1.2.2 From 0eddba525cf4c3a4aab9feaf36b12b465290d4a7 Mon Sep 17 00:00:00 2001 From: Anton Vorontsov Date: Wed, 3 Mar 2010 08:18:58 +0000 Subject: gianfar: Fix TX ring processing on SMP machines Starting with commit a3bc1f11e9b867a4f49505 ("gianfar: Revive SKB recycling") gianfar driver sooner or later stops transmitting any packets on SMP machines. start_xmit() prepares new skb for transmitting, generally it does three things: 1. sets up all BDs (marks them ready to send), except the first one. 2. stores skb into tx_queue->tx_skbuff so that clean_tx_ring() would cleanup it later. 3. sets up the first BD, i.e. marks it ready. Here is what clean_tx_ring() does: 1. reads skbs from tx_queue->tx_skbuff 2. checks if the *last* BD is ready. If it's still ready [to send] then it it isn't transmitted, so clean_tx_ring() returns. Otherwise it actually cleanups BDs. All is OK. Now, if there is just one BD, code flow: - start_xmit(): stores skb into tx_skbuff. Note that the first BD (which is also the last one) isn't marked as ready, yet. - clean_tx_ring(): sees that skb is not null, *and* its lstatus says that it is NOT ready (like if BD was sent), so it cleans it up (bad!) - start_xmit(): marks BD as ready [to send], but it's too late. We can fix this simply by reordering lstatus/tx_skbuff writes. Reported-by: Martyn Welch Bisected-by: Paul Gortmaker Signed-off-by: Anton Vorontsov Tested-by: Paul Gortmaker Tested-by: Martyn Welch Cc: Sandeep Gopalpet Cc: Stable [2.6.33] Signed-off-by: David S. Miller --- drivers/net/gianfar.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c index 6aa526ee9096..c3f061957c04 100644 --- a/drivers/net/gianfar.c +++ b/drivers/net/gianfar.c @@ -2021,7 +2021,6 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev) } /* setup the TxBD length and buffer pointer for the first BD */ - tx_queue->tx_skbuff[tx_queue->skb_curtx] = skb; txbdp_start->bufPtr = dma_map_single(&priv->ofdev->dev, skb->data, skb_headlen(skb), DMA_TO_DEVICE); @@ -2053,6 +2052,10 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev) txbdp_start->lstatus = lstatus; + eieio(); /* force lstatus write before tx_skbuff */ + + tx_queue->tx_skbuff[tx_queue->skb_curtx] = skb; + /* Update the current skb pointer to the next entry we will use * (wrapping if necessary) */ tx_queue->skb_curtx = (tx_queue->skb_curtx + 1) & -- cgit v1.2.2 From a6f018e324ba91d0464cca6895447c2b89e6d578 Mon Sep 17 00:00:00 2001 From: Divy Le Ray Date: Wed, 3 Mar 2010 09:49:47 +0000 Subject: cxgb3: fix hot plug removal crash queue restart tasklets need to be stopped after napi handlers are stopped since the latter can restart them. So stop them after stopping napi. Signed-off-by: Divy Le Ray Signed-off-by: David S. Miller --- drivers/net/cxgb3/cxgb3_main.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/net/cxgb3/cxgb3_main.c b/drivers/net/cxgb3/cxgb3_main.c index 6fd968abb073..cecdec1551db 100644 --- a/drivers/net/cxgb3/cxgb3_main.c +++ b/drivers/net/cxgb3/cxgb3_main.c @@ -1280,6 +1280,7 @@ static void cxgb_down(struct adapter *adapter) free_irq_resources(adapter); quiesce_rx(adapter); + t3_sge_stop(adapter); flush_workqueue(cxgb3_wq); /* wait for external IRQ handler */ } -- cgit v1.2.2 From 12c3400a84742f8bb0e4edc822e9ccba58781e0c Mon Sep 17 00:00:00 2001 From: Jiri Pirko Date: Thu, 4 Mar 2010 03:32:16 -0800 Subject: rndis_wlan: correct multicast_list handling V3 My previous patch (655ffee284dfcf9a24ac0343f3e5ee6db85b85c5) added locking in a bad way. Because rndis_set_oid can sleep, there is need to prepare multicast addresses into local buffer under netif_addr_lock first, then call rndis_set_oid outside. This caused reorganizing of the whole function. Signed-off-by: Jiri Pirko Reported-by: Jussi Kivilinna Signed-off-by: David S. Miller --- drivers/net/wireless/rndis_wlan.c | 66 ++++++++++++++++++++++++--------------- 1 file changed, 41 insertions(+), 25 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/rndis_wlan.c b/drivers/net/wireless/rndis_wlan.c index 9f6d6bf06b8e..2887047069f2 100644 --- a/drivers/net/wireless/rndis_wlan.c +++ b/drivers/net/wireless/rndis_wlan.c @@ -1496,51 +1496,67 @@ static void set_multicast_list(struct usbnet *usbdev) { struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); struct dev_mc_list *mclist; - __le32 filter; - int ret, i, size; - char *buf; + __le32 filter, basefilter; + int ret; + char *mc_addrs = NULL; + int mc_count; - filter = RNDIS_PACKET_TYPE_DIRECTED | RNDIS_PACKET_TYPE_BROADCAST; + basefilter = filter = RNDIS_PACKET_TYPE_DIRECTED | + RNDIS_PACKET_TYPE_BROADCAST; - netif_addr_lock_bh(usbdev->net); if (usbdev->net->flags & IFF_PROMISC) { filter |= RNDIS_PACKET_TYPE_PROMISCUOUS | RNDIS_PACKET_TYPE_ALL_LOCAL; - } else if (usbdev->net->flags & IFF_ALLMULTI || - netdev_mc_count(usbdev->net) > priv->multicast_size) { + } else if (usbdev->net->flags & IFF_ALLMULTI) { + filter |= RNDIS_PACKET_TYPE_ALL_MULTICAST; + } + + if (filter != basefilter) + goto set_filter; + + /* + * mc_list should be accessed holding the lock, so copy addresses to + * local buffer first. + */ + netif_addr_lock_bh(usbdev->net); + mc_count = netdev_mc_count(usbdev->net); + if (mc_count > priv->multicast_size) { filter |= RNDIS_PACKET_TYPE_ALL_MULTICAST; - } else if (!netdev_mc_empty(usbdev->net)) { - size = min(priv->multicast_size, netdev_mc_count(usbdev->net)); - buf = kmalloc(size * ETH_ALEN, GFP_KERNEL); - if (!buf) { + } else if (mc_count) { + int i = 0; + + mc_addrs = kmalloc(mc_count * ETH_ALEN, GFP_ATOMIC); + if (!mc_addrs) { netdev_warn(usbdev->net, "couldn't alloc %d bytes of memory\n", - size * ETH_ALEN); + mc_count * ETH_ALEN); netif_addr_unlock_bh(usbdev->net); return; } - i = 0; - netdev_for_each_mc_addr(mclist, usbdev->net) { - if (i == size) - break; - memcpy(buf + i++ * ETH_ALEN, mclist->dmi_addr, ETH_ALEN); - } + netdev_for_each_mc_addr(mclist, usbdev->net) + memcpy(mc_addrs + i++ * ETH_ALEN, + mclist->dmi_addr, ETH_ALEN); + } + netif_addr_unlock_bh(usbdev->net); - ret = rndis_set_oid(usbdev, OID_802_3_MULTICAST_LIST, buf, - i * ETH_ALEN); - if (ret == 0 && i > 0) + if (filter != basefilter) + goto set_filter; + + if (mc_count) { + ret = rndis_set_oid(usbdev, OID_802_3_MULTICAST_LIST, mc_addrs, + mc_count * ETH_ALEN); + kfree(mc_addrs); + if (ret == 0) filter |= RNDIS_PACKET_TYPE_MULTICAST; else filter |= RNDIS_PACKET_TYPE_ALL_MULTICAST; netdev_dbg(usbdev->net, "OID_802_3_MULTICAST_LIST(%d, max: %d) -> %d\n", - i, priv->multicast_size, ret); - - kfree(buf); + mc_count, priv->multicast_size, ret); } - netif_addr_unlock_bh(usbdev->net); +set_filter: ret = rndis_set_oid(usbdev, OID_GEN_CURRENT_PACKET_FILTER, &filter, sizeof(filter)); if (ret < 0) { -- cgit v1.2.2 From 4b79a1aedcb9dd6e3f27b970dcb553aefcd97254 Mon Sep 17 00:00:00 2001 From: David Brown Date: Fri, 5 Mar 2010 09:12:34 +0000 Subject: net: smc91x: Support Qualcomm MSM development boards. Signed-off-by: David Brown Signed-off-by: Daniel Walker Acked-by: Nicolas Pitre Signed-off-by: David S. Miller --- drivers/net/smc91x.h | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'drivers') diff --git a/drivers/net/smc91x.h b/drivers/net/smc91x.h index 54799544bda3..a6ee883d1b0e 100644 --- a/drivers/net/smc91x.h +++ b/drivers/net/smc91x.h @@ -330,6 +330,20 @@ static inline void LPD7_SMC_outsw (unsigned char* a, int r, #include +#elif defined(CONFIG_ARCH_MSM) + +#define SMC_CAN_USE_8BIT 0 +#define SMC_CAN_USE_16BIT 1 +#define SMC_CAN_USE_32BIT 0 +#define SMC_NOWAIT 1 + +#define SMC_inw(a, r) readw((a) + (r)) +#define SMC_outw(v, a, r) writew(v, (a) + (r)) +#define SMC_insw(a, r, p, l) readsw((a) + (r), p, l) +#define SMC_outsw(a, r, p, l) writesw((a) + (r), p, l) + +#define SMC_IRQ_FLAGS IRQF_TRIGGER_HIGH + #else /* -- cgit v1.2.2 From 5fe88eae26dbd24eed73eb0b681e13981fd486b3 Mon Sep 17 00:00:00 2001 From: David Dillow Date: Thu, 4 Mar 2010 04:37:16 +0000 Subject: typhoon: fix incorrect use of smp_wmb() The typhoon driver was incorrectly using smp_wmb() to order memory accesses against IO to the NIC in a few instances. Use wmb() instead, which is required to actually order between memory types. Signed-off-by: David Dillow Signed-off-by: David S. Miller --- drivers/net/typhoon.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/typhoon.c b/drivers/net/typhoon.c index e3ddcb8f29df..1cf012d3e072 100644 --- a/drivers/net/typhoon.c +++ b/drivers/net/typhoon.c @@ -480,7 +480,7 @@ typhoon_hello(struct typhoon *tp) typhoon_inc_cmd_index(&ring->lastWrite, 1); INIT_COMMAND_NO_RESPONSE(cmd, TYPHOON_CMD_HELLO_RESP); - smp_wmb(); + wmb(); iowrite32(ring->lastWrite, tp->ioaddr + TYPHOON_REG_CMD_READY); spin_unlock(&tp->command_lock); } @@ -1311,13 +1311,15 @@ typhoon_init_interface(struct typhoon *tp) tp->txlo_dma_addr = le32_to_cpu(iface->txLoAddr); tp->card_state = Sleeping; - smp_wmb(); tp->offload = TYPHOON_OFFLOAD_IP_CHKSUM | TYPHOON_OFFLOAD_TCP_CHKSUM; tp->offload |= TYPHOON_OFFLOAD_UDP_CHKSUM | TSO_OFFLOAD_ON; spin_lock_init(&tp->command_lock); spin_lock_init(&tp->state_lock); + + /* Force the writes to the shared memory area out before continuing. */ + wmb(); } static void -- cgit v1.2.2 From a80483d3722b603dae8a52495f8d88a7d4b1bf1c Mon Sep 17 00:00:00 2001 From: Jesse Brandeburg Date: Fri, 5 Mar 2010 02:21:44 +0000 Subject: e1000e: fix packet corruption and tx hang during NFSv2 when receiving a particular type of NFS v2 UDP traffic, the hardware could DMA some bad data and then hang, possibly corrupting memory. Disable the NFS parsing in this hardware, verified to fix the bug. Originally reported and reproduced by RedHat's Neil Horman CC: nhorman@tuxdriver.com Signed-off-by: Jesse Brandeburg Signed-off-by: Jeff Kirsher Acked-by: Neil Horman Signed-off-by: David S. Miller --- drivers/net/e1000e/defines.h | 2 ++ drivers/net/e1000e/ich8lan.c | 10 ++++++++++ 2 files changed, 12 insertions(+) (limited to 'drivers') diff --git a/drivers/net/e1000e/defines.h b/drivers/net/e1000e/defines.h index db05ec355749..e301e26d6897 100644 --- a/drivers/net/e1000e/defines.h +++ b/drivers/net/e1000e/defines.h @@ -320,6 +320,8 @@ #define E1000_RXCSUM_IPPCSE 0x00001000 /* IP payload checksum enable */ /* Header split receive */ +#define E1000_RFCTL_NFSW_DIS 0x00000040 +#define E1000_RFCTL_NFSR_DIS 0x00000080 #define E1000_RFCTL_ACK_DIS 0x00001000 #define E1000_RFCTL_EXTEN 0x00008000 #define E1000_RFCTL_IPV6_EX_DIS 0x00010000 diff --git a/drivers/net/e1000e/ich8lan.c b/drivers/net/e1000e/ich8lan.c index 54d03a0ce3ce..8b5e157e9c87 100644 --- a/drivers/net/e1000e/ich8lan.c +++ b/drivers/net/e1000e/ich8lan.c @@ -2740,6 +2740,16 @@ static void e1000_initialize_hw_bits_ich8lan(struct e1000_hw *hw) reg &= ~(1 << 31); ew32(STATUS, reg); } + + /* + * work-around descriptor data corruption issue during nfs v2 udp + * traffic, just disable the nfs filtering capability + */ + reg = er32(RFCTL); + reg |= (E1000_RFCTL_NFSW_DIS | E1000_RFCTL_NFSR_DIS); + ew32(RFCTL, reg); + + return; } /** -- cgit v1.2.2 From 3a22813a5aaf8e8c72be575dabe0ba26f9352f4d Mon Sep 17 00:00:00 2001 From: Breno Leitao Date: Thu, 4 Mar 2010 10:40:44 +0000 Subject: s2io: Fixing debug message Currently s2io is dumping debug messages using the interface name before it was allocated, showing a message like the following: s2io: eth%d: Ring Mem PHY: 0x7ef80000 s2io: s2io_reset: Resetting XFrame card eth%d This patch just fixes it, printing the pci bus information for the card instead of the interface name. Signed-off-by: Breno Leitao Signed-off-by: David S. Miller --- drivers/net/s2io.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c index 43bc66aa8405..df70657260dd 100644 --- a/drivers/net/s2io.c +++ b/drivers/net/s2io.c @@ -923,8 +923,8 @@ static int init_shared_mem(struct s2io_nic *nic) tmp_v_addr = mac_control->stats_mem; mac_control->stats_info = (struct stat_block *)tmp_v_addr; memset(tmp_v_addr, 0, size); - DBG_PRINT(INIT_DBG, "%s: Ring Mem PHY: 0x%llx\n", dev->name, - (unsigned long long)tmp_p_addr); + DBG_PRINT(INIT_DBG, "%s: Ring Mem PHY: 0x%llx\n", + dev_name(&nic->pdev->dev), (unsigned long long)tmp_p_addr); mac_control->stats_info->sw_stat.mem_allocated += mem_allocated; return SUCCESS; } @@ -3480,7 +3480,7 @@ static void s2io_reset(struct s2io_nic *sp) struct swStat *swstats; DBG_PRINT(INIT_DBG, "%s: Resetting XFrame card %s\n", - __func__, sp->dev->name); + __func__, pci_name(sp->pdev)); /* Back up the PCI-X CMD reg, dont want to lose MMRBC, OST settings */ pci_read_config_word(sp->pdev, PCIX_COMMAND_REGISTER, &(pci_cmd)); -- cgit v1.2.2 From b96b894c518bc7399e6b86b635b5e8cd7356a8e9 Mon Sep 17 00:00:00 2001 From: "Figo.zhang" Date: Fri, 5 Mar 2010 16:36:02 +0000 Subject: fix a race in ks8695_poll fix a race at the end of NAPI processing in ks8695_poll() function. Signed-off-by:Figo.zhang Signed-off-by: David S. Miller --- drivers/net/arm/ks8695net.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/arm/ks8695net.c b/drivers/net/arm/ks8695net.c index 8ca639127dbc..a1d4188c430b 100644 --- a/drivers/net/arm/ks8695net.c +++ b/drivers/net/arm/ks8695net.c @@ -575,9 +575,9 @@ static int ks8695_poll(struct napi_struct *napi, int budget) if (work_done < budget) { unsigned long flags; spin_lock_irqsave(&ksp->rx_lock, flags); + __napi_complete(napi); /*enable rx interrupt*/ writel(isr | mask_bit, KS8695_IRQ_VA + KS8695_INTEN); - __napi_complete(napi); spin_unlock_irqrestore(&ksp->rx_lock, flags); } return work_done; -- cgit v1.2.2 From ea3fb371b2a391958670f2a65e1203f7dba61671 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Sat, 6 Mar 2010 01:11:38 +0000 Subject: ems_usb: cleanup: remove uneeded check "skb" is alway non-null here, but even if it were null the check isn't needed because dev_kfree_skb() can handle it. This eliminates a smatch warning about dereferencing a variable before checking that it is non-null. Signed-off-by: Dan Carpenter Signed-off-by: David S. Miller --- drivers/net/can/usb/ems_usb.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/can/usb/ems_usb.c b/drivers/net/can/usb/ems_usb.c index 11c87840cc00..33451092b8e8 100644 --- a/drivers/net/can/usb/ems_usb.c +++ b/drivers/net/can/usb/ems_usb.c @@ -876,9 +876,7 @@ static netdev_tx_t ems_usb_start_xmit(struct sk_buff *skb, struct net_device *ne return NETDEV_TX_OK; nomem: - if (skb) - dev_kfree_skb(skb); - + dev_kfree_skb(skb); stats->tx_dropped++; return NETDEV_TX_OK; -- cgit v1.2.2 From 0e2b807234c42fab59f98ec913db30dfda0e63a7 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Sun, 7 Mar 2010 02:35:42 +0000 Subject: irda-usb: add error handling and fix leak If the call to kcalloc() fails then we should return -ENOMEM. Signed-off-by: Dan Carpenter Signed-off-by: David S. Miller --- drivers/net/irda/irda-usb.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers') diff --git a/drivers/net/irda/irda-usb.c b/drivers/net/irda/irda-usb.c index e8e33bb9d876..2c9b3af16612 100644 --- a/drivers/net/irda/irda-usb.c +++ b/drivers/net/irda/irda-usb.c @@ -1651,6 +1651,8 @@ static int irda_usb_probe(struct usb_interface *intf, self->rx_urb = kcalloc(self->max_rx_urb, sizeof(struct urb *), GFP_KERNEL); + if (!self->rx_urb) + goto err_free_net; for (i = 0; i < self->max_rx_urb; i++) { self->rx_urb[i] = usb_alloc_urb(0, GFP_KERNEL); @@ -1783,6 +1785,8 @@ err_out_2: err_out_1: for (i = 0; i < self->max_rx_urb; i++) usb_free_urb(self->rx_urb[i]); + kfree(self->rx_urb); +err_free_net: free_netdev(net); err_out: return ret; -- cgit v1.2.2 From e7111eac8ebda724d1e4d9e6aaf4569744a584d5 Mon Sep 17 00:00:00 2001 From: Petko Manolov Date: Sun, 7 Mar 2010 06:10:01 +0000 Subject: another pegasus usb net device This one removes trailing whitespace in pegasus.h and more importantly adds new Pegasus compatible device. Signed-off-by: Julian Brown Signed-off-by: Petko Manolov Signed-off-by: David S. Miller --- drivers/net/usb/pegasus.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/usb/pegasus.h b/drivers/net/usb/pegasus.h index 5d02f0200737..b90d8766ab74 100644 --- a/drivers/net/usb/pegasus.h +++ b/drivers/net/usb/pegasus.h @@ -177,7 +177,7 @@ PEGASUS_DEV( "USB 10/100 Fast Ethernet", VENDOR_ABOCOM, 0x400c, PEGASUS_DEV( "USB 10/100 Fast Ethernet", VENDOR_ABOCOM, 0xabc1, DEFAULT_GPIO_RESET ) PEGASUS_DEV( "USB 10/100 Fast Ethernet", VENDOR_ABOCOM, 0x200c, - DEFAULT_GPIO_RESET | PEGASUS_II ) + DEFAULT_GPIO_RESET | PEGASUS_II ) PEGASUS_DEV( "Accton USB 10/100 Ethernet Adapter", VENDOR_ACCTON, 0x1046, DEFAULT_GPIO_RESET ) PEGASUS_DEV( "SpeedStream USB 10/100 Ethernet", VENDOR_ACCTON, 0x5046, @@ -208,6 +208,8 @@ PEGASUS_DEV( "Allied Telesyn Int. AT-USB100", VENDOR_ALLIEDTEL, 0xb100, */ PEGASUS_DEV_CLASS( "Belkin F5D5050 USB Ethernet", VENDOR_BELKIN, 0x0121, 0x00, DEFAULT_GPIO_RESET | PEGASUS_II ) +PEGASUS_DEV( "Belkin F5U122 10/100 USB Ethernet", VENDOR_BELKIN, 0x0122, + DEFAULT_GPIO_RESET | PEGASUS_II ) PEGASUS_DEV( "Billionton USB-100", VENDOR_BILLIONTON, 0x0986, DEFAULT_GPIO_RESET ) PEGASUS_DEV( "Billionton USBLP-100", VENDOR_BILLIONTON, 0x0987, @@ -249,7 +251,7 @@ PEGASUS_DEV( "GIGABYTE GN-BR402W Wireless Router", VENDOR_GIGABYTE, 0x8002, PEGASUS_DEV( "Hawking UF100 10/100 Ethernet", VENDOR_HAWKING, 0x400c, DEFAULT_GPIO_RESET | PEGASUS_II ) PEGASUS_DEV( "HP hn210c Ethernet USB", VENDOR_HP, 0x811c, - DEFAULT_GPIO_RESET | PEGASUS_II ) + DEFAULT_GPIO_RESET | PEGASUS_II ) PEGASUS_DEV( "IO DATA USB ET/TX", VENDOR_IODATA, 0x0904, DEFAULT_GPIO_RESET ) PEGASUS_DEV( "IO DATA USB ET/TX-S", VENDOR_IODATA, 0x0913, -- cgit v1.2.2 From 30765d0502905a9248e5de72fc7ac83c23422861 Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Sun, 7 Mar 2010 00:55:26 +0000 Subject: cpmac: fix the receiving of 802.1q frames Despite what the comment above CPMAC_SKB_SIZE says, the hardware also needs to account for the FCS length in a received frame. This patch fix the receiving of 802.1q frames which have 4 more bytes. While at it unhardcode the definition and use the one from if_vlan.h. Signed-off-by: Florian Fainelli Signed-off-by: David S. Miller --- drivers/net/cpmac.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/cpmac.c b/drivers/net/cpmac.c index 9d489421535e..55ee055d3321 100644 --- a/drivers/net/cpmac.c +++ b/drivers/net/cpmac.c @@ -28,6 +28,7 @@ #include #include +#include #include #include #include @@ -56,8 +57,8 @@ MODULE_PARM_DESC(debug_level, "Number of NETIF_MSG bits to enable"); MODULE_PARM_DESC(dumb_switch, "Assume switch is not connected to MDIO bus"); #define CPMAC_VERSION "0.5.1" -/* frame size + 802.1q tag */ -#define CPMAC_SKB_SIZE (ETH_FRAME_LEN + 4) +/* frame size + 802.1q tag + FCS size */ +#define CPMAC_SKB_SIZE (ETH_FRAME_LEN + ETH_FCS_LEN + VLAN_HLEN) #define CPMAC_QUEUES 8 /* Ethernet registers */ -- cgit v1.2.2 From 9fba1c31f4f3f9f860a4afee0b409cde27d06741 Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Sun, 7 Mar 2010 00:55:47 +0000 Subject: cpmac: fallback to switch mode if no PHY chip found If we were unable to detect a PHY on any of the MDIO bus id we tried instead of bailing out with -ENODEV, assume the MAC is connected to a switch and use MDIO bus 0. This unbreaks quite a lot of devices out there whose switch cannot be detected. Signed-off-by: Florian Fainelli Signed-off-by: David S. Miller --- drivers/net/cpmac.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/cpmac.c b/drivers/net/cpmac.c index 55ee055d3321..baeb5bab05b5 100644 --- a/drivers/net/cpmac.c +++ b/drivers/net/cpmac.c @@ -1137,8 +1137,9 @@ static int __devinit cpmac_probe(struct platform_device *pdev) } if (phy_id == PHY_MAX_ADDR) { - dev_err(&pdev->dev, "no PHY present\n"); - return -ENODEV; + dev_err(&pdev->dev, "no PHY present, falling back to switch on MDIO bus 0\n"); + strncpy(mdio_bus_id, "0", MII_BUS_ID_SIZE); /* fixed phys bus */ + phy_id = pdev->id; } dev = alloc_etherdev_mq(sizeof(*priv), CPMAC_QUEUES); -- cgit v1.2.2 From 25dc27d17dc868aae78fd03bef3113cf586b12e5 Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Sun, 7 Mar 2010 00:55:50 +0000 Subject: cpmac: bump version to 0.5.2 Signed-off-by: Florian Fainelli Signed-off-by: David S. Miller --- drivers/net/cpmac.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/cpmac.c b/drivers/net/cpmac.c index baeb5bab05b5..60777fd90b33 100644 --- a/drivers/net/cpmac.c +++ b/drivers/net/cpmac.c @@ -56,7 +56,7 @@ module_param(dumb_switch, int, 0444); MODULE_PARM_DESC(debug_level, "Number of NETIF_MSG bits to enable"); MODULE_PARM_DESC(dumb_switch, "Assume switch is not connected to MDIO bus"); -#define CPMAC_VERSION "0.5.1" +#define CPMAC_VERSION "0.5.2" /* frame size + 802.1q tag + FCS size */ #define CPMAC_SKB_SIZE (ETH_FRAME_LEN + ETH_FCS_LEN + VLAN_HLEN) #define CPMAC_QUEUES 8 -- cgit v1.2.2 From 500ca9ba241304937c54c379e515b24400379353 Mon Sep 17 00:00:00 2001 From: Ajit Khaparde Date: Sun, 7 Mar 2010 14:21:27 +0000 Subject: be2net: remove usage of be_pci_func When PCI functions are virtuialized in applications by assigning PCI functions to VM (PCI passthrough), the be2net driver in the VM sees a different function number. So, use of PCI function number in any calculation will break existing code. This patch takes care of it. Signed-off-by: Ajit Khaparde Signed-off-by: David S. Miller --- drivers/net/benet/be.h | 5 ----- drivers/net/benet/be_cmds.c | 6 ------ drivers/net/benet/be_main.c | 2 +- 3 files changed, 1 insertion(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/net/benet/be.h b/drivers/net/benet/be.h index be81fb2d10f7..8f0752553681 100644 --- a/drivers/net/benet/be.h +++ b/drivers/net/benet/be.h @@ -290,11 +290,6 @@ extern const struct ethtool_ops be_ethtool_ops; #define drvr_stats(adapter) (&adapter->stats.drvr_stats) -static inline unsigned int be_pci_func(struct be_adapter *adapter) -{ - return PCI_FUNC(adapter->pdev->devfn); -} - #define BE_SET_NETDEV_OPS(netdev, ops) (netdev->netdev_ops = ops) #define PAGE_SHIFT_4K 12 diff --git a/drivers/net/benet/be_cmds.c b/drivers/net/benet/be_cmds.c index 4b1f80519ca4..c59215361f4e 100644 --- a/drivers/net/benet/be_cmds.c +++ b/drivers/net/benet/be_cmds.c @@ -465,8 +465,6 @@ int be_cmd_eq_create(struct be_adapter *adapter, req->num_pages = cpu_to_le16(PAGES_4K_SPANNED(q_mem->va, q_mem->size)); - AMAP_SET_BITS(struct amap_eq_context, func, req->context, - be_pci_func(adapter)); AMAP_SET_BITS(struct amap_eq_context, valid, req->context, 1); /* 4byte eqe*/ AMAP_SET_BITS(struct amap_eq_context, size, req->context, 0); @@ -629,7 +627,6 @@ int be_cmd_cq_create(struct be_adapter *adapter, AMAP_SET_BITS(struct amap_cq_context, eventable, ctxt, 1); AMAP_SET_BITS(struct amap_cq_context, eqid, ctxt, eq->id); AMAP_SET_BITS(struct amap_cq_context, armed, ctxt, 1); - AMAP_SET_BITS(struct amap_cq_context, func, ctxt, be_pci_func(adapter)); be_dws_cpu_to_le(ctxt, sizeof(req->context)); be_cmd_page_addrs_prepare(req->pages, ARRAY_SIZE(req->pages), q_mem); @@ -678,7 +675,6 @@ int be_cmd_mccq_create(struct be_adapter *adapter, req->num_pages = PAGES_4K_SPANNED(q_mem->va, q_mem->size); - AMAP_SET_BITS(struct amap_mcc_context, fid, ctxt, be_pci_func(adapter)); AMAP_SET_BITS(struct amap_mcc_context, valid, ctxt, 1); AMAP_SET_BITS(struct amap_mcc_context, ring_size, ctxt, be_encoded_q_len(mccq->len)); @@ -727,8 +723,6 @@ int be_cmd_txq_create(struct be_adapter *adapter, AMAP_SET_BITS(struct amap_tx_context, tx_ring_size, ctxt, be_encoded_q_len(txq->len)); - AMAP_SET_BITS(struct amap_tx_context, pci_func_id, ctxt, - be_pci_func(adapter)); AMAP_SET_BITS(struct amap_tx_context, ctx_valid, ctxt, 1); AMAP_SET_BITS(struct amap_tx_context, cq_id_send, ctxt, cq->id); diff --git a/drivers/net/benet/be_main.c b/drivers/net/benet/be_main.c index 22f787f2a30b..7c9b57eb780e 100644 --- a/drivers/net/benet/be_main.c +++ b/drivers/net/benet/be_main.c @@ -1382,7 +1382,7 @@ rx_eq_free: /* There are 8 evt ids per func. Retruns the evt id's bit number */ static inline int be_evt_bit_get(struct be_adapter *adapter, u32 eq_id) { - return eq_id - 8 * be_pci_func(adapter); + return eq_id % 8; } static irqreturn_t be_intx(int irq, void *dev) -- cgit v1.2.2 From 7e8a9298adf7531c58d73ba9c499353e3807cf19 Mon Sep 17 00:00:00 2001 From: Ajit Khaparde Date: Sun, 7 Mar 2010 14:23:44 +0000 Subject: be2net: remove unused code in be_load_fw This patch cleans up some unused code from be_load_fw(). Signed-off-by: Ajit Khaparde Signed-off-by: David S. Miller --- drivers/net/benet/be_main.c | 9 --------- 1 file changed, 9 deletions(-) (limited to 'drivers') diff --git a/drivers/net/benet/be_main.c b/drivers/net/benet/be_main.c index 7c9b57eb780e..43e8032f9236 100644 --- a/drivers/net/benet/be_main.c +++ b/drivers/net/benet/be_main.c @@ -1993,16 +1993,7 @@ int be_load_fw(struct be_adapter *adapter, u8 *func) struct be_dma_mem flash_cmd; int status, i = 0; const u8 *p; - char fw_ver[FW_VER_LEN]; - char fw_cfg; - status = be_cmd_get_fw_ver(adapter, fw_ver); - if (status) - return status; - - fw_cfg = *(fw_ver + 2); - if (fw_cfg == '0') - fw_cfg = '1'; strcpy(fw_file, func); status = request_firmware(&fw, fw_file, &adapter->pdev->dev); -- cgit v1.2.2 From 8bae5698616ac336938684ce7a7370299bd55d01 Mon Sep 17 00:00:00 2001 From: Sucheta Chakraborty Date: Mon, 8 Mar 2010 00:14:45 +0000 Subject: qlcnic: fix tx csum status Kernel default tx csum function (ethtool_op_get_tx_csum) doesn't show correct csum status. It takes various FLAGS (NETIF_F_ALL_CSUM) in account to show tx csum status, which driver doesn't set while disabling tx csum. Signed-off-by: Sucheta Chakraborty Signed-off-by: Amit Kumar Salecha Signed-off-by: David S. Miller --- drivers/net/qlcnic/qlcnic_ethtool.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'drivers') diff --git a/drivers/net/qlcnic/qlcnic_ethtool.c b/drivers/net/qlcnic/qlcnic_ethtool.c index 8da6ec8c13b9..ef12792a88be 100644 --- a/drivers/net/qlcnic/qlcnic_ethtool.c +++ b/drivers/net/qlcnic/qlcnic_ethtool.c @@ -785,6 +785,11 @@ qlcnic_get_ethtool_stats(struct net_device *dev, } } +static u32 qlcnic_get_tx_csum(struct net_device *dev) +{ + return dev->features & NETIF_F_IP_CSUM; +} + static u32 qlcnic_get_rx_csum(struct net_device *dev) { struct qlcnic_adapter *adapter = netdev_priv(dev); @@ -995,6 +1000,7 @@ const struct ethtool_ops qlcnic_ethtool_ops = { .set_ringparam = qlcnic_set_ringparam, .get_pauseparam = qlcnic_get_pauseparam, .set_pauseparam = qlcnic_set_pauseparam, + .get_tx_csum = qlcnic_get_tx_csum, .set_tx_csum = ethtool_op_set_tx_csum, .set_sg = ethtool_op_set_sg, .get_tso = qlcnic_get_tso, -- cgit v1.2.2 From 8bfe8b91b8b877066c8ac788f59a40324eaac6d8 Mon Sep 17 00:00:00 2001 From: Sucheta Chakraborty Date: Mon, 8 Mar 2010 00:14:46 +0000 Subject: qlcnic: additional driver statistics. Statistics added for lro/lso bytes, count for tx stop queue and wake queue and skb alloc failure count. Signed-off-by: Sucheta Chakraborty Signed-off-by: Amit Kumar Salecha Signed-off-by: David S. Miller --- drivers/net/qlcnic/qlcnic.h | 5 +++++ drivers/net/qlcnic/qlcnic_ethtool.c | 11 +++++++++++ drivers/net/qlcnic/qlcnic_hw.c | 1 + drivers/net/qlcnic/qlcnic_init.c | 8 ++++++-- drivers/net/qlcnic/qlcnic_main.c | 5 +++++ 5 files changed, 28 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/qlcnic/qlcnic.h b/drivers/net/qlcnic/qlcnic.h index b40a851ec7d1..9897b699752f 100644 --- a/drivers/net/qlcnic/qlcnic.h +++ b/drivers/net/qlcnic/qlcnic.h @@ -423,6 +423,11 @@ struct qlcnic_adapter_stats { u64 lro_pkts; u64 rxbytes; u64 txbytes; + u64 lrobytes; + u64 lso_frames; + u64 xmit_on; + u64 xmit_off; + u64 skb_alloc_failure; }; /* diff --git a/drivers/net/qlcnic/qlcnic_ethtool.c b/drivers/net/qlcnic/qlcnic_ethtool.c index ef12792a88be..f83e15fe3e1b 100644 --- a/drivers/net/qlcnic/qlcnic_ethtool.c +++ b/drivers/net/qlcnic/qlcnic_ethtool.c @@ -59,6 +59,17 @@ static const struct qlcnic_stats qlcnic_gstrings_stats[] = { QLC_SIZEOF(stats.rxbytes), QLC_OFF(stats.rxbytes)}, {"tx_bytes", QLC_SIZEOF(stats.txbytes), QLC_OFF(stats.txbytes)}, + {"lrobytes", + QLC_SIZEOF(stats.lrobytes), QLC_OFF(stats.lrobytes)}, + {"lso_frames", + QLC_SIZEOF(stats.lso_frames), QLC_OFF(stats.lso_frames)}, + {"xmit_on", + QLC_SIZEOF(stats.xmit_on), QLC_OFF(stats.xmit_on)}, + {"xmit_off", + QLC_SIZEOF(stats.xmit_off), QLC_OFF(stats.xmit_off)}, + {"skb_alloc_failure", QLC_SIZEOF(stats.skb_alloc_failure), + QLC_OFF(stats.skb_alloc_failure)}, + }; #define QLCNIC_STATS_LEN ARRAY_SIZE(qlcnic_gstrings_stats) diff --git a/drivers/net/qlcnic/qlcnic_hw.c b/drivers/net/qlcnic/qlcnic_hw.c index 99a4d1379d00..e95646bf7d56 100644 --- a/drivers/net/qlcnic/qlcnic_hw.c +++ b/drivers/net/qlcnic/qlcnic_hw.c @@ -349,6 +349,7 @@ qlcnic_send_cmd_descs(struct qlcnic_adapter *adapter, if (nr_desc >= qlcnic_tx_avail(tx_ring)) { netif_tx_stop_queue(tx_ring->txq); __netif_tx_unlock_bh(tx_ring->txq); + adapter->stats.xmit_off++; return -EBUSY; } diff --git a/drivers/net/qlcnic/qlcnic_init.c b/drivers/net/qlcnic/qlcnic_init.c index ea00ab4d4feb..f0df9717aece 100644 --- a/drivers/net/qlcnic/qlcnic_init.c +++ b/drivers/net/qlcnic/qlcnic_init.c @@ -1114,8 +1114,10 @@ qlcnic_alloc_rx_skb(struct qlcnic_adapter *adapter, struct pci_dev *pdev = adapter->pdev; buffer->skb = dev_alloc_skb(rds_ring->skb_size); - if (!buffer->skb) + if (!buffer->skb) { + adapter->stats.skb_alloc_failure++; return -ENOMEM; + } skb = buffer->skb; @@ -1289,7 +1291,7 @@ qlcnic_process_lro(struct qlcnic_adapter *adapter, netif_receive_skb(skb); adapter->stats.lro_pkts++; - adapter->stats.rxbytes += length; + adapter->stats.lrobytes += length; return buffer; } @@ -1505,6 +1507,8 @@ qlcnic_process_rcv_diag(struct qlcnic_adapter *adapter, adapter->diag_cnt++; dev_kfree_skb_any(skb); + adapter->stats.rx_pkts++; + adapter->stats.rxbytes += length; return buffer; } diff --git a/drivers/net/qlcnic/qlcnic_main.c b/drivers/net/qlcnic/qlcnic_main.c index 665e8e56b6a8..fc721564e69e 100644 --- a/drivers/net/qlcnic/qlcnic_main.c +++ b/drivers/net/qlcnic/qlcnic_main.c @@ -118,6 +118,7 @@ qlcnic_update_cmd_producer(struct qlcnic_adapter *adapter, if (qlcnic_tx_avail(tx_ring) <= TX_STOP_THRESH) { netif_stop_queue(adapter->netdev); smp_mb(); + adapter->stats.xmit_off++; } } @@ -1385,6 +1386,7 @@ qlcnic_tso_check(struct net_device *netdev, int copied, offset, copy_len, hdr_len = 0, tso = 0, vlan_oob = 0; struct cmd_desc_type0 *hwdesc; struct vlan_ethhdr *vh; + struct qlcnic_adapter *adapter = netdev_priv(netdev); if (protocol == cpu_to_be16(ETH_P_8021Q)) { @@ -1494,6 +1496,7 @@ qlcnic_tso_check(struct net_device *netdev, tx_ring->producer = producer; barrier(); + adapter->stats.lso_frames++; } static int @@ -1573,6 +1576,7 @@ qlcnic_xmit_frame(struct sk_buff *skb, struct net_device *netdev) if (unlikely(no_of_desc + 2 > qlcnic_tx_avail(tx_ring))) { netif_stop_queue(netdev); + adapter->stats.xmit_off++; return NETDEV_TX_BUSY; } @@ -1880,6 +1884,7 @@ static int qlcnic_process_cmd_ring(struct qlcnic_adapter *adapter) if (qlcnic_tx_avail(tx_ring) > TX_STOP_THRESH) { netif_wake_queue(netdev); adapter->tx_timeo_cnt = 0; + adapter->stats.xmit_on++; } __netif_tx_unlock(tx_ring->txq); } -- cgit v1.2.2 From 9ab17b3968f9521bb4fffd8767953d2b0148aad0 Mon Sep 17 00:00:00 2001 From: Sucheta Chakraborty Date: Mon, 8 Mar 2010 00:14:47 +0000 Subject: qlcnic: fix multicast handling For promiscuous mode, driver send request to device for deleting multicast addresses and again it send request for adding them back while exiting from this mode, this is bad for performance. Just setting device in promiscuous mode is enough, no need to del/add multicast addresses. Signed-off-by: Sucheta Chakraborty Signed-off-by: Amit Kumar Salecha Signed-off-by: David S. Miller --- drivers/net/qlcnic/qlcnic_hw.c | 31 ++++++------------------------- 1 file changed, 6 insertions(+), 25 deletions(-) (limited to 'drivers') diff --git a/drivers/net/qlcnic/qlcnic_hw.c b/drivers/net/qlcnic/qlcnic_hw.c index e95646bf7d56..da00e162b6d3 100644 --- a/drivers/net/qlcnic/qlcnic_hw.c +++ b/drivers/net/qlcnic/qlcnic_hw.c @@ -398,20 +398,16 @@ qlcnic_sre_macaddr_change(struct qlcnic_adapter *adapter, u8 *addr, return qlcnic_send_cmd_descs(adapter, (struct cmd_desc_type0 *)&req, 1); } -static int qlcnic_nic_add_mac(struct qlcnic_adapter *adapter, - u8 *addr, struct list_head *del_list) +static int qlcnic_nic_add_mac(struct qlcnic_adapter *adapter, u8 *addr) { struct list_head *head; struct qlcnic_mac_list_s *cur; /* look up if already exists */ - list_for_each(head, del_list) { + list_for_each(head, &adapter->mac_list) { cur = list_entry(head, struct qlcnic_mac_list_s, list); - - if (memcmp(addr, cur->mac_addr, ETH_ALEN) == 0) { - list_move_tail(head, &adapter->mac_list); + if (memcmp(addr, cur->mac_addr, ETH_ALEN) == 0) return 0; - } } cur = kzalloc(sizeof(struct qlcnic_mac_list_s), GFP_ATOMIC); @@ -433,14 +429,9 @@ void qlcnic_set_multi(struct net_device *netdev) struct dev_mc_list *mc_ptr; u8 bcast_addr[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; u32 mode = VPORT_MISS_MODE_DROP; - LIST_HEAD(del_list); - struct list_head *head; - struct qlcnic_mac_list_s *cur; - list_splice_tail_init(&adapter->mac_list, &del_list); - - qlcnic_nic_add_mac(adapter, adapter->mac_addr, &del_list); - qlcnic_nic_add_mac(adapter, bcast_addr, &del_list); + qlcnic_nic_add_mac(adapter, adapter->mac_addr); + qlcnic_nic_add_mac(adapter, bcast_addr); if (netdev->flags & IFF_PROMISC) { mode = VPORT_MISS_MODE_ACCEPT_ALL; @@ -455,22 +446,12 @@ void qlcnic_set_multi(struct net_device *netdev) if (!netdev_mc_empty(netdev)) { netdev_for_each_mc_addr(mc_ptr, netdev) { - qlcnic_nic_add_mac(adapter, mc_ptr->dmi_addr, - &del_list); + qlcnic_nic_add_mac(adapter, mc_ptr->dmi_addr); } } send_fw_cmd: qlcnic_nic_set_promisc(adapter, mode); - head = &del_list; - while (!list_empty(head)) { - cur = list_entry(head->next, struct qlcnic_mac_list_s, list); - - qlcnic_sre_macaddr_change(adapter, - cur->mac_addr, QLCNIC_MAC_DEL); - list_del(&cur->list); - kfree(cur); - } } int qlcnic_nic_set_promisc(struct qlcnic_adapter *adapter, u32 mode) -- cgit v1.2.2 From b7eff1007fea3d153a9a5c0f872304ec19412bbb Mon Sep 17 00:00:00 2001 From: Sucheta Chakraborty Date: Mon, 8 Mar 2010 00:14:48 +0000 Subject: qlcnic: validate unified fw image Validate all sections of unified fw image, before accessing them, to avoid seg fault. Signed-off-by: Sucheta Chakraborty Signed-off-by: Amit Kumar Salecha Signed-off-by: David S. Miller --- drivers/net/qlcnic/qlcnic_init.c | 146 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 139 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/net/qlcnic/qlcnic_init.c b/drivers/net/qlcnic/qlcnic_init.c index f0df9717aece..21a6e9f3dac5 100644 --- a/drivers/net/qlcnic/qlcnic_init.c +++ b/drivers/net/qlcnic/qlcnic_init.c @@ -568,21 +568,123 @@ struct uni_table_desc *qlcnic_get_table_desc(const u8 *unirom, int section) return NULL; } +#define FILEHEADER_SIZE (14 * 4) + static int -qlcnic_set_product_offs(struct qlcnic_adapter *adapter) +qlcnic_validate_header(struct qlcnic_adapter *adapter) { - struct uni_table_desc *ptab_descr; const u8 *unirom = adapter->fw->data; - u32 i; + struct uni_table_desc *directory = (struct uni_table_desc *) &unirom[0]; + __le32 fw_file_size = adapter->fw->size; __le32 entries; + __le32 entry_size; + __le32 tab_size; + + if (fw_file_size < FILEHEADER_SIZE) + return -EINVAL; + + entries = cpu_to_le32(directory->num_entries); + entry_size = cpu_to_le32(directory->entry_size); + tab_size = cpu_to_le32(directory->findex) + (entries * entry_size); + + if (fw_file_size < tab_size) + return -EINVAL; + + return 0; +} + +static int +qlcnic_validate_bootld(struct qlcnic_adapter *adapter) +{ + struct uni_table_desc *tab_desc; + struct uni_data_desc *descr; + const u8 *unirom = adapter->fw->data; + int idx = cpu_to_le32(*((int *)&unirom[adapter->file_prd_off] + + QLCNIC_UNI_BOOTLD_IDX_OFF)); + __le32 offs; + __le32 tab_size; + __le32 data_size; + + tab_desc = qlcnic_get_table_desc(unirom, QLCNIC_UNI_DIR_SECT_BOOTLD); + + if (!tab_desc) + return -EINVAL; + + tab_size = cpu_to_le32(tab_desc->findex) + + (cpu_to_le32(tab_desc->entry_size * (idx + 1))); + + if (adapter->fw->size < tab_size) + return -EINVAL; + + offs = cpu_to_le32(tab_desc->findex) + + (cpu_to_le32(tab_desc->entry_size) * (idx)); + descr = (struct uni_data_desc *)&unirom[offs]; + + data_size = descr->findex + cpu_to_le32(descr->size); + + if (adapter->fw->size < data_size) + return -EINVAL; + + return 0; +} + +static int +qlcnic_validate_fw(struct qlcnic_adapter *adapter) +{ + struct uni_table_desc *tab_desc; + struct uni_data_desc *descr; + const u8 *unirom = adapter->fw->data; + int idx = cpu_to_le32(*((int *)&unirom[adapter->file_prd_off] + + QLCNIC_UNI_FIRMWARE_IDX_OFF)); + __le32 offs; + __le32 tab_size; + __le32 data_size; + + tab_desc = qlcnic_get_table_desc(unirom, QLCNIC_UNI_DIR_SECT_FW); + + if (!tab_desc) + return -EINVAL; + + tab_size = cpu_to_le32(tab_desc->findex) + + (cpu_to_le32(tab_desc->entry_size * (idx + 1))); + + if (adapter->fw->size < tab_size) + return -EINVAL; + + offs = cpu_to_le32(tab_desc->findex) + + (cpu_to_le32(tab_desc->entry_size) * (idx)); + descr = (struct uni_data_desc *)&unirom[offs]; + data_size = descr->findex + cpu_to_le32(descr->size); + + if (adapter->fw->size < data_size) + return -EINVAL; + + return 0; +} + +static int +qlcnic_validate_product_offs(struct qlcnic_adapter *adapter) +{ + struct uni_table_desc *ptab_descr; + const u8 *unirom = adapter->fw->data; int mn_present = qlcnic_has_mn(adapter); + __le32 entries; + __le32 entry_size; + __le32 tab_size; + u32 i; ptab_descr = qlcnic_get_table_desc(unirom, QLCNIC_UNI_DIR_SECT_PRODUCT_TBL); - if (ptab_descr == NULL) - return -1; + if (!ptab_descr) + return -EINVAL; entries = cpu_to_le32(ptab_descr->num_entries); + entry_size = cpu_to_le32(ptab_descr->entry_size); + tab_size = cpu_to_le32(ptab_descr->findex) + (entries * entry_size); + + if (adapter->fw->size < tab_size) + return -EINVAL; + nomn: for (i = 0; i < entries; i++) { @@ -609,7 +711,37 @@ nomn: mn_present = 0; goto nomn; } - return -1; + return -EINVAL; +} + +static int +qlcnic_validate_unified_romimage(struct qlcnic_adapter *adapter) +{ + if (qlcnic_validate_header(adapter)) { + dev_err(&adapter->pdev->dev, + "unified image: header validation failed\n"); + return -EINVAL; + } + + if (qlcnic_validate_product_offs(adapter)) { + dev_err(&adapter->pdev->dev, + "unified image: product validation failed\n"); + return -EINVAL; + } + + if (qlcnic_validate_bootld(adapter)) { + dev_err(&adapter->pdev->dev, + "unified image: bootld validation failed\n"); + return -EINVAL; + } + + if (qlcnic_validate_fw(adapter)) { + dev_err(&adapter->pdev->dev, + "unified image: firmware validation failed\n"); + return -EINVAL; + } + + return 0; } static @@ -858,7 +990,7 @@ qlcnic_validate_firmware(struct qlcnic_adapter *adapter) u8 fw_type = adapter->fw_type; if (fw_type == QLCNIC_UNIFIED_ROMIMAGE) { - if (qlcnic_set_product_offs(adapter)) + if (qlcnic_validate_unified_romimage(adapter)) return -EINVAL; min_size = QLCNIC_UNI_FW_MIN_SIZE; -- cgit v1.2.2 From addd5abf49be31787aeb6203d266e0bd31a3fadd Mon Sep 17 00:00:00 2001 From: Amit Kumar Salecha Date: Mon, 8 Mar 2010 00:14:49 +0000 Subject: qlcnic: fix bios version check Bios sub version from unified fw image is calculated incorrect. Signed-off-by: Amit Kumar Salecha Signed-off-by: David S. Miller --- drivers/net/qlcnic/qlcnic_init.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/qlcnic/qlcnic_init.c b/drivers/net/qlcnic/qlcnic_init.c index 21a6e9f3dac5..7c34e4e29b3f 100644 --- a/drivers/net/qlcnic/qlcnic_init.c +++ b/drivers/net/qlcnic/qlcnic_init.c @@ -847,7 +847,7 @@ qlcnic_get_bios_version(struct qlcnic_adapter *adapter) bios_ver = cpu_to_le32(*((u32 *) (&fw->data[prd_off]) + QLCNIC_UNI_BIOS_VERSION_OFF)); - return (bios_ver << 24) + ((bios_ver >> 8) & 0xff00) + (bios_ver >> 24); + return (bios_ver << 16) + ((bios_ver >> 8) & 0xff00) + (bios_ver >> 24); } int -- cgit v1.2.2 From 1515faf2f995add976d4428bbc1583a4a0c81e5f Mon Sep 17 00:00:00 2001 From: Amit Kumar Salecha Date: Mon, 8 Mar 2010 00:14:50 +0000 Subject: qlcnic: remove extra space from board names Signed-off-by: Amit Kumar Salecha Signed-off-by: David S. Miller --- drivers/net/qlcnic/qlcnic.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/net/qlcnic/qlcnic.h b/drivers/net/qlcnic/qlcnic.h index 9897b699752f..0da94b208db1 100644 --- a/drivers/net/qlcnic/qlcnic.h +++ b/drivers/net/qlcnic/qlcnic.h @@ -1100,11 +1100,11 @@ struct qlcnic_brdinfo { static const struct qlcnic_brdinfo qlcnic_boards[] = { {0x1077, 0x8020, 0x1077, 0x203, - "8200 Series Single Port 10GbE Converged Network Adapter \ - (TCP/IP Networking)"}, + "8200 Series Single Port 10GbE Converged Network Adapter " + "(TCP/IP Networking)"}, {0x1077, 0x8020, 0x1077, 0x207, - "8200 Series Dual Port 10GbE Converged Network Adapter \ - (TCP/IP Networking)"}, + "8200 Series Dual Port 10GbE Converged Network Adapter " + "(TCP/IP Networking)"}, {0x1077, 0x8020, 0x1077, 0x20b, "3200 Series Dual Port 10Gb Intelligent Ethernet Adapter"}, {0x1077, 0x8020, 0x1077, 0x20c, -- cgit v1.2.2 From e9dcd1613f0ac0b3573b7d813a2c5672cd8302eb Mon Sep 17 00:00:00 2001 From: Barry Song Date: Mon, 8 Mar 2010 12:13:57 -0800 Subject: can: fix bfin_can build error after alloc_candev() change Looks like commit a6e4bc530403 didn't include updates to drivers so the Blackfin CAN driver fails to build now. Signed-off-by: Barry Song Signed-off-by: Mike Frysinger Acked-by: Wolfgang Grandegger Signed-off-by: David S. Miller --- drivers/net/can/bfin_can.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/can/bfin_can.c b/drivers/net/can/bfin_can.c index bf7f9ba2d903..866905fa4119 100644 --- a/drivers/net/can/bfin_can.c +++ b/drivers/net/can/bfin_can.c @@ -26,6 +26,7 @@ #define DRV_NAME "bfin_can" #define BFIN_CAN_TIMEOUT 100 +#define TX_ECHO_SKB_MAX 1 /* * transmit and receive channels @@ -593,7 +594,7 @@ struct net_device *alloc_bfin_candev(void) struct net_device *dev; struct bfin_can_priv *priv; - dev = alloc_candev(sizeof(*priv)); + dev = alloc_candev(sizeof(*priv), TX_ECHO_SKB_MAX); if (!dev) return NULL; -- cgit v1.2.2 From 1d79e53c56afe0826a311c3bc1653ad938166c22 Mon Sep 17 00:00:00 2001 From: Reinette Chatre Date: Fri, 26 Feb 2010 11:01:36 -0800 Subject: iwl3945: fix memory corruption Recent patch "iwlwifi: move 3945 clip groups to 3945 data" exposed a memory corruption problem. When initializing the clip groups the code was mistakenly using the iwlagn rate count, not the 3945 rate count. This resulted in more memory being written than was allocated. "iwlwifi: move 3945 clip groups to 3945 data" moved the location where the clip groups are stored and the impact is now severe in that the number of configured TX queues is modified. Previously the "temperature" field was overwritten, which did not seem to affect the operation. Fix this one instance where wrong rate count was used. I also noticed one more location where the iwlagn rate count was used to index an iwl3945 array, fix this. I also modified one location that modified the iwlagn rate count to obtain the iwl3945 rate count ... just use the iwl3945 rate count directly. This fixes http://bugzilla.intellinuxwireless.org/show_bug.cgi?id=2165 and http://bugzilla.intellinuxwireless.org/show_bug.cgi?id=2168 Signed-off-by: Reinette Chatre --- drivers/net/wireless/iwlwifi/iwl-3945.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c index 303cc8193adc..e0678d921055 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945.c +++ b/drivers/net/wireless/iwlwifi/iwl-3945.c @@ -184,7 +184,7 @@ static int iwl3945_hwrate_to_plcp_idx(u8 plcp) { int idx; - for (idx = 0; idx < IWL_RATE_COUNT; idx++) + for (idx = 0; idx < IWL_RATE_COUNT_3945; idx++) if (iwl3945_rates[idx].plcp == plcp) return idx; return -1; @@ -805,7 +805,7 @@ void iwl3945_hw_build_tx_cmd_rate(struct iwl_priv *priv, int sta_id, int tx_id) { u16 hw_value = ieee80211_get_tx_rate(priv->hw, info)->hw_value; - u16 rate_index = min(hw_value & 0xffff, IWL_RATE_COUNT - 1); + u16 rate_index = min(hw_value & 0xffff, IWL_RATE_COUNT_3945); u16 rate_mask; int rate; u8 rts_retry_limit; @@ -2146,7 +2146,7 @@ static void iwl3945_hw_reg_init_channel_groups(struct iwl_priv *priv) /* fill in channel group's nominal powers for each rate */ for (rate_index = 0; - rate_index < IWL_RATE_COUNT; rate_index++, clip_pwrs++) { + rate_index < IWL_RATE_COUNT_3945; rate_index++, clip_pwrs++) { switch (rate_index) { case IWL_RATE_36M_INDEX_TABLE: if (i == 0) /* B/G */ -- cgit v1.2.2 From 1382c71c764540880d35485b033a44ce104d8e2e Mon Sep 17 00:00:00 2001 From: Reinette Chatre Date: Thu, 25 Feb 2010 10:02:19 -0800 Subject: Revert "iwlwifi: Send broadcast probe request only when asked to" This reverts commit 21b2d8bd2f0d4e0f21ade147fd193c8b9c1fd2b9. As explained by Johannes: When we build a probe request frame in the buffer with the SSID, we could arrive over the limit of 200 bytes. When we build it in the buffer without the SSID (wildcard) we don't arrive over 200 bytes, but the ucode still allows direct probe in addition because it has an internal buffer that is larger when it inserts the SSID... Signed-off-by: Reinette Chatre --- drivers/net/wireless/iwlwifi/iwl-agn.c | 2 +- drivers/net/wireless/iwlwifi/iwl-scan.c | 49 +++++++++++---------------------- 2 files changed, 17 insertions(+), 34 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 47b021477967..818367b57bab 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -2653,7 +2653,7 @@ static int iwl_mac_setup_register(struct iwl_priv *priv) */ hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT; - hw->wiphy->max_scan_ssids = PROBE_OPTION_MAX + 1; + hw->wiphy->max_scan_ssids = PROBE_OPTION_MAX; /* we create the 802.11 header and a zero-length SSID element */ hw->wiphy->max_scan_ie_len = IWL_MAX_PROBE_REQUEST - 24 - 2; diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c index dd9ff2ed645a..bd2f7c420563 100644 --- a/drivers/net/wireless/iwlwifi/iwl-scan.c +++ b/drivers/net/wireless/iwlwifi/iwl-scan.c @@ -638,20 +638,9 @@ u16 iwl_fill_probe_req(struct iwl_priv *priv, struct ieee80211_mgmt *frame, if (left < 0) return 0; *pos++ = WLAN_EID_SSID; - if (!priv->is_internal_short_scan && - priv->scan_request->n_ssids) { - struct cfg80211_ssid *ssid = - priv->scan_request->ssids; - - /* Broadcast if ssid_len is 0 */ - *pos++ = ssid->ssid_len; - memcpy(pos, ssid->ssid, ssid->ssid_len); - pos += ssid->ssid_len; - len += 2 + ssid->ssid_len; - } else { - *pos++ = 0; - len += 2; - } + *pos++ = 0; + + len += 2; if (WARN_ON(left < ie_len)) return len; @@ -780,26 +769,20 @@ static void iwl_bg_request_scan(struct work_struct *data) if (priv->is_internal_short_scan) { IWL_DEBUG_SCAN(priv, "Start internal passive scan.\n"); } else if (priv->scan_request->n_ssids) { + int i, p = 0; IWL_DEBUG_SCAN(priv, "Kicking off active scan\n"); - /* - * The first SSID to scan is stuffed into the probe request - * template and the remaining ones are handled through the - * direct_scan array. - */ - if (priv->scan_request->n_ssids > 1) { - int i, p = 0; - for (i = 1; i < priv->scan_request->n_ssids; i++) { - if (!priv->scan_request->ssids[i].ssid_len) - continue; - scan->direct_scan[p].id = WLAN_EID_SSID; - scan->direct_scan[p].len = - priv->scan_request->ssids[i].ssid_len; - memcpy(scan->direct_scan[p].ssid, - priv->scan_request->ssids[i].ssid, - priv->scan_request->ssids[i].ssid_len); - n_probes++; - p++; - } + for (i = 0; i < priv->scan_request->n_ssids; i++) { + /* always does wildcard anyway */ + if (!priv->scan_request->ssids[i].ssid_len) + continue; + scan->direct_scan[p].id = WLAN_EID_SSID; + scan->direct_scan[p].len = + priv->scan_request->ssids[i].ssid_len; + memcpy(scan->direct_scan[p].ssid, + priv->scan_request->ssids[i].ssid, + priv->scan_request->ssids[i].ssid_len); + n_probes++; + p++; } is_active = true; } else -- cgit v1.2.2 From e5a9a35cb9c0d92d7c986cb3696fb794be100087 Mon Sep 17 00:00:00 2001 From: Helmut Schaa Date: Fri, 5 Mar 2010 17:44:22 +0100 Subject: rt2x00: remove KSEG1ADDR define from rt2x00soc.h Remove the KSEG1ADDR define from rt2x00soc.h as it redefines and covers the correct one from the arch/mips/include/asm/addrspace.h. Otherwise the driver oopses on the target platform (Ralink rt3050 board). Signed-off-by: Helmut Schaa Acked-by: Ivo van Doorn Acked-by: Gertjan van Wingerde Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2x00soc.h | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/rt2x00/rt2x00soc.h b/drivers/net/wireless/rt2x00/rt2x00soc.h index 4739edfe2f00..474cbfc1efc7 100644 --- a/drivers/net/wireless/rt2x00/rt2x00soc.h +++ b/drivers/net/wireless/rt2x00/rt2x00soc.h @@ -26,8 +26,6 @@ #ifndef RT2X00SOC_H #define RT2X00SOC_H -#define KSEG1ADDR(__ptr) __ptr - /* * SoC driver handlers. */ -- cgit v1.2.2 From 8e59340e4fb65cfd748eaa1e23db057c52520f35 Mon Sep 17 00:00:00 2001 From: Zhu Yi Date: Mon, 8 Mar 2010 13:18:03 +0800 Subject: libipw: split ieee->networks into small pieces The ieee->networks consists of 128 struct libipw_network entries. If we allocate this chunk of memory altogether, it ends up with an order 4 page allocation. High order page allocation is likely to fail on system high load. This patch splits the big chunk memory allocation into small pieces, each is 344 bytes, allocates them with 128 times. The patch fixed bug http://bugzilla.kernel.org/show_bug.cgi?id=14989 Signed-off-by: Zhu Yi Signed-off-by: John W. Linville --- drivers/net/wireless/ipw2x00/libipw.h | 2 +- drivers/net/wireless/ipw2x00/libipw_module.c | 37 +++++++++++++--------------- 2 files changed, 18 insertions(+), 21 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ipw2x00/libipw.h b/drivers/net/wireless/ipw2x00/libipw.h index bf45391172f3..a6d5e42647e4 100644 --- a/drivers/net/wireless/ipw2x00/libipw.h +++ b/drivers/net/wireless/ipw2x00/libipw.h @@ -797,7 +797,7 @@ struct libipw_device { /* Probe / Beacon management */ struct list_head network_free_list; struct list_head network_list; - struct libipw_network *networks; + struct libipw_network *networks[MAX_NETWORK_COUNT]; int scans; int scan_age; diff --git a/drivers/net/wireless/ipw2x00/libipw_module.c b/drivers/net/wireless/ipw2x00/libipw_module.c index 1ae0b2b02c38..2fa55867bd8b 100644 --- a/drivers/net/wireless/ipw2x00/libipw_module.c +++ b/drivers/net/wireless/ipw2x00/libipw_module.c @@ -67,16 +67,17 @@ void *libipw_wiphy_privid = &libipw_wiphy_privid; static int libipw_networks_allocate(struct libipw_device *ieee) { - if (ieee->networks) - return 0; - - ieee->networks = - kzalloc(MAX_NETWORK_COUNT * sizeof(struct libipw_network), - GFP_KERNEL); - if (!ieee->networks) { - printk(KERN_WARNING "%s: Out of memory allocating beacons\n", - ieee->dev->name); - return -ENOMEM; + int i, j; + + for (i = 0; i < MAX_NETWORK_COUNT; i++) { + ieee->networks[i] = kzalloc(sizeof(struct libipw_network), + GFP_KERNEL); + if (!ieee->networks[i]) { + LIBIPW_ERROR("Out of memory allocating beacons\n"); + for (j = 0; j < i; j++) + kfree(ieee->networks[j]); + return -ENOMEM; + } } return 0; @@ -97,15 +98,11 @@ static inline void libipw_networks_free(struct libipw_device *ieee) { int i; - if (!ieee->networks) - return; - - for (i = 0; i < MAX_NETWORK_COUNT; i++) - if (ieee->networks[i].ibss_dfs) - kfree(ieee->networks[i].ibss_dfs); - - kfree(ieee->networks); - ieee->networks = NULL; + for (i = 0; i < MAX_NETWORK_COUNT; i++) { + if (ieee->networks[i]->ibss_dfs) + kfree(ieee->networks[i]->ibss_dfs); + kfree(ieee->networks[i]); + } } void libipw_networks_age(struct libipw_device *ieee, @@ -130,7 +127,7 @@ static void libipw_networks_initialize(struct libipw_device *ieee) INIT_LIST_HEAD(&ieee->network_free_list); INIT_LIST_HEAD(&ieee->network_list); for (i = 0; i < MAX_NETWORK_COUNT; i++) - list_add_tail(&ieee->networks[i].list, + list_add_tail(&ieee->networks[i]->list, &ieee->network_free_list); } -- cgit v1.2.2 From 8bd8beab49fec3f7d014c328641bd94de3df744b Mon Sep 17 00:00:00 2001 From: Bruno Randolf Date: Tue, 9 Mar 2010 16:55:23 +0900 Subject: ath5k: use fixed antenna for tx descriptors when using a fixed antenna we should use the antenna number in all tx descriptors, otherwise the hardware will sometimes send the frame out on the other antenna. it seems like the hardware does not always respect the default antenna and diversity settings (esp. AR5K_STA_ID1_DEFAULT_ANTENNA). also i would like to note that antenna diversity does not always work correctly on 5414 (at least) when only one antenna is connected: for example all frames might be received on antenna A but still the HW tries to send on antenna B some times, causing packet loss. this is both verified with the antenna statistics output of the previous patch and a spectrum analyzer. Signed-off-by: Bruno Randolf Acked-by: Nick Kossifidis Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/phy.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath5k/phy.c b/drivers/net/wireless/ath/ath5k/phy.c index 72474c0ccaff..ffe253ab9be7 100644 --- a/drivers/net/wireless/ath/ath5k/phy.c +++ b/drivers/net/wireless/ath/ath5k/phy.c @@ -1873,7 +1873,7 @@ ath5k_hw_set_antenna_mode(struct ath5k_hw *ah, u8 ant_mode) break; case AR5K_ANTMODE_FIXED_A: def_ant = 1; - tx_ant = 0; + tx_ant = 1; use_def_for_tx = true; update_def_on_tx = false; use_def_for_rts = true; @@ -1882,7 +1882,7 @@ ath5k_hw_set_antenna_mode(struct ath5k_hw *ah, u8 ant_mode) break; case AR5K_ANTMODE_FIXED_B: def_ant = 2; - tx_ant = 0; + tx_ant = 2; use_def_for_tx = true; update_def_on_tx = false; use_def_for_rts = true; -- cgit v1.2.2 From a3b980fd1391e75068ae25f3817728b27bfdb04c Mon Sep 17 00:00:00 2001 From: Bruno Randolf Date: Tue, 9 Mar 2010 16:55:33 +0900 Subject: ath5k: fix TSF reset to reset the TSF, AR5K_BEACON_RESET_TSF has to be 1, not 0. also we have a function for that so use it. Signed-off-by: Bruno Randolf Acked-by: Nick Kossifidis Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/reset.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath5k/reset.c b/drivers/net/wireless/ath/ath5k/reset.c index a35a7db0fc4c..c780b55020d2 100644 --- a/drivers/net/wireless/ath/ath5k/reset.c +++ b/drivers/net/wireless/ath/ath5k/reset.c @@ -1379,11 +1379,10 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode, ath5k_hw_set_sleep_clock(ah, true); /* - * Disable beacons and reset the register + * Disable beacons and reset the TSF */ - AR5K_REG_DISABLE_BITS(ah, AR5K_BEACON, AR5K_BEACON_ENABLE | - AR5K_BEACON_RESET_TSF); - + AR5K_REG_DISABLE_BITS(ah, AR5K_BEACON, AR5K_BEACON_ENABLE); + ath5k_hw_reset_tsf(ah); return 0; } -- cgit v1.2.2 From 86415d43efd4f7093979cfa8a80232114266f1a4 Mon Sep 17 00:00:00 2001 From: Bruno Randolf Date: Tue, 9 Mar 2010 16:56:05 +0900 Subject: ath5k: fix I/Q calibration (for real) I/Q calibration was completely broken, resulting in a high number of CRC errors on received packets. before i could see around 10% to 20% CRC errors, with this patch they are between 0% and 3%. 1.) the removal of the mask in commit "ath5k: Fix I/Q calibration (f1cf2dbd0f798b71b1590e7aca6647f2caef1649)" resulted in no mask beeing used when writing the I/Q values into the register. additional errors in the calculation of the values (see 2.) resulted too high numbers, exceeding the masks, so wrong values like 0xfffffffe were written. to be safe we should always use the bitmask when writing parts of a register. 2.) using a (s32) cast for q_coff is a wrong conversion to signed, since we convert to a signed value later by substracting 128. this resulted in too low numbers for Q many times, which were limited to -16 by the boundary check later on. 3.) checked everything against the HAL sources and took over comments and minor optimizations from there. 4.) we can't use ENABLE_BITS when we want to write a number (the number can contain zeros). also always write the correction values first and set ENABLE bit last, like the HAL does. Signed-off-by: Bruno Randolf Cc: stable@kernel.org Acked-by: Nick Kossifidis Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/phy.c | 37 ++++++++++++++++++------------------ drivers/net/wireless/ath/ath5k/reg.h | 1 + 2 files changed, 20 insertions(+), 18 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath5k/phy.c b/drivers/net/wireless/ath/ath5k/phy.c index ffe253ab9be7..eff3323efb4b 100644 --- a/drivers/net/wireless/ath/ath5k/phy.c +++ b/drivers/net/wireless/ath/ath5k/phy.c @@ -1386,38 +1386,39 @@ static int ath5k_hw_rf511x_calibrate(struct ath5k_hw *ah, goto done; /* Calibration has finished, get the results and re-run */ + + /* work around empty results which can apparently happen on 5212 */ for (i = 0; i <= 10; i++) { iq_corr = ath5k_hw_reg_read(ah, AR5K_PHY_IQRES_CAL_CORR); i_pwr = ath5k_hw_reg_read(ah, AR5K_PHY_IQRES_CAL_PWR_I); q_pwr = ath5k_hw_reg_read(ah, AR5K_PHY_IQRES_CAL_PWR_Q); + ATH5K_DBG_UNLIMIT(ah->ah_sc, ATH5K_DEBUG_CALIBRATE, + "iq_corr:%x i_pwr:%x q_pwr:%x", iq_corr, i_pwr, q_pwr); + if (i_pwr && q_pwr) + break; } i_coffd = ((i_pwr >> 1) + (q_pwr >> 1)) >> 7; q_coffd = q_pwr >> 7; - /* No correction */ - if (i_coffd == 0 || q_coffd == 0) + /* protect against divide by 0 and loss of sign bits */ + if (i_coffd == 0 || q_coffd < 2) goto done; - i_coff = ((-iq_corr) / i_coffd); + i_coff = (-iq_corr) / i_coffd; + i_coff = clamp(i_coff, -32, 31); /* signed 6 bit */ - /* Boundary check */ - if (i_coff > 31) - i_coff = 31; - if (i_coff < -32) - i_coff = -32; + q_coff = (i_pwr / q_coffd) - 128; + q_coff = clamp(q_coff, -16, 15); /* signed 5 bit */ - q_coff = (((s32)i_pwr / q_coffd) - 128); + ATH5K_DBG_UNLIMIT(ah->ah_sc, ATH5K_DEBUG_CALIBRATE, + "new I:%d Q:%d (i_coffd:%x q_coffd:%x)", + i_coff, q_coff, i_coffd, q_coffd); - /* Boundary check */ - if (q_coff > 15) - q_coff = 15; - if (q_coff < -16) - q_coff = -16; - - /* Commit new I/Q value */ - AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_IQ, AR5K_PHY_IQ_CORR_ENABLE | - ((u32)q_coff) | ((u32)i_coff << AR5K_PHY_IQ_CORR_Q_I_COFF_S)); + /* Commit new I/Q values (set enable bit last to match HAL sources) */ + AR5K_REG_WRITE_BITS(ah, AR5K_PHY_IQ, AR5K_PHY_IQ_CORR_Q_I_COFF, i_coff); + AR5K_REG_WRITE_BITS(ah, AR5K_PHY_IQ, AR5K_PHY_IQ_CORR_Q_Q_COFF, q_coff); + AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_IQ, AR5K_PHY_IQ_CORR_ENABLE); /* Re-enable calibration -if we don't we'll commit * the same values again and again */ diff --git a/drivers/net/wireless/ath/ath5k/reg.h b/drivers/net/wireless/ath/ath5k/reg.h index 4cb9c5df9f46..1464f89b249c 100644 --- a/drivers/net/wireless/ath/ath5k/reg.h +++ b/drivers/net/wireless/ath/ath5k/reg.h @@ -2187,6 +2187,7 @@ */ #define AR5K_PHY_IQ 0x9920 /* Register Address */ #define AR5K_PHY_IQ_CORR_Q_Q_COFF 0x0000001f /* Mask for q correction info */ +#define AR5K_PHY_IQ_CORR_Q_Q_COFF_S 0 #define AR5K_PHY_IQ_CORR_Q_I_COFF 0x000007e0 /* Mask for i correction info */ #define AR5K_PHY_IQ_CORR_Q_I_COFF_S 5 #define AR5K_PHY_IQ_CORR_ENABLE 0x00000800 /* Enable i/q correction */ -- cgit v1.2.2 From 5f13bfac0718ce6f83ecba3755f224c3790e8d66 Mon Sep 17 00:00:00 2001 From: Bruno Randolf Date: Tue, 9 Mar 2010 16:56:10 +0900 Subject: ath5k: read eeprom IQ calibration values correctly for G mode we read the IQ correction values (i_cal and q_cal) for G mode from a wrong location (the same shifts as for A mode is applied which is incorrect). use correct locations, matching the docs and HAL sources. also we should write IQ correction only when we have that information in the EEPROM, starting from version 4. also write it in the same way as we do in the periodic recalibration (enable last), just to be sure. Signed-off-by: Bruno Randolf Acked-by: Nick Kossifidis Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/eeprom.c | 4 ++-- drivers/net/wireless/ath/ath5k/reset.c | 15 +++++++++------ 2 files changed, 11 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath5k/eeprom.c b/drivers/net/wireless/ath/ath5k/eeprom.c index 6a3f4da7fb48..10b52262b232 100644 --- a/drivers/net/wireless/ath/ath5k/eeprom.c +++ b/drivers/net/wireless/ath/ath5k/eeprom.c @@ -429,8 +429,8 @@ static int ath5k_eeprom_read_modes(struct ath5k_hw *ah, u32 *offset, ee->ee_margin_tx_rx[mode] = (val >> 8) & 0x3f; AR5K_EEPROM_READ(o++, val); - ee->ee_i_cal[mode] = (val >> 8) & 0x3f; - ee->ee_q_cal[mode] = (val >> 3) & 0x1f; + ee->ee_i_cal[mode] = (val >> 5) & 0x3f; + ee->ee_q_cal[mode] = val & 0x1f; if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_2) { AR5K_EEPROM_READ(o++, val); diff --git a/drivers/net/wireless/ath/ath5k/reset.c b/drivers/net/wireless/ath/ath5k/reset.c index c780b55020d2..cbf28e379843 100644 --- a/drivers/net/wireless/ath/ath5k/reset.c +++ b/drivers/net/wireless/ath/ath5k/reset.c @@ -851,12 +851,15 @@ static void ath5k_hw_commit_eeprom_settings(struct ath5k_hw *ah, AR5K_PHY_OFDM_SELFCORR_CYPWR_THR1, AR5K_INIT_CYCRSSI_THR1); - /* I/Q correction - * TODO: Per channel i/q infos ? */ - AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_IQ, - AR5K_PHY_IQ_CORR_ENABLE | - (ee->ee_i_cal[ee_mode] << AR5K_PHY_IQ_CORR_Q_I_COFF_S) | - ee->ee_q_cal[ee_mode]); + /* I/Q correction (set enable bit last to match HAL sources) */ + /* TODO: Per channel i/q infos ? */ + if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_0) { + AR5K_REG_WRITE_BITS(ah, AR5K_PHY_IQ, AR5K_PHY_IQ_CORR_Q_I_COFF, + ee->ee_i_cal[ee_mode]); + AR5K_REG_WRITE_BITS(ah, AR5K_PHY_IQ, AR5K_PHY_IQ_CORR_Q_Q_COFF, + ee->ee_q_cal[ee_mode]); + AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_IQ, AR5K_PHY_IQ_CORR_ENABLE); + } /* Heavy clipping -disable for now */ if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_5_1) -- cgit v1.2.2 From 41093167ec6c1854903a4bc38a37b5740c028984 Mon Sep 17 00:00:00 2001 From: Zhu Yi Date: Tue, 9 Mar 2010 16:05:31 +0800 Subject: ipw2200: use kmalloc for large local variables MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixed below compiler warning: drivers/net/wireless/ipw2x00/ipw2200.c: In function ‘ipw_load_firmware’: drivers/net/wireless/ipw2x00/ipw2200.c:3260: warning: the frame size of 1168 bytes is larger than 1024 bytes Signed-off-by: Zhu Yi Signed-off-by: John W. Linville --- drivers/net/wireless/ipw2x00/ipw2200.c | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ipw2x00/ipw2200.c b/drivers/net/wireless/ipw2x00/ipw2200.c index 63c2a7ade5fb..5c7aa1b1eb56 100644 --- a/drivers/net/wireless/ipw2x00/ipw2200.c +++ b/drivers/net/wireless/ipw2x00/ipw2200.c @@ -3177,14 +3177,27 @@ static int ipw_load_firmware(struct ipw_priv *priv, u8 * data, size_t len) int total_nr = 0; int i; struct pci_pool *pool; - u32 *virts[CB_NUMBER_OF_ELEMENTS_SMALL]; - dma_addr_t phys[CB_NUMBER_OF_ELEMENTS_SMALL]; + void **virts; + dma_addr_t *phys; IPW_DEBUG_TRACE("<< : \n"); + virts = kmalloc(sizeof(void *) * CB_NUMBER_OF_ELEMENTS_SMALL, + GFP_KERNEL); + if (!virts) + return -ENOMEM; + + phys = kmalloc(sizeof(dma_addr_t) * CB_NUMBER_OF_ELEMENTS_SMALL, + GFP_KERNEL); + if (!phys) { + kfree(virts); + return -ENOMEM; + } pool = pci_pool_create("ipw2200", priv->pci_dev, CB_MAX_LENGTH, 0, 0); if (!pool) { IPW_ERROR("pci_pool_create failed\n"); + kfree(phys); + kfree(virts); return -ENOMEM; } @@ -3254,6 +3267,8 @@ static int ipw_load_firmware(struct ipw_priv *priv, u8 * data, size_t len) pci_pool_free(pool, virts[i], phys[i]); pci_pool_destroy(pool); + kfree(phys); + kfree(virts); return ret; } -- cgit v1.2.2 From 3f60ebc9d6291863652d564bacc430629271e6a9 Mon Sep 17 00:00:00 2001 From: Grazvydas Ignotas Date: Thu, 11 Mar 2010 17:45:26 +0200 Subject: wl1251: fix potential crash In case debugfs does not init for some reason (or is disabled on older kernels) driver does not allocate stats.fw_stats structure, but tries to clear it later and trips on a NULL pointer: Unable to handle kernel NULL pointer dereference at virtual address 00000000 PC is at __memzero+0x24/0x80 Backtrace: [] (wl1251_debugfs_reset+0x0/0x30 [wl1251]) [] (wl1251_op_stop+0x0/0x12c [wl1251]) [] (ieee80211_stop_device+0x0/0x74 [mac80211]) [] (ieee80211_stop+0x0/0x4ac [mac80211]) [] (dev_close+0x0/0xb4) [] (dev_change_flags+0x0/0x184) [] (devinet_ioctl+0x0/0x704) [] (inet_ioctl+0x0/0x100) Add a NULL pointer check to fix this. Signed-off-by: Grazvydas Ignotas Acked-by: Kalle Valo Cc: stable@kernel.org Signed-off-by: John W. Linville --- drivers/net/wireless/wl12xx/wl1251_debugfs.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/wl12xx/wl1251_debugfs.c b/drivers/net/wireless/wl12xx/wl1251_debugfs.c index 0ccba57fb9fb..05e4d68eb4cc 100644 --- a/drivers/net/wireless/wl12xx/wl1251_debugfs.c +++ b/drivers/net/wireless/wl12xx/wl1251_debugfs.c @@ -466,7 +466,8 @@ out: void wl1251_debugfs_reset(struct wl1251 *wl) { - memset(wl->stats.fw_stats, 0, sizeof(*wl->stats.fw_stats)); + if (wl->stats.fw_stats != NULL) + memset(wl->stats.fw_stats, 0, sizeof(*wl->stats.fw_stats)); wl->stats.retry_count = 0; wl->stats.excessive_retries = 0; } -- cgit v1.2.2 From 4fdec031b9169b3c17938b9c4168f099f457169c Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Fri, 12 Mar 2010 04:02:43 +0100 Subject: ath9k: fix BUG_ON triggered by PAE frames When I initially stumbled upon sequence number problems with PAE frames in ath9k, I submitted a patch to remove all special cases for PAE frames and let them go through the normal transmit path. Out of concern about crypto incompatibility issues, this change was merged instead: commit 6c8afef551fef87a3bf24f8a74c69a7f2f72fc82 Author: Sujith Date: Tue Feb 9 10:07:00 2010 +0530 ath9k: Fix sequence numbers for PAE frames After a lot of testing, I'm able to reliably trigger a driver crash on rekeying with current versions with this change in place. It seems that the driver does not support sending out regular MPDUs with the same TID while an A-MPDU session is active. This leads to duplicate entries in the TID Tx buffer, which hits the following BUG_ON in ath_tx_addto_baw(): index = ATH_BA_INDEX(tid->seq_start, bf->bf_seqno); cindex = (tid->baw_head + index) & (ATH_TID_MAX_BUFS - 1); BUG_ON(tid->tx_buf[cindex] != NULL); I believe until we actually have a reproducible case of an incompatibility with another AP using no PAE special cases, we should simply get rid of this mess. This patch completely fixes my crash issues in STA mode and makes it stay connected without throughput drops or connectivity issues even when the AP is configured to a very short group rekey interval. Signed-off-by: Felix Fietkau Cc: stable@kernel.org Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/xmit.c | 21 +-------------------- 1 file changed, 1 insertion(+), 20 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index b2c8207f7bc1..294b486bc3ed 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c @@ -1353,25 +1353,6 @@ static enum ath9k_pkt_type get_hw_packet_type(struct sk_buff *skb) return htype; } -static bool is_pae(struct sk_buff *skb) -{ - struct ieee80211_hdr *hdr; - __le16 fc; - - hdr = (struct ieee80211_hdr *)skb->data; - fc = hdr->frame_control; - - if (ieee80211_is_data(fc)) { - if (ieee80211_is_nullfunc(fc) || - /* Port Access Entity (IEEE 802.1X) */ - (skb->protocol == cpu_to_be16(ETH_P_PAE))) { - return true; - } - } - - return false; -} - static int get_hw_crypto_keytype(struct sk_buff *skb) { struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); @@ -1696,7 +1677,7 @@ static void ath_tx_start_dma(struct ath_softc *sc, struct ath_buf *bf, goto tx_done; } - if ((tx_info->flags & IEEE80211_TX_CTL_AMPDU) && !is_pae(skb)) { + if (tx_info->flags & IEEE80211_TX_CTL_AMPDU) { /* * Try aggregation if it's a unicast data frame * and the destination is HT capable. -- cgit v1.2.2 From c8406ea8fa1adde8dc5400127281d497bbcdb84a Mon Sep 17 00:00:00 2001 From: Adel Gadllah Date: Sun, 14 Mar 2010 19:16:25 +0100 Subject: iwlwifi: Silence tfds_in_queue message Commit a239a8b47cc0e5e6d7416a89f340beac06d5edaa introduced a noisy message, that fills up the log very fast. The error seems not to be fatal (the connection is stable and performance is ok), so make it IWL_DEBUG_TX rather than IWL_ERR. Signed-off-by: Adel Gadllah Cc: stable@kernel.org Acked-by: Reinette Chatre Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-tx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-tx.c b/drivers/net/wireless/iwlwifi/iwl-tx.c index 1ed5206721ec..8c12311dbb0a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-tx.c @@ -124,7 +124,7 @@ void iwl_free_tfds_in_queue(struct iwl_priv *priv, if (priv->stations[sta_id].tid[tid].tfds_in_queue >= freed) priv->stations[sta_id].tid[tid].tfds_in_queue -= freed; else { - IWL_ERR(priv, "free more than tfds_in_queue (%u:%d)\n", + IWL_DEBUG_TX(priv, "free more than tfds_in_queue (%u:%d)\n", priv->stations[sta_id].tid[tid].tfds_in_queue, freed); priv->stations[sta_id].tid[tid].tfds_in_queue = 0; -- cgit v1.2.2 From eb3d72c8b7e6bb6a55e15272c52eb4eadf7fb1f1 Mon Sep 17 00:00:00 2001 From: Ben Konrath Date: Thu, 18 Mar 2010 19:06:57 -0400 Subject: ar9170: add support for NEC WL300NU-G USB dongle This patch adds support for the NEC WL300NU-G USB wifi dongle. Signed-off-by: Ben Konrath Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ar9170/usb.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ar9170/usb.c b/drivers/net/wireless/ath/ar9170/usb.c index 4e30197afff6..c18575070061 100644 --- a/drivers/net/wireless/ath/ar9170/usb.c +++ b/drivers/net/wireless/ath/ar9170/usb.c @@ -94,6 +94,8 @@ static struct usb_device_id ar9170_usb_ids[] = { { USB_DEVICE(0x04bb, 0x093f) }, /* AVM FRITZ!WLAN USB Stick N */ { USB_DEVICE(0x057C, 0x8401) }, + /* NEC WL300NU-G */ + { USB_DEVICE(0x0409, 0x0249) }, /* AVM FRITZ!WLAN USB Stick N 2.4 */ { USB_DEVICE(0x057C, 0x8402), .driver_info = AR9170_REQ_FW1_ONLY }, -- cgit v1.2.2 From e5868ba10c3c5d8a56c06bbafe098103356ac03f Mon Sep 17 00:00:00 2001 From: Benjamin Larsson Date: Fri, 19 Mar 2010 01:46:10 +0100 Subject: Add a pci-id to the mwl8k driver Signed-off-by: Benjamin Larsson Signed-off-by: John W. Linville --- drivers/net/wireless/mwl8k.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/net/wireless/mwl8k.c b/drivers/net/wireless/mwl8k.c index ac65e13eb0de..4e58ebe15580 100644 --- a/drivers/net/wireless/mwl8k.c +++ b/drivers/net/wireless/mwl8k.c @@ -3851,6 +3851,7 @@ MODULE_FIRMWARE("mwl8k/helper_8366.fw"); MODULE_FIRMWARE("mwl8k/fmimage_8366.fw"); static DEFINE_PCI_DEVICE_TABLE(mwl8k_pci_id_table) = { + { PCI_VDEVICE(MARVELL, 0x2a0a), .driver_data = MWL8363, }, { PCI_VDEVICE(MARVELL, 0x2a0c), .driver_data = MWL8363, }, { PCI_VDEVICE(MARVELL, 0x2a24), .driver_data = MWL8363, }, { PCI_VDEVICE(MARVELL, 0x2a2b), .driver_data = MWL8687, }, -- cgit v1.2.2 From 05a9a1617026977422c7c5ed3aeac6f46fa2132c Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Wed, 17 Mar 2010 14:37:16 +0100 Subject: Add USB ID for Thomson SpeedTouch 120g to p54usb id table Thanks to Chris Chabot for giving his old wireless usb dongle to me to test it under Linux. Signed-off-by: Hans de Goede Signed-off-by: John W. Linville --- drivers/net/wireless/p54/p54usb.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/net/wireless/p54/p54usb.c b/drivers/net/wireless/p54/p54usb.c index b3c4fbd80d8d..e3cfc001d2fd 100644 --- a/drivers/net/wireless/p54/p54usb.c +++ b/drivers/net/wireless/p54/p54usb.c @@ -35,6 +35,7 @@ MODULE_FIRMWARE("isl3887usb"); static struct usb_device_id p54u_table[] __devinitdata = { /* Version 1 devices (pci chip + net2280) */ {USB_DEVICE(0x0506, 0x0a11)}, /* 3COM 3CRWE254G72 */ + {USB_DEVICE(0x06b9, 0x0120)}, /* Thomson SpeedTouch 120g */ {USB_DEVICE(0x0707, 0xee06)}, /* SMC 2862W-G */ {USB_DEVICE(0x07aa, 0x001c)}, /* Corega CG-WLUSB2GT */ {USB_DEVICE(0x083a, 0x4501)}, /* Accton 802.11g WN4501 USB */ -- cgit v1.2.2 From f6c8f1523a2de3b84340e45913cbcee8bee74570 Mon Sep 17 00:00:00 2001 From: Reinette Chatre Date: Fri, 12 Mar 2010 11:13:26 -0800 Subject: iwlwifi: fix regulatory Commit "cfg80211: convert bools into flags" mistakenly modified iwlwifi's regulatory settings instead of just converting it. Fix this. This fixes http://bugzilla.intellinuxwireless.org/show_bug.cgi?id=2172 Signed-off-by: Reinette Chatre CC: stable@kernel.org --- drivers/net/wireless/iwlwifi/iwl-agn.c | 2 +- drivers/net/wireless/iwlwifi/iwl3945-base.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 818367b57bab..c8e2e3a42b4b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -2644,7 +2644,7 @@ static int iwl_mac_setup_register(struct iwl_priv *priv) BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_ADHOC); - hw->wiphy->flags |= WIPHY_FLAG_STRICT_REGULATORY | + hw->wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY | WIPHY_FLAG_DISABLE_BEACON_HINTS; /* diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c index 54daa38ecba3..f93013e9b17d 100644 --- a/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c @@ -3921,7 +3921,7 @@ static int iwl3945_setup_mac(struct iwl_priv *priv) BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_ADHOC); - hw->wiphy->flags |= WIPHY_FLAG_STRICT_REGULATORY | + hw->wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY | WIPHY_FLAG_DISABLE_BEACON_HINTS; hw->wiphy->max_scan_ssids = PROBE_OPTION_MAX_3945; -- cgit v1.2.2 From be6b38bcb175613f239e0b302607db346472c6b6 Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Thu, 18 Mar 2010 09:05:00 -0700 Subject: iwlwifi: counting number of tfds can be free for 4965 Forget one hunk in 4965 during "iwlwifi: error checking for number of tfds in queue" patch. Reported-by: Shanyu Zhao Signed-off-by: Wey-Yi Guy Signed-off-by: Reinette Chatre CC: stable@kernel.org --- drivers/net/wireless/iwlwifi/iwl-4965.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c index 1bd2cd836026..83c52a682622 100644 --- a/drivers/net/wireless/iwlwifi/iwl-4965.c +++ b/drivers/net/wireless/iwlwifi/iwl-4965.c @@ -2041,16 +2041,14 @@ static void iwl4965_rx_reply_tx(struct iwl_priv *priv, tx_resp->failure_frame); freed = iwl_tx_queue_reclaim(priv, txq_id, index); - if (qc && likely(sta_id != IWL_INVALID_STATION)) - priv->stations[sta_id].tid[tid].tfds_in_queue -= freed; + iwl_free_tfds_in_queue(priv, sta_id, tid, freed); if (priv->mac80211_registered && (iwl_queue_space(&txq->q) > txq->q.low_mark)) iwl_wake_queue(priv, txq_id); } - if (qc && likely(sta_id != IWL_INVALID_STATION)) - iwl_txq_check_empty(priv, sta_id, tid, txq_id); + iwl_txq_check_empty(priv, sta_id, tid, txq_id); if (iwl_check_bits(status, TX_ABORT_REQUIRED_MSK)) IWL_ERR(priv, "TODO: Implement Tx ABORT REQUIRED!!!\n"); -- cgit v1.2.2 From 48a6be6a0dd3982bb2d48e82b3e6f5458d9f3c63 Mon Sep 17 00:00:00 2001 From: Shanyu Zhao Date: Tue, 16 Mar 2010 10:22:26 -0700 Subject: iwlwifi: clear unattended interrupts in tasklet Previously in interrupt handling tasklet, iwlwifi driver only clear/ack those interrupts that are enabled by the driver through inta_mask. If the hardware generates unattended interrupts, driver will not ack them, defeating the interrupt coalescing feature. This results in high number of interrupts per second and high CPU utilization. This patch addresses this issue by acking those unattended interrupts in the tasklet. Local test showed an order of magnitude improvement in terms of the number of interrupts without sacrificing networking throughput. This is a workaround for hardware issue. Signed-off-by: Shanyu Zhao Signed-off-by: Zhu Yi Signed-off-by: Reinette Chatre --- drivers/net/wireless/iwlwifi/iwl-agn.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index c8e2e3a42b4b..e4c2e1e448ad 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -1258,7 +1258,15 @@ static void iwl_irq_tasklet(struct iwl_priv *priv) /* Ack/clear/reset pending uCode interrupts. * Note: Some bits in CSR_INT are "OR" of bits in CSR_FH_INT_STATUS, */ - iwl_write32(priv, CSR_INT, priv->inta); + /* There is a hardware bug in the interrupt mask function that some + * interrupts (i.e. CSR_INT_BIT_SCD) can still be generated even if + * they are disabled in the CSR_INT_MASK register. Furthermore the + * ICT interrupt handling mechanism has another bug that might cause + * these unmasked interrupts fail to be detected. We workaround the + * hardware bugs here by ACKing all the possible interrupts so that + * interrupt coalescing can still be achieved. + */ + iwl_write32(priv, CSR_INT, priv->inta | ~priv->inta_mask); inta = priv->inta; -- cgit v1.2.2 From 71976907842abb71a0e6fda081e1d16e00420849 Mon Sep 17 00:00:00 2001 From: Gertjan van Wingerde Date: Wed, 24 Mar 2010 21:42:36 +0100 Subject: rt2x00: Fix typo in RF register programming of rt2800. Signed-off-by: Gertjan van Wingerde Acked-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2800lib.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c index 18d4d8e4ae6b..326fce78489d 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/rt2x00/rt2800lib.c @@ -812,9 +812,9 @@ static void rt2800_config_channel_rt3x(struct rt2x00_dev *rt2x00dev, rt2800_rfcsr_write(rt2x00dev, 24, rt2x00dev->calibration[conf_is_ht40(conf)]); - rt2800_rfcsr_read(rt2x00dev, 23, &rfcsr); + rt2800_rfcsr_read(rt2x00dev, 7, &rfcsr); rt2x00_set_field8(&rfcsr, RFCSR7_RF_TUNING, 1); - rt2800_rfcsr_write(rt2x00dev, 23, rfcsr); + rt2800_rfcsr_write(rt2x00dev, 7, rfcsr); } static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev, -- cgit v1.2.2 From 9e76ad2a27f592c1390248867391880c7efe78b3 Mon Sep 17 00:00:00 2001 From: Gertjan van Wingerde Date: Wed, 24 Mar 2010 21:42:37 +0100 Subject: rt2x00: Disable powersaving by default in rt2500usb. Recent bug reports have shown that rt2500usb also suffers from the powersave problems that the PCI rt2x00 drivers suffer from. So disable powersaving by default for rt2500usb as well. Signed-off-by: Gertjan van Wingerde Acked-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2500usb.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c index ee34c137e7cd..dbaa78138437 100644 --- a/drivers/net/wireless/rt2x00/rt2500usb.c +++ b/drivers/net/wireless/rt2x00/rt2500usb.c @@ -1642,6 +1642,11 @@ static int rt2500usb_probe_hw_mode(struct rt2x00_dev *rt2x00dev) char *tx_power; unsigned int i; + /* + * Disable powersaving as default. + */ + rt2x00dev->hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT; + /* * Initialize all hw fields. */ -- cgit v1.2.2 From 2d20c72c021d96f8b9230396c8e3782f204214ec Mon Sep 17 00:00:00 2001 From: Valentin Longchamp Date: Fri, 26 Mar 2010 11:44:33 +0100 Subject: setup correct int pipe type in ar9170_usb_exec_cmd An int urb is constructed but we fill it in with a bulk pipe type. Commit f661c6f8c67bd55e93348f160d590ff9edf08904 implemented a pipe type check when CONFIG_USB_DEBUG is enabled. The check failed for all the ar9170 usb transfers and the driver could not configure the wifi dongle. This went unnoticed until now because most people don't have CONFIG_USB_DEBUG enabled. Signed-off-by: Valentin Longchamp Cc: Stable Acked-by: Christian Lamparter Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ar9170/usb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ar9170/usb.c b/drivers/net/wireless/ath/ar9170/usb.c index c18575070061..6b1cb706e410 100644 --- a/drivers/net/wireless/ath/ar9170/usb.c +++ b/drivers/net/wireless/ath/ar9170/usb.c @@ -418,7 +418,7 @@ static int ar9170_usb_exec_cmd(struct ar9170 *ar, enum ar9170_cmd cmd, spin_unlock_irqrestore(&aru->common.cmdlock, flags); usb_fill_int_urb(urb, aru->udev, - usb_sndbulkpipe(aru->udev, AR9170_EP_CMD), + usb_sndintpipe(aru->udev, AR9170_EP_CMD), aru->common.cmdbuf, plen + 4, ar9170_usb_tx_urb_complete, NULL, 1); -- cgit v1.2.2 From 8e1a53c615e8efe0fac670f2973da64758748a8a Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Sun, 28 Mar 2010 14:55:00 +0300 Subject: iwlwifi: range checking issue IWL_RATE_COUNT is 13 and IWL_RATE_COUNT_LEGACY is 12. IWL_RATE_COUNT_LEGACY is the right one here because iwl3945_rates doesn't support 60M and also that's how "rates" is defined in iwlcore_init_geos() from drivers/net/wireless/iwlwifi/iwl-core.c. rates = kzalloc((sizeof(struct ieee80211_rate) * IWL_RATE_COUNT_LEGACY), GFP_KERNEL); Signed-off-by: Dan Carpenter Cc: stable@kernel.org Acked-by: Zhu Yi Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl3945-base.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c index f93013e9b17d..e276f2a4e835 100644 --- a/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c @@ -1955,7 +1955,7 @@ static void iwl3945_init_hw_rates(struct iwl_priv *priv, { int i; - for (i = 0; i < IWL_RATE_COUNT; i++) { + for (i = 0; i < IWL_RATE_COUNT_LEGACY; i++) { rates[i].bitrate = iwl3945_rates[i].ieee * 5; rates[i].hw_value = i; /* Rate scaling will work on indexes */ rates[i].hw_value_short = i; -- cgit v1.2.2 From 7371400431389e1df6a2a05ab9882055b8a6ff2c Mon Sep 17 00:00:00 2001 From: Daniel Mack Date: Mon, 29 Mar 2010 17:14:18 +0200 Subject: net/wireless/libertas: do not call wiphy_unregister() w/o wiphy_register() The libertas driver calls wiphy_unregister() without a prior wiphy_register() when a devices fails initialization. Fix this by introducing a private flag. [ 9.310000] Unable to handle kernel NULL pointer dereference at virtual address 00000000 [...] [ 9.330000] [] (wiphy_unregister+0xfc/0x19c) from [] (lbs_cfg_free+0x70/0x9c [libertas]) [ 9.330000] [] (lbs_cfg_free+0x70/0x9c [libertas]) from [] (lbs_remove_card+0x180/0x210 [libertas]) [ 9.330000] [] (lbs_remove_card+0x180/0x210 [libertas]) from [] (if_sdio_probe+0xdc4/0xef4 [libertas_sdio]) [ 9.330000] [] (if_sdio_probe+0xdc4/0xef4 [libertas_sdio]) from [] (sdio_bus_probe+0xd4/0xf0) [ 9.330000] [] (sdio_bus_probe+0xd4/0xf0) from [] (driver_probe_device+0xa4/0x174) [ 9.330000] [] (driver_probe_device+0xa4/0x174) from [] (__driver_attach+0x60/0x84) [ 9.330000] [] (__driver_attach+0x60/0x84) from [] (bus_for_each_dev+0x4c/0x8c) [ 9.330000] [] (bus_for_each_dev+0x4c/0x8c) from [] (bus_add_driver+0xa0/0x228) [ 9.330000] [] (bus_add_driver+0xa0/0x228) from [] (driver_register+0xc0/0x150) [ 9.330000] [] (driver_register+0xc0/0x150) from [] (if_sdio_init_module+0x6c/0x108 [libertas_sdio]) [ 9.330000] [] (if_sdio_init_module+0x6c/0x108 [libertas_sdio]) from [] (do_one_initcall+0x5c/0x1bc) [ 9.330000] [] (do_one_initcall+0x5c/0x1bc) from [] (sys_init_module+0xc0/0x1f0) [ 9.330000] [] (sys_init_module+0xc0/0x1f0) from [] (ret_fast_syscall+0x0/0x30) Signed-off-by: Daniel Mack Cc: Dan Williams Cc: John W. Linville Cc: Holger Schurig Cc: Bing Zhao Cc: libertas-dev@lists.infradead.org Cc: linux-wireless@vger.kernel.org Cc: netdev@vger.kernel.org Signed-off-by: John W. Linville --- drivers/net/wireless/libertas/cfg.c | 8 ++++++-- drivers/net/wireless/libertas/dev.h | 1 + 2 files changed, 7 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/libertas/cfg.c b/drivers/net/wireless/libertas/cfg.c index 4396dccd12ac..82ebe1461a77 100644 --- a/drivers/net/wireless/libertas/cfg.c +++ b/drivers/net/wireless/libertas/cfg.c @@ -172,6 +172,8 @@ int lbs_cfg_register(struct lbs_private *priv) if (ret < 0) lbs_pr_err("cannot register wiphy device\n"); + priv->wiphy_registered = true; + ret = register_netdev(priv->dev); if (ret) lbs_pr_err("cannot register network device\n"); @@ -190,9 +192,11 @@ void lbs_cfg_free(struct lbs_private *priv) if (!wdev) return; - if (wdev->wiphy) { + if (priv->wiphy_registered) wiphy_unregister(wdev->wiphy); + + if (wdev->wiphy) wiphy_free(wdev->wiphy); - } + kfree(wdev); } diff --git a/drivers/net/wireless/libertas/dev.h b/drivers/net/wireless/libertas/dev.h index 6977ee820214..6875e1498bd5 100644 --- a/drivers/net/wireless/libertas/dev.h +++ b/drivers/net/wireless/libertas/dev.h @@ -36,6 +36,7 @@ struct lbs_private { /* CFG80211 */ struct wireless_dev *wdev; + bool wiphy_registered; /* Mesh */ struct net_device *mesh_dev; /* Virtual device */ -- cgit v1.2.2 From dd48744964296b5713032ea1d66eb9e3d990e287 Mon Sep 17 00:00:00 2001 From: Zhu Yi Date: Mon, 22 Mar 2010 02:28:41 -0700 Subject: iwlwifi: fix DMA allocation warnings Below warning is triggered sometimes at module removal time when CONFIG_DMA_API_DEBUG is enabled. This should be caused by we didn't unmap pending commands (enqueued, but no complete notification received) for the Tx command queue. [ 1583.107469] ------------[ cut here ]------------ [ 1583.107539] WARNING: at lib/dma-debug.c:688 dma_debug_device_change+0x13c/0x180() [ 1583.107617] Hardware name: ... [ 1583.107664] pci 0000:04:00.0: DMA-API: device driver has pending DMA allocations while released from device [count=1] [ 1583.107713] Modules linked in: ... [ 1583.111661] Pid: 16970, comm: modprobe Tainted: G W 2.6.34-rc1-wl #33 [ 1583.111727] Call Trace: [ 1583.111779] [] ? dma_debug_device_change+0x13c/0x180 [ 1583.111833] [] ? dma_debug_device_change+0x13c/0x180 [ 1583.111908] [] warn_slowpath_common+0x71/0xd0 [ 1583.111963] [] ? dma_debug_device_change+0x13c/0x180 [ 1583.112016] [] warn_slowpath_fmt+0x2b/0x30 [ 1583.112086] [] dma_debug_device_change+0x13c/0x180 [ 1583.112142] [] notifier_call_chain+0x53/0x90 [ 1583.112198] [] ? down_read+0x6e/0x90 [ 1583.112271] [] __blocking_notifier_call_chain+0x49/0x70 [ 1583.112326] [] blocking_notifier_call_chain+0x1f/0x30 [ 1583.112380] [] __device_release_driver+0x8c/0xa0 [ 1583.112451] [] driver_detach+0x8f/0xa0 [ 1583.112538] [] bus_remove_driver+0x82/0x100 [ 1583.112595] [] driver_unregister+0x49/0x80 [ 1583.112671] [] ? sysfs_remove_file+0x12/0x20 [ 1583.112727] [] pci_unregister_driver+0x32/0x80 [ 1583.112791] [] iwl_exit+0x12/0x19 [iwlagn] [ 1583.112848] [] sys_delete_module+0x15a/0x210 [ 1583.112870] [] ? up_read+0x1b/0x30 [ 1583.112893] [] ? trace_hardirqs_off_thunk+0xc/0x10 [ 1583.112924] [] ? trace_hardirqs_on_thunk+0xc/0x10 [ 1583.112947] [] ? do_page_fault+0x1ff/0x3c0 [ 1583.112978] [] ? restore_all_notrace+0x0/0x18 [ 1583.113002] [] ? trace_hardirqs_on_caller+0x20/0x190 [ 1583.113025] [] sysenter_do_call+0x12/0x38 [ 1583.113054] ---[ end trace fc23e059cc4c2ced ]--- Signed-off-by: Zhu Yi Signed-off-by: Reinette Chatre --- drivers/net/wireless/iwlwifi/iwl-tx.c | 48 ++++++++++++++++++++++++++++++++--- 1 file changed, 45 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-tx.c b/drivers/net/wireless/iwlwifi/iwl-tx.c index 8c12311dbb0a..6aa309032f4e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-tx.c @@ -193,10 +193,34 @@ void iwl_cmd_queue_free(struct iwl_priv *priv) struct iwl_queue *q = &txq->q; struct device *dev = &priv->pci_dev->dev; int i; + bool huge = false; if (q->n_bd == 0) return; + for (; q->read_ptr != q->write_ptr; + q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd)) { + /* we have no way to tell if it is a huge cmd ATM */ + i = get_cmd_index(q, q->read_ptr, 0); + + if (txq->meta[i].flags & CMD_SIZE_HUGE) { + huge = true; + continue; + } + + pci_unmap_single(priv->pci_dev, + pci_unmap_addr(&txq->meta[i], mapping), + pci_unmap_len(&txq->meta[i], len), + PCI_DMA_BIDIRECTIONAL); + } + if (huge) { + i = q->n_window; + pci_unmap_single(priv->pci_dev, + pci_unmap_addr(&txq->meta[i], mapping), + pci_unmap_len(&txq->meta[i], len), + PCI_DMA_BIDIRECTIONAL); + } + /* De-alloc array of command/tx buffers */ for (i = 0; i <= TFD_CMD_SLOTS; i++) kfree(txq->cmd[i]); @@ -1049,6 +1073,14 @@ int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd) spin_lock_irqsave(&priv->hcmd_lock, flags); + /* If this is a huge cmd, mark the huge flag also on the meta.flags + * of the _original_ cmd. This is used for DMA mapping clean up. + */ + if (cmd->flags & CMD_SIZE_HUGE) { + idx = get_cmd_index(q, q->write_ptr, 0); + txq->meta[idx].flags = CMD_SIZE_HUGE; + } + idx = get_cmd_index(q, q->write_ptr, cmd->flags & CMD_SIZE_HUGE); out_cmd = txq->cmd[idx]; out_meta = &txq->meta[idx]; @@ -1226,6 +1258,7 @@ void iwl_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb) bool huge = !!(pkt->hdr.sequence & SEQ_HUGE_FRAME); struct iwl_device_cmd *cmd; struct iwl_cmd_meta *meta; + struct iwl_tx_queue *txq = &priv->txq[IWL_CMD_QUEUE_NUM]; /* If a Tx command is being handled and it isn't in the actual * command queue then there a command routing bug has been introduced @@ -1239,9 +1272,17 @@ void iwl_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb) return; } - cmd_index = get_cmd_index(&priv->txq[IWL_CMD_QUEUE_NUM].q, index, huge); - cmd = priv->txq[IWL_CMD_QUEUE_NUM].cmd[cmd_index]; - meta = &priv->txq[IWL_CMD_QUEUE_NUM].meta[cmd_index]; + /* If this is a huge cmd, clear the huge flag on the meta.flags + * of the _original_ cmd. So that iwl_cmd_queue_free won't unmap + * the DMA buffer for the scan (huge) command. + */ + if (huge) { + cmd_index = get_cmd_index(&txq->q, index, 0); + txq->meta[cmd_index].flags = 0; + } + cmd_index = get_cmd_index(&txq->q, index, huge); + cmd = txq->cmd[cmd_index]; + meta = &txq->meta[cmd_index]; pci_unmap_single(priv->pci_dev, pci_unmap_addr(meta, mapping), @@ -1263,6 +1304,7 @@ void iwl_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb) get_cmd_string(cmd->hdr.cmd)); wake_up_interruptible(&priv->wait_command_queue); } + meta->flags = 0; } EXPORT_SYMBOL(iwl_tx_cmd_complete); -- cgit v1.2.2 From 04f2dec1c3d375c4072613880f28f43b66524876 Mon Sep 17 00:00:00 2001 From: Shanyu Zhao Date: Fri, 19 Mar 2010 13:34:45 -0700 Subject: iwlwifi: use consistent table for tx data collect When collecting tx data for non-aggregation packets in rate scaling, if the tx data matches "other table", it still uses current table to update the stats and calculate average throughput in function rs_collect_tx_data(). This can mess up the rate scaling data structure and cause a kernel panic in a BUG_ON statement in rs_rate_scale_perform(). To fix this bug, we pass table pointer instead of window pointer (pointed to by table pointer) to function rs_collect_tx_data() so that the table being used is consistent. Signed-off-by: Shanyu Zhao Signed-off-by: Henry Zhang Signed-off-by: Reinette Chatre --- drivers/net/wireless/iwlwifi/iwl-agn-rs.c | 55 ++++++++++++++----------------- 1 file changed, 24 insertions(+), 31 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c index 8bf7c20b9d39..be00cb3b1d0e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c @@ -345,6 +345,17 @@ static inline int get_num_of_ant_from_rate(u32 rate_n_flags) !!(rate_n_flags & RATE_MCS_ANT_C_MSK); } +/* + * Static function to get the expected throughput from an iwl_scale_tbl_info + * that wraps a NULL pointer check + */ +static s32 get_expected_tpt(struct iwl_scale_tbl_info *tbl, int rs_index) +{ + if (tbl->expected_tpt) + return tbl->expected_tpt[rs_index]; + return 0; +} + /** * rs_collect_tx_data - Update the success/failure sliding window * @@ -352,19 +363,21 @@ static inline int get_num_of_ant_from_rate(u32 rate_n_flags) * at this rate. window->data contains the bitmask of successful * packets. */ -static int rs_collect_tx_data(struct iwl_rate_scale_data *windows, - int scale_index, s32 tpt, int attempts, - int successes) +static int rs_collect_tx_data(struct iwl_scale_tbl_info *tbl, + int scale_index, int attempts, int successes) { struct iwl_rate_scale_data *window = NULL; static const u64 mask = (((u64)1) << (IWL_RATE_MAX_WINDOW - 1)); - s32 fail_count; + s32 fail_count, tpt; if (scale_index < 0 || scale_index >= IWL_RATE_COUNT) return -EINVAL; /* Select window for current tx bit rate */ - window = &(windows[scale_index]); + window = &(tbl->win[scale_index]); + + /* Get expected throughput */ + tpt = get_expected_tpt(tbl, scale_index); /* * Keep track of only the latest 62 tx frame attempts in this rate's @@ -738,16 +751,6 @@ static bool table_type_matches(struct iwl_scale_tbl_info *a, return (a->lq_type == b->lq_type) && (a->ant_type == b->ant_type) && (a->is_SGI == b->is_SGI); } -/* - * Static function to get the expected throughput from an iwl_scale_tbl_info - * that wraps a NULL pointer check - */ -static s32 get_expected_tpt(struct iwl_scale_tbl_info *tbl, int rs_index) -{ - if (tbl->expected_tpt) - return tbl->expected_tpt[rs_index]; - return 0; -} /* * mac80211 sends us Tx status @@ -764,12 +767,10 @@ static void rs_tx_status(void *priv_r, struct ieee80211_supported_band *sband, struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; struct iwl_priv *priv = (struct iwl_priv *)priv_r; struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); - struct iwl_rate_scale_data *window = NULL; enum mac80211_rate_control_flags mac_flags; u32 tx_rate; struct iwl_scale_tbl_info tbl_type; - struct iwl_scale_tbl_info *curr_tbl, *other_tbl; - s32 tpt = 0; + struct iwl_scale_tbl_info *curr_tbl, *other_tbl, *tmp_tbl; IWL_DEBUG_RATE_LIMIT(priv, "get frame ack response, update rate scale window\n"); @@ -852,7 +853,6 @@ static void rs_tx_status(void *priv_r, struct ieee80211_supported_band *sband, IWL_DEBUG_RATE(priv, "Neither active nor search matches tx rate\n"); return; } - window = (struct iwl_rate_scale_data *)&(curr_tbl->win[0]); /* * Updating the frame history depends on whether packets were @@ -865,8 +865,7 @@ static void rs_tx_status(void *priv_r, struct ieee80211_supported_band *sband, tx_rate = le32_to_cpu(table->rs_table[0].rate_n_flags); rs_get_tbl_info_from_mcs(tx_rate, priv->band, &tbl_type, &rs_index); - tpt = get_expected_tpt(curr_tbl, rs_index); - rs_collect_tx_data(window, rs_index, tpt, + rs_collect_tx_data(curr_tbl, rs_index, info->status.ampdu_ack_len, info->status.ampdu_ack_map); @@ -896,19 +895,13 @@ static void rs_tx_status(void *priv_r, struct ieee80211_supported_band *sband, * table as active/search. */ if (table_type_matches(&tbl_type, curr_tbl)) - tpt = get_expected_tpt(curr_tbl, rs_index); + tmp_tbl = curr_tbl; else if (table_type_matches(&tbl_type, other_tbl)) - tpt = get_expected_tpt(other_tbl, rs_index); + tmp_tbl = other_tbl; else continue; - - /* Constants mean 1 transmission, 0 successes */ - if (i < retries) - rs_collect_tx_data(window, rs_index, tpt, 1, - 0); - else - rs_collect_tx_data(window, rs_index, tpt, 1, - legacy_success); + rs_collect_tx_data(tmp_tbl, rs_index, 1, + i < retries ? 0 : legacy_success); } /* Update success/fail counts if not searching for new mode */ -- cgit v1.2.2 From de0f60ea94e132c858caa64a44b2012e1e8580b0 Mon Sep 17 00:00:00 2001 From: Zhu Yi Date: Tue, 23 Mar 2010 00:45:03 -0700 Subject: iwlwifi: avoid Tx queue memory allocation in interface down We used to free all the Tx queues memory when interface is brought down and reallocate them again in interface up. This requires order-4 allocation for txq->cmd[]. In situations like s2ram, this usually leads to allocation failure in the memory subsystem. The patch fixed this problem by allocating the Tx queues memory only at the first time. Later iwl_down/iwl_up only initialize but don't free and reallocate them. The memory is freed at the device removal time. BTW, we have already done this for the Rx queue. This fixed bug https://bugzilla.kernel.org/show_bug.cgi?id=15551 Signed-off-by: Zhu Yi Acked-by: Wey-Yi Guy Signed-off-by: Reinette Chatre --- drivers/net/wireless/iwlwifi/iwl-core.c | 11 +++--- drivers/net/wireless/iwlwifi/iwl-core.h | 5 ++- drivers/net/wireless/iwlwifi/iwl-tx.c | 59 +++++++++++++++++++++++++++------ 3 files changed, 60 insertions(+), 15 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index 112149e9b31e..894bcb8b8b37 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -307,10 +307,13 @@ int iwl_hw_nic_init(struct iwl_priv *priv) spin_unlock_irqrestore(&priv->lock, flags); - /* Allocate and init all Tx and Command queues */ - ret = iwl_txq_ctx_reset(priv); - if (ret) - return ret; + /* Allocate or reset and init all Tx and Command queues */ + if (!priv->txq) { + ret = iwl_txq_ctx_alloc(priv); + if (ret) + return ret; + } else + iwl_txq_ctx_reset(priv); set_bit(STATUS_INIT, &priv->status); diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index 4ef7739f9e8e..732590f5fe30 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -442,7 +442,8 @@ void iwl_rx_csa(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb); /***************************************************** * TX ******************************************************/ -int iwl_txq_ctx_reset(struct iwl_priv *priv); +int iwl_txq_ctx_alloc(struct iwl_priv *priv); +void iwl_txq_ctx_reset(struct iwl_priv *priv); void iwl_hw_txq_free_tfd(struct iwl_priv *priv, struct iwl_tx_queue *txq); int iwl_hw_txq_attach_buf_to_tfd(struct iwl_priv *priv, struct iwl_tx_queue *txq, @@ -456,6 +457,8 @@ void iwl_free_tfds_in_queue(struct iwl_priv *priv, void iwl_txq_update_write_ptr(struct iwl_priv *priv, struct iwl_tx_queue *txq); int iwl_tx_queue_init(struct iwl_priv *priv, struct iwl_tx_queue *txq, int slots_num, u32 txq_id); +void iwl_tx_queue_reset(struct iwl_priv *priv, struct iwl_tx_queue *txq, + int slots_num, u32 txq_id); void iwl_tx_queue_free(struct iwl_priv *priv, int txq_id); int iwl_tx_agg_start(struct iwl_priv *priv, const u8 *ra, u16 tid, u16 *ssn); int iwl_tx_agg_stop(struct iwl_priv *priv , const u8 *ra, u16 tid); diff --git a/drivers/net/wireless/iwlwifi/iwl-tx.c b/drivers/net/wireless/iwlwifi/iwl-tx.c index 6aa309032f4e..343d81ad2653 100644 --- a/drivers/net/wireless/iwlwifi/iwl-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-tx.c @@ -433,6 +433,26 @@ out_free_arrays: } EXPORT_SYMBOL(iwl_tx_queue_init); +void iwl_tx_queue_reset(struct iwl_priv *priv, struct iwl_tx_queue *txq, + int slots_num, u32 txq_id) +{ + int actual_slots = slots_num; + + if (txq_id == IWL_CMD_QUEUE_NUM) + actual_slots++; + + memset(txq->meta, 0, sizeof(struct iwl_cmd_meta) * actual_slots); + + txq->need_update = 0; + + /* Initialize queue's high/low-water marks, and head/tail indexes */ + iwl_queue_init(priv, &txq->q, TFD_QUEUE_SIZE_MAX, slots_num, txq_id); + + /* Tell device where to find queue */ + priv->cfg->ops->lib->txq_init(priv, txq); +} +EXPORT_SYMBOL(iwl_tx_queue_reset); + /** * iwl_hw_txq_ctx_free - Free TXQ Context * @@ -444,8 +464,7 @@ void iwl_hw_txq_ctx_free(struct iwl_priv *priv) /* Tx queues */ if (priv->txq) { - for (txq_id = 0; txq_id < priv->hw_params.max_txq_num; - txq_id++) + for (txq_id = 0; txq_id < priv->hw_params.max_txq_num; txq_id++) if (txq_id == IWL_CMD_QUEUE_NUM) iwl_cmd_queue_free(priv); else @@ -461,15 +480,15 @@ void iwl_hw_txq_ctx_free(struct iwl_priv *priv) EXPORT_SYMBOL(iwl_hw_txq_ctx_free); /** - * iwl_txq_ctx_reset - Reset TX queue context - * Destroys all DMA structures and initialize them again + * iwl_txq_ctx_alloc - allocate TX queue context + * Allocate all Tx DMA structures and initialize them * * @param priv * @return error code */ -int iwl_txq_ctx_reset(struct iwl_priv *priv) +int iwl_txq_ctx_alloc(struct iwl_priv *priv) { - int ret = 0; + int ret; int txq_id, slots_num; unsigned long flags; @@ -527,8 +546,31 @@ int iwl_txq_ctx_reset(struct iwl_priv *priv) return ret; } +void iwl_txq_ctx_reset(struct iwl_priv *priv) +{ + int txq_id, slots_num; + unsigned long flags; + + spin_lock_irqsave(&priv->lock, flags); + + /* Turn off all Tx DMA fifos */ + priv->cfg->ops->lib->txq_set_sched(priv, 0); + + /* Tell NIC where to find the "keep warm" buffer */ + iwl_write_direct32(priv, FH_KW_MEM_ADDR_REG, priv->kw.dma >> 4); + + spin_unlock_irqrestore(&priv->lock, flags); + + /* Alloc and init all Tx queues, including the command queue (#4) */ + for (txq_id = 0; txq_id < priv->hw_params.max_txq_num; txq_id++) { + slots_num = txq_id == IWL_CMD_QUEUE_NUM ? + TFD_CMD_SLOTS : TFD_TX_CMD_SLOTS; + iwl_tx_queue_reset(priv, &priv->txq[txq_id], slots_num, txq_id); + } +} + /** - * iwl_txq_ctx_stop - Stop all Tx DMA channels, free Tx queue memory + * iwl_txq_ctx_stop - Stop all Tx DMA channels */ void iwl_txq_ctx_stop(struct iwl_priv *priv) { @@ -548,9 +590,6 @@ void iwl_txq_ctx_stop(struct iwl_priv *priv) 1000); } spin_unlock_irqrestore(&priv->lock, flags); - - /* Deallocate memory for all Tx queues */ - iwl_hw_txq_ctx_free(priv); } EXPORT_SYMBOL(iwl_txq_ctx_stop); -- cgit v1.2.2 From 1144601118507f8b3b676a9a392584d216d3f2cc Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Tue, 6 Apr 2010 12:05:01 -0700 Subject: ath9k: fix double calls to ath_radio_enable With the enable_radio being uninitialized, ath_radio_enable() might be called twice, which can leave some hardware in an undefined state. Signed-off-by: Felix Fietkau Cc: stable@kernel.org Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/main.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 67ca4e5a6017..115e1aeedb59 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -1532,8 +1532,7 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed) all_wiphys_idle = ath9k_all_wiphys_idle(sc); ath9k_set_wiphy_idle(aphy, idle); - if (!idle && all_wiphys_idle) - enable_radio = true; + enable_radio = (!idle && all_wiphys_idle); /* * After we unlock here its possible another wiphy -- cgit v1.2.2