diff options
Diffstat (limited to 'drivers')
54 files changed, 346 insertions, 190 deletions
diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig index abcafac64738..ef683ebd367c 100644 --- a/drivers/char/Kconfig +++ b/drivers/char/Kconfig @@ -815,7 +815,7 @@ config SGI_IP27_RTC config GEN_RTC tristate "Generic /dev/rtc emulation" - depends on RTC!=y && !IA64 && !ARM && !M32R && !SPARC && !FRV && !S390 + depends on RTC!=y && !IA64 && !ARM && !M32R && !SPARC && !FRV && !S390 && !SUPERH ---help--- If you say Y here and create a character special file /dev/rtc with major number 10 and minor number 135 using mknod ("man mknod"), you diff --git a/drivers/i2c/busses/i2c-s3c2410.c b/drivers/i2c/busses/i2c-s3c2410.c index e68a96f589fd..e4540fcf6476 100644 --- a/drivers/i2c/busses/i2c-s3c2410.c +++ b/drivers/i2c/busses/i2c-s3c2410.c @@ -830,7 +830,8 @@ static int s3c24xx_i2c_probe(struct platform_device *pdev) i2c->irq = res; - dev_dbg(&pdev->dev, "irq resource %p (%ld)\n", res, res->start); + dev_dbg(&pdev->dev, "irq resource %p (%lu)\n", res, + (unsigned long)res->start); ret = i2c_add_adapter(&i2c->adap); if (ret < 0) { diff --git a/drivers/i2c/busses/i2c-tiny-usb.c b/drivers/i2c/busses/i2c-tiny-usb.c index 907999049d50..cb9abe7565a7 100644 --- a/drivers/i2c/busses/i2c-tiny-usb.c +++ b/drivers/i2c/busses/i2c-tiny-usb.c @@ -208,7 +208,7 @@ static int i2c_tiny_usb_probe(struct usb_interface *interface, dev->adapter.class = I2C_CLASS_HWMON; dev->adapter.algo = &usb_algorithm; dev->adapter.algo_data = dev; - snprintf(dev->adapter.name, I2C_NAME_SIZE, + snprintf(dev->adapter.name, sizeof(dev->adapter.name), "i2c-tiny-usb at bus %03d device %03d", dev->usb_dev->bus->busnum, dev->usb_dev->devnum); diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c index 64f8e56d300e..435925eba437 100644 --- a/drivers/i2c/i2c-core.c +++ b/drivers/i2c/i2c-core.c @@ -697,9 +697,10 @@ int i2c_attach_client(struct i2c_client *client) if (client->driver) client->dev.driver = &client->driver->driver; - if (client->driver && !is_newstyle_driver(client->driver)) + if (client->driver && !is_newstyle_driver(client->driver)) { client->dev.release = i2c_client_release; - else + client->dev.uevent_suppress = 1; + } else client->dev.release = i2c_client_dev_release; snprintf(&client->dev.bus_id[0], sizeof(client->dev.bus_id), diff --git a/drivers/input/joystick/iforce/iforce-main.c b/drivers/input/joystick/iforce/iforce-main.c index fb129c479a66..682244b1c042 100644 --- a/drivers/input/joystick/iforce/iforce-main.c +++ b/drivers/input/joystick/iforce/iforce-main.c @@ -370,10 +370,8 @@ int iforce_init_device(struct iforce *iforce) /* * Disable spring, enable force feedback. - * FIXME: We should use iforce_set_autocenter() et al here. */ - - iforce_send_packet(iforce, FF_CMD_AUTOCENTER, "\004\000"); + iforce_set_autocenter(input_dev, 0); /* * Find appropriate device entry diff --git a/drivers/input/joystick/iforce/iforce-packets.c b/drivers/input/joystick/iforce/iforce-packets.c index 21c4e13d3a50..3154ccd74000 100644 --- a/drivers/input/joystick/iforce/iforce-packets.c +++ b/drivers/input/joystick/iforce/iforce-packets.c @@ -246,6 +246,8 @@ void iforce_process_packet(struct iforce *iforce, u16 cmd, unsigned char *data) int iforce_get_id_packet(struct iforce *iforce, char *packet) { + int status; + switch (iforce->bus) { case IFORCE_USB: @@ -254,18 +256,22 @@ int iforce_get_id_packet(struct iforce *iforce, char *packet) iforce->cr.bRequest = packet[0]; iforce->ctrl->dev = iforce->usbdev; - if (usb_submit_urb(iforce->ctrl, GFP_ATOMIC)) + status = usb_submit_urb(iforce->ctrl, GFP_ATOMIC); + if (status) { + err("usb_submit_urb failed %d", status); return -1; + } wait_event_interruptible_timeout(iforce->wait, iforce->ctrl->status != -EINPROGRESS, HZ); if (iforce->ctrl->status) { + dbg("iforce->ctrl->status = %d", iforce->ctrl->status); usb_unlink_urb(iforce->ctrl); return -1; } #else - err("iforce_get_id_packet: iforce->bus = USB!"); + dbg("iforce_get_id_packet: iforce->bus = USB!"); #endif break; diff --git a/drivers/input/joystick/iforce/iforce-usb.c b/drivers/input/joystick/iforce/iforce-usb.c index 750099d8e3c6..1457b73850e7 100644 --- a/drivers/input/joystick/iforce/iforce-usb.c +++ b/drivers/input/joystick/iforce/iforce-usb.c @@ -65,6 +65,7 @@ void iforce_usb_xmit(struct iforce *iforce) XMIT_INC(iforce->xmit.tail, n); if ( (n=usb_submit_urb(iforce->out, GFP_ATOMIC)) ) { + clear_bit(IFORCE_XMIT_RUNNING, iforce->xmit_flags); warn("usb_submit_urb failed %d\n", n); } @@ -163,8 +164,8 @@ static int iforce_usb_probe(struct usb_interface *intf, usb_fill_int_urb(iforce->irq, dev, usb_rcvintpipe(dev, epirq->bEndpointAddress), iforce->data, 16, iforce_usb_irq, iforce, epirq->bInterval); - usb_fill_bulk_urb(iforce->out, dev, usb_sndbulkpipe(dev, epout->bEndpointAddress), - iforce + 1, 32, iforce_usb_out, iforce); + usb_fill_int_urb(iforce->out, dev, usb_sndintpipe(dev, epout->bEndpointAddress), + iforce + 1, 32, iforce_usb_out, iforce, epout->bInterval); usb_fill_control_urb(iforce->ctrl, dev, usb_rcvctrlpipe(dev, 0), (void*) &iforce->cr, iforce->edata, 16, iforce_usb_ctrl, iforce); diff --git a/drivers/input/misc/input-polldev.c b/drivers/input/misc/input-polldev.c index 1b2b9c9c5d88..b773d4c756a6 100644 --- a/drivers/input/misc/input-polldev.c +++ b/drivers/input/misc/input-polldev.c @@ -12,6 +12,11 @@ #include <linux/mutex.h> #include <linux/input-polldev.h> +MODULE_AUTHOR("Dmitry Torokhov <dtor@mail.ru>"); +MODULE_DESCRIPTION("Generic implementation of a polled input device"); +MODULE_LICENSE("GPL v2"); +MODULE_VERSION("0.1"); + static DEFINE_MUTEX(polldev_mutex); static int polldev_users; static struct workqueue_struct *polldev_wq; diff --git a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c index cf3e4664e72b..2c5f11a4f6b4 100644 --- a/drivers/input/mouse/alps.c +++ b/drivers/input/mouse/alps.c @@ -251,11 +251,15 @@ static const struct alps_model_info *alps_get_model(struct psmouse *psmouse, int dbg("E7 report: %2.2x %2.2x %2.2x", param[0], param[1], param[2]); - for (i = 0; i < ARRAY_SIZE(rates) && param[2] != rates[i]; i++); - *version = (param[0] << 8) | (param[1] << 4) | i; + if (version) { + for (i = 0; i < ARRAY_SIZE(rates) && param[2] != rates[i]; i++) + /* empty */; + *version = (param[0] << 8) | (param[1] << 4) | i; + } for (i = 0; i < ARRAY_SIZE(alps_model_data); i++) - if (!memcmp(param, alps_model_data[i].signature, sizeof(alps_model_data[i].signature))) + if (!memcmp(param, alps_model_data[i].signature, + sizeof(alps_model_data[i].signature))) return alps_model_data + i; return NULL; @@ -380,32 +384,46 @@ static int alps_poll(struct psmouse *psmouse) return 0; } -static int alps_reconnect(struct psmouse *psmouse) +static int alps_hw_init(struct psmouse *psmouse, int *version) { struct alps_data *priv = psmouse->private; - int version; - - psmouse_reset(psmouse); - if (!(priv->i = alps_get_model(psmouse, &version))) + priv->i = alps_get_model(psmouse, version); + if (!priv->i) return -1; if ((priv->i->flags & ALPS_PASS) && alps_passthrough_mode(psmouse, 1)) return -1; if (alps_tap_mode(psmouse, 1)) { - printk(KERN_WARNING "alps.c: Failed to reenable hardware tapping\n"); + printk(KERN_WARNING "alps.c: Failed to enable hardware tapping\n"); return -1; } if (alps_absolute_mode(psmouse)) { - printk(KERN_ERR "alps.c: Failed to reenable absolute mode\n"); + printk(KERN_ERR "alps.c: Failed to enable absolute mode\n"); return -1; } if ((priv->i->flags & ALPS_PASS) && alps_passthrough_mode(psmouse, 0)) return -1; + /* ALPS needs stream mode, otherwise it won't report any data */ + if (ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_SETSTREAM)) { + printk(KERN_ERR "alps.c: Failed to enable stream mode\n"); + return -1; + } + + return 0; +} + +static int alps_reconnect(struct psmouse *psmouse) +{ + psmouse_reset(psmouse); + + if (alps_hw_init(psmouse, NULL)) + return -1; + return 0; } @@ -430,23 +448,9 @@ int alps_init(struct psmouse *psmouse) goto init_fail; priv->dev2 = dev2; + psmouse->private = priv; - priv->i = alps_get_model(psmouse, &version); - if (!priv->i) - goto init_fail; - - if ((priv->i->flags & ALPS_PASS) && alps_passthrough_mode(psmouse, 1)) - goto init_fail; - - if (alps_tap_mode(psmouse, 1)) - printk(KERN_WARNING "alps.c: Failed to enable hardware tapping\n"); - - if (alps_absolute_mode(psmouse)) { - printk(KERN_ERR "alps.c: Failed to enable absolute mode\n"); - goto init_fail; - } - - if ((priv->i->flags & ALPS_PASS) && alps_passthrough_mode(psmouse, 0)) + if (alps_hw_init(psmouse, &version)) goto init_fail; dev1->evbit[LONG(EV_KEY)] |= BIT(EV_KEY); @@ -493,13 +497,13 @@ int alps_init(struct psmouse *psmouse) /* We are having trouble resyncing ALPS touchpads so disable it for now */ psmouse->resync_time = 0; - psmouse->private = priv; return 0; init_fail: psmouse_reset(psmouse); input_free_device(dev2); kfree(priv); + psmouse->private = NULL; return -1; } diff --git a/drivers/input/mouse/logips2pp.c b/drivers/input/mouse/logips2pp.c index 9df74b72e6c4..0c5660d28caa 100644 --- a/drivers/input/mouse/logips2pp.c +++ b/drivers/input/mouse/logips2pp.c @@ -221,6 +221,7 @@ static const struct ps2pp_info *get_model_info(unsigned char model) { 66, PS2PP_KIND_MX, /* MX3100 reciver */ PS2PP_WHEEL | PS2PP_SIDE_BTN | PS2PP_TASK_BTN | PS2PP_EXTRA_BTN | PS2PP_NAV_BTN | PS2PP_HWHEEL }, + { 72, PS2PP_KIND_TRACKMAN, 0 }, /* T-CH11: TrackMan Marble */ { 73, 0, PS2PP_SIDE_BTN }, { 75, PS2PP_KIND_WHEEL, PS2PP_WHEEL }, { 76, PS2PP_KIND_WHEEL, PS2PP_WHEEL }, diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig index 4f091800bfeb..e5cca9bd0406 100644 --- a/drivers/input/touchscreen/Kconfig +++ b/drivers/input/touchscreen/Kconfig @@ -12,17 +12,17 @@ menuconfig INPUT_TOUCHSCREEN if INPUT_TOUCHSCREEN config TOUCHSCREEN_ADS7846 - tristate "ADS 7846/7843 based touchscreens" + tristate "ADS7846/TSC2046 and ADS7843 based touchscreens" depends on SPI_MASTER depends on HWMON = n || HWMON help Say Y here if you have a touchscreen interface using the - ADS7846 or ADS7843 controller, and your board-specific setup - code includes that in its table of SPI devices. + ADS7846/TSC2046 or ADS7843 controller, and your board-specific + setup code includes that in its table of SPI devices. If HWMON is selected, and the driver is told the reference voltage on your board, you will also get hwmon interfaces for the voltage - (and on ads7846, temperature) sensors of this chip. + (and on ads7846/tsc2046, temperature) sensors of this chip. If unsure, say N (but it's safe to say "Y"). diff --git a/drivers/input/touchscreen/ads7846.c b/drivers/input/touchscreen/ads7846.c index 693e3b2a65a3..1c9069cd3bae 100644 --- a/drivers/input/touchscreen/ads7846.c +++ b/drivers/input/touchscreen/ads7846.c @@ -39,6 +39,7 @@ /* * This code has been heavily tested on a Nokia 770, and lightly * tested on other ads7846 devices (OSK/Mistral, Lubbock). + * TSC2046 is just newer ads7846 silicon. * Support for ads7843 tested on Atmel at91sam926x-EK. * Support for ads7845 has only been stubbed in. * @@ -847,7 +848,7 @@ static int __devinit ads7846_probe(struct spi_device *spi) * may not. So we stick to very-portable 8 bit words, both RX and TX. */ spi->bits_per_word = 8; - spi->mode = SPI_MODE_1; + spi->mode = SPI_MODE_0; err = spi_setup(spi); if (err < 0) return err; diff --git a/drivers/input/touchscreen/hp680_ts_input.c b/drivers/input/touchscreen/hp680_ts_input.c index 61c15024c2a0..1a15475aedfc 100644 --- a/drivers/input/touchscreen/hp680_ts_input.c +++ b/drivers/input/touchscreen/hp680_ts_input.c @@ -1,7 +1,6 @@ #include <linux/input.h> #include <linux/module.h> #include <linux/init.h> - #include <linux/interrupt.h> #include <asm/io.h> #include <asm/delay.h> @@ -18,12 +17,12 @@ #define PHDR 0xa400012e #define SCPDR 0xa4000136 -static void do_softint(void *data); +static void do_softint(struct work_struct *work); static struct input_dev *hp680_ts_dev; -static DECLARE_WORK(work, do_softint); +static DECLARE_DELAYED_WORK(work, do_softint); -static void do_softint(void *data) +static void do_softint(struct work_struct *work) { int absx = 0, absy = 0; u8 scpdr; diff --git a/drivers/input/touchscreen/ucb1400_ts.c b/drivers/input/touchscreen/ucb1400_ts.c index 6582816a0477..f0cbcdb008ed 100644 --- a/drivers/input/touchscreen/ucb1400_ts.c +++ b/drivers/input/touchscreen/ucb1400_ts.c @@ -288,9 +288,9 @@ static int ucb1400_ts_thread(void *_ucb) struct ucb1400 *ucb = _ucb; struct task_struct *tsk = current; int valid = 0; + struct sched_param param = { .sched_priority = 1 }; - tsk->policy = SCHED_FIFO; - tsk->rt_priority = 1; + sched_setscheduler(tsk, SCHED_FIFO, ¶m); while (!kthread_should_stop()) { unsigned int x, y, p; diff --git a/drivers/macintosh/adbhid.c b/drivers/macintosh/adbhid.c index b77ef5187d6d..b46817f699f1 100644 --- a/drivers/macintosh/adbhid.c +++ b/drivers/macintosh/adbhid.c @@ -628,16 +628,16 @@ static void real_leds(unsigned char leds, int device) */ static int adbhid_kbd_event(struct input_dev *dev, unsigned int type, unsigned int code, int value) { - struct adbhid *adbhid = dev->private; + struct adbhid *adbhid = input_get_drvdata(dev); unsigned char leds; switch (type) { case EV_LED: - leds = (test_bit(LED_SCROLLL, dev->led) ? 4 : 0) - | (test_bit(LED_NUML, dev->led) ? 1 : 0) - | (test_bit(LED_CAPSL, dev->led) ? 2 : 0); - real_leds(leds, adbhid->id); - return 0; + leds = (test_bit(LED_SCROLLL, dev->led) ? 4 : 0) | + (test_bit(LED_NUML, dev->led) ? 1 : 0) | + (test_bit(LED_CAPSL, dev->led) ? 2 : 0); + real_leds(leds, adbhid->id); + return 0; } return -1; @@ -649,7 +649,7 @@ adb_message_handler(struct notifier_block *this, unsigned long code, void *x) switch (code) { case ADB_MSG_PRE_RESET: case ADB_MSG_POWERDOWN: - /* Stop the repeat timer. Autopoll is already off at this point */ + /* Stop the repeat timer. Autopoll is already off at this point */ { int i; for (i = 1; i < 16; i++) { @@ -699,7 +699,7 @@ adbhid_input_register(int id, int default_id, int original_handler_id, hid->current_handler_id = current_handler_id; hid->mouse_kind = mouse_kind; hid->flags = 0; - input_dev->private = hid; + input_set_drvdata(input_dev, hid); input_dev->name = hid->name; input_dev->phys = hid->phys; input_dev->id.bustype = BUS_ADB; diff --git a/drivers/media/dvb/bt8xx/dst.c b/drivers/media/dvb/bt8xx/dst.c index 0393a3d19920..e908e3cf1e50 100644 --- a/drivers/media/dvb/bt8xx/dst.c +++ b/drivers/media/dvb/bt8xx/dst.c @@ -1721,9 +1721,6 @@ static void dst_release(struct dvb_frontend *fe) symbol_put(dst_ca_attach); #endif } -#ifdef CONFIG_DVB_CORE_ATTACH - symbol_put(dst_attach); -#endif kfree(state); } diff --git a/drivers/media/dvb/dvb-core/dvbdev.c b/drivers/media/dvb/dvb-core/dvbdev.c index e23d8a0ea1d3..a9fa3337dd81 100644 --- a/drivers/media/dvb/dvb-core/dvbdev.c +++ b/drivers/media/dvb/dvb-core/dvbdev.c @@ -200,7 +200,7 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev, { struct dvb_device *dvbdev; struct file_operations *dvbdevfops; - + struct class_device *clsdev; int id; mutex_lock(&dvbdev_register_lock); @@ -242,8 +242,15 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev, mutex_unlock(&dvbdev_register_lock); - class_device_create(dvb_class, NULL, MKDEV(DVB_MAJOR, nums2minor(adap->num, type, id)), - adap->device, "dvb%d.%s%d", adap->num, dnames[type], id); + clsdev = class_device_create(dvb_class, NULL, MKDEV(DVB_MAJOR, + nums2minor(adap->num, type, id)), + adap->device, "dvb%d.%s%d", adap->num, + dnames[type], id); + if (IS_ERR(clsdev)) { + printk(KERN_ERR "%s: failed to create device dvb%d.%s%d (%ld)\n", + __FUNCTION__, adap->num, dnames[type], id, PTR_ERR(clsdev)); + return PTR_ERR(clsdev); + } dprintk("DVB: register adapter%d/%s%d @ minor: %i (0x%02x)\n", adap->num, dnames[type], id, nums2minor(adap->num, type, id), @@ -431,7 +438,7 @@ static void __exit exit_dvbdev(void) unregister_chrdev_region(MKDEV(DVB_MAJOR, 0), MAX_DVB_MINORS); } -module_init(init_dvbdev); +subsys_initcall(init_dvbdev); module_exit(exit_dvbdev); MODULE_DESCRIPTION("DVB Core Driver"); diff --git a/drivers/media/video/cafe_ccic-regs.h b/drivers/media/video/cafe_ccic-regs.h index b2c22a0d6643..8e2a87cdc791 100644 --- a/drivers/media/video/cafe_ccic-regs.h +++ b/drivers/media/video/cafe_ccic-regs.h @@ -150,6 +150,12 @@ #define REG_GL_IMASK 0x300c /* Interrupt mask register */ #define GIMSK_CCIC_EN 0x00000004 /* CCIC Interrupt enable */ +#define REG_GL_FCR 0x3038 /* GPIO functional control register */ +#define GFCR_GPIO_ON 0x08 /* Camera GPIO enabled */ +#define REG_GL_GPIOR 0x315c /* GPIO register */ +#define GGPIO_OUT 0x80000 /* GPIO output */ +#define GGPIO_VAL 0x00008 /* Output pin value */ + #define REG_LEN REG_GL_IMASK + 4 diff --git a/drivers/media/video/cafe_ccic.c b/drivers/media/video/cafe_ccic.c index 96254dbaf625..c08f650df423 100644 --- a/drivers/media/video/cafe_ccic.c +++ b/drivers/media/video/cafe_ccic.c @@ -775,6 +775,12 @@ static void cafe_ctlr_power_up(struct cafe_camera *cam) spin_lock_irqsave(&cam->dev_lock, flags); cafe_reg_clear_bit(cam, REG_CTRL1, C1_PWRDWN); /* + * Part one of the sensor dance: turn the global + * GPIO signal on. + */ + cafe_reg_write(cam, REG_GL_FCR, GFCR_GPIO_ON); + cafe_reg_write(cam, REG_GL_GPIOR, GGPIO_OUT|GGPIO_VAL); + /* * Put the sensor into operational mode (assumes OLPC-style * wiring). Control 0 is reset - set to 1 to operate. * Control 1 is power down, set to 0 to operate. @@ -784,6 +790,7 @@ static void cafe_ctlr_power_up(struct cafe_camera *cam) cafe_reg_write(cam, REG_GPR, GPR_C1EN|GPR_C0EN|GPR_C0); // mdelay(1); /* Enough? */ spin_unlock_irqrestore(&cam->dev_lock, flags); + msleep(5); /* Just to be sure */ } static void cafe_ctlr_power_down(struct cafe_camera *cam) @@ -792,6 +799,8 @@ static void cafe_ctlr_power_down(struct cafe_camera *cam) spin_lock_irqsave(&cam->dev_lock, flags); cafe_reg_write(cam, REG_GPR, GPR_C1EN|GPR_C0EN|GPR_C1); + cafe_reg_write(cam, REG_GL_FCR, GFCR_GPIO_ON); + cafe_reg_write(cam, REG_GL_GPIOR, GGPIO_OUT); cafe_reg_set_bit(cam, REG_CTRL1, C1_PWRDWN); spin_unlock_irqrestore(&cam->dev_lock, flags); } @@ -851,6 +860,7 @@ static int cafe_cam_init(struct cafe_camera *cam) ret = 0; cam->state = S_IDLE; out: + cafe_ctlr_power_down(cam); mutex_unlock(&cam->s_mutex); return ret; } @@ -2103,10 +2113,16 @@ static int cafe_pci_probe(struct pci_dev *pdev, ret = request_irq(pdev->irq, cafe_irq, IRQF_SHARED, "cafe-ccic", cam); if (ret) goto out_iounmap; + /* + * Initialize the controller and leave it powered up. It will + * stay that way until the sensor driver shows up. + */ cafe_ctlr_init(cam); cafe_ctlr_power_up(cam); /* - * Set up I2C/SMBUS communications + * Set up I2C/SMBUS communications. We have to drop the mutex here + * because the sensor could attach in this call chain, leading to + * unsightly deadlocks. */ mutex_unlock(&cam->s_mutex); /* attach can deadlock */ ret = cafe_smbus_setup(cam); diff --git a/drivers/media/video/em28xx/Kconfig b/drivers/media/video/em28xx/Kconfig index 2c450bd05af5..5b6a40371602 100644 --- a/drivers/media/video/em28xx/Kconfig +++ b/drivers/media/video/em28xx/Kconfig @@ -1,7 +1,6 @@ config VIDEO_EM28XX tristate "Empia EM2800/2820/2840 USB video capture support" - depends on VIDEO_V4L1 && I2C && PCI - select VIDEO_BUF + depends on VIDEO_V4L1 && I2C select VIDEO_TUNER select VIDEO_TVEEPROM select VIDEO_IR diff --git a/drivers/media/video/ivtv/Kconfig b/drivers/media/video/ivtv/Kconfig index 0cc98a0e2496..1aaeaa02f158 100644 --- a/drivers/media/video/ivtv/Kconfig +++ b/drivers/media/video/ivtv/Kconfig @@ -1,6 +1,6 @@ config VIDEO_IVTV tristate "Conexant cx23416/cx23415 MPEG encoder/decoder support" - depends on VIDEO_V4L1 && VIDEO_V4L2 && USB && I2C && EXPERIMENTAL && PCI + depends on VIDEO_V4L1 && VIDEO_V4L2 && PCI && I2C && EXPERIMENTAL select FW_LOADER select VIDEO_TUNER select VIDEO_TVEEPROM diff --git a/drivers/media/video/ivtv/ivtv-driver.h b/drivers/media/video/ivtv/ivtv-driver.h index 9a412d6c6d06..552f04511ead 100644 --- a/drivers/media/video/ivtv/ivtv-driver.h +++ b/drivers/media/video/ivtv/ivtv-driver.h @@ -67,14 +67,6 @@ #include <media/ivtv.h> -#ifdef CONFIG_LIRC_I2C -# error "This driver is not compatible with the LIRC I2C kernel configuration option." -#endif /* CONFIG_LIRC_I2C */ - -#ifndef CONFIG_PCI -# error "This driver requires kernel PCI support." -#endif /* CONFIG_PCI */ - #define IVTV_ENCODER_OFFSET 0x00000000 #define IVTV_ENCODER_SIZE 0x00800000 /* Last half isn't needed 0x01000000 */ diff --git a/drivers/media/video/ivtv/ivtv-ioctl.c b/drivers/media/video/ivtv/ivtv-ioctl.c index 794a6a02f82f..1989ec1cb973 100644 --- a/drivers/media/video/ivtv/ivtv-ioctl.c +++ b/drivers/media/video/ivtv/ivtv-ioctl.c @@ -362,8 +362,6 @@ static int ivtv_get_fmt(struct ivtv *itv, int streamtype, struct v4l2_format *fm case V4L2_BUF_TYPE_VIDEO_OUTPUT: if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) return -EINVAL; - fmt->fmt.pix.left = itv->main_rect.left; - fmt->fmt.pix.top = itv->main_rect.top; fmt->fmt.pix.width = itv->main_rect.width; fmt->fmt.pix.height = itv->main_rect.height; fmt->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; @@ -402,8 +400,6 @@ static int ivtv_get_fmt(struct ivtv *itv, int streamtype, struct v4l2_format *fm break; case V4L2_BUF_TYPE_VIDEO_CAPTURE: - fmt->fmt.pix.left = 0; - fmt->fmt.pix.top = 0; fmt->fmt.pix.width = itv->params.width; fmt->fmt.pix.height = itv->params.height; fmt->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; @@ -498,15 +494,13 @@ static int ivtv_try_or_set_fmt(struct ivtv *itv, int streamtype, if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) return -EINVAL; field = fmt->fmt.pix.field; - r.top = fmt->fmt.pix.top; - r.left = fmt->fmt.pix.left; + r.top = 0; + r.left = 0; r.width = fmt->fmt.pix.width; r.height = fmt->fmt.pix.height; ivtv_get_fmt(itv, streamtype, fmt); if (itv->output_mode != OUT_UDMA_YUV) { /* TODO: would setting the rect also be valid for this mode? */ - fmt->fmt.pix.top = r.top; - fmt->fmt.pix.left = r.left; fmt->fmt.pix.width = r.width; fmt->fmt.pix.height = r.height; } @@ -1141,8 +1135,6 @@ int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void fb->fmt.pixelformat = itv->osd_pixelformat; fb->fmt.width = itv->osd_rect.width; fb->fmt.height = itv->osd_rect.height; - fb->fmt.left = itv->osd_rect.left; - fb->fmt.top = itv->osd_rect.top; fb->base = (void *)itv->osd_video_pbase; if (itv->osd_global_alpha_state) fb->flags |= V4L2_FBUF_FLAG_GLOBAL_ALPHA; diff --git a/drivers/media/video/ov7670.c b/drivers/media/video/ov7670.c index 03bc369a9e49..3ceb8a6249dd 100644 --- a/drivers/media/video/ov7670.c +++ b/drivers/media/video/ov7670.c @@ -720,12 +720,22 @@ static int ov7670_s_fmt(struct i2c_client *c, struct v4l2_format *fmt) struct ov7670_format_struct *ovfmt; struct ov7670_win_size *wsize; struct ov7670_info *info = i2c_get_clientdata(c); - unsigned char com7; + unsigned char com7, clkrc; ret = ov7670_try_fmt(c, fmt, &ovfmt, &wsize); if (ret) return ret; /* + * HACK: if we're running rgb565 we need to grab then rewrite + * CLKRC. If we're *not*, however, then rewriting clkrc hoses + * the colors. + */ + if (fmt->fmt.pix.pixelformat == V4L2_PIX_FMT_RGB565) { + ret = ov7670_read(c, REG_CLKRC, &clkrc); + if (ret) + return ret; + } + /* * COM7 is a pain in the ass, it doesn't like to be read then * quickly written afterward. But we have everything we need * to set it absolutely here, as long as the format-specific @@ -744,7 +754,10 @@ static int ov7670_s_fmt(struct i2c_client *c, struct v4l2_format *fmt) if (wsize->regs) ret = ov7670_write_array(c, wsize->regs); info->fmt = ovfmt; - return 0; + + if (fmt->fmt.pix.pixelformat == V4L2_PIX_FMT_RGB565 && ret == 0) + ret = ov7670_write(c, REG_CLKRC, clkrc); + return ret; } /* @@ -1267,7 +1280,9 @@ static int ov7670_attach(struct i2c_adapter *adapter) ret = ov7670_detect(client); if (ret) goto out_free_info; - i2c_attach_client(client); + ret = i2c_attach_client(client); + if (ret) + goto out_free_info; return 0; out_free_info: diff --git a/drivers/media/video/tuner-simple.c b/drivers/media/video/tuner-simple.c index 1b9b0742f753..c40b92ce1fad 100644 --- a/drivers/media/video/tuner-simple.c +++ b/drivers/media/video/tuner-simple.c @@ -205,9 +205,13 @@ static void default_set_tv_freq(struct i2c_client *c, unsigned int freq) /* 0x01 -> ??? no change ??? */ /* 0x02 -> PAL BDGHI / SECAM L */ /* 0x04 -> ??? PAL others / SECAM others ??? */ - cb &= ~0x02; - if (t->std & V4L2_STD_SECAM) - cb |= 0x02; + cb &= ~0x03; + if (t->std & V4L2_STD_SECAM_L) //also valid for V4L2_STD_SECAM + cb |= PHILIPS_MF_SET_PAL_L; + else if (t->std & V4L2_STD_SECAM_LC) + cb |= PHILIPS_MF_SET_PAL_L2; + else /* V4L2_STD_B|V4L2_STD_GH */ + cb |= PHILIPS_MF_SET_BG; break; case TUNER_TEMIC_4046FM5: diff --git a/drivers/mfd/ucb1x00-ts.c b/drivers/mfd/ucb1x00-ts.c index cb8c264eaff0..7772bd1d92b4 100644 --- a/drivers/mfd/ucb1x00-ts.c +++ b/drivers/mfd/ucb1x00-ts.c @@ -207,16 +207,7 @@ static int ucb1x00_thread(void *_ts) struct ucb1x00_ts *ts = _ts; struct task_struct *tsk = current; DECLARE_WAITQUEUE(wait, tsk); - int valid; - - /* - * We could run as a real-time thread. However, thus far - * this doesn't seem to be necessary. - */ -// tsk->policy = SCHED_FIFO; -// tsk->rt_priority = 1; - - valid = 0; + int valid = 0; add_wait_queue(&ts->irq_wait, &wait); while (!kthread_should_stop()) { diff --git a/drivers/net/usb/cdc_ether.c b/drivers/net/usb/cdc_ether.c index 5a21f06bf8a5..675ac99a79c6 100644 --- a/drivers/net/usb/cdc_ether.c +++ b/drivers/net/usb/cdc_ether.c @@ -91,6 +91,22 @@ int usbnet_generic_cdc_bind(struct usbnet *dev, struct usb_interface *intf) "CDC descriptors on config\n"); } + /* Maybe CDC descriptors are after the endpoint? This bug has + * been seen on some 2Wire Inc RNDIS-ish products. + */ + if (len == 0) { + struct usb_host_endpoint *hep; + + hep = intf->cur_altsetting->endpoint; + if (hep) { + buf = hep->extra; + len = hep->extralen; + } + if (len) + dev_dbg(&intf->dev, + "CDC descriptors on endpoint\n"); + } + /* this assumes that if there's a non-RNDIS vendor variant * of cdc-acm, it'll fail RNDIS requests cleanly. */ diff --git a/drivers/net/usb/rndis_host.c b/drivers/net/usb/rndis_host.c index 980e4aaa97aa..cd991a0f75bb 100644 --- a/drivers/net/usb/rndis_host.c +++ b/drivers/net/usb/rndis_host.c @@ -515,6 +515,7 @@ static int rndis_bind(struct usbnet *dev, struct usb_interface *intf) dev_err(&intf->dev, "dev can't take %u byte packets (max %u)\n", dev->hard_mtu, tmp); + retval = -EINVAL; goto fail_and_release; } diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c index f9cd42d058b0..5b16d9a1269a 100644 --- a/drivers/net/usb/usbnet.c +++ b/drivers/net/usb/usbnet.c @@ -1252,20 +1252,23 @@ EXPORT_SYMBOL_GPL(usbnet_probe); /*-------------------------------------------------------------------------*/ -/* FIXME these suspend/resume methods assume non-CDC style - * devices, with only one interface. +/* + * suspend the whole driver as soon as the first interface is suspended + * resume only when the last interface is resumed */ int usbnet_suspend (struct usb_interface *intf, pm_message_t message) { struct usbnet *dev = usb_get_intfdata(intf); - /* accelerate emptying of the rx and queues, to avoid - * having everything error out. - */ - netif_device_detach (dev->net); - (void) unlink_urbs (dev, &dev->rxq); - (void) unlink_urbs (dev, &dev->txq); + if (!dev->suspend_count++) { + /* accelerate emptying of the rx and queues, to avoid + * having everything error out. + */ + netif_device_detach (dev->net); + (void) unlink_urbs (dev, &dev->rxq); + (void) unlink_urbs (dev, &dev->txq); + } return 0; } EXPORT_SYMBOL_GPL(usbnet_suspend); @@ -1274,8 +1277,10 @@ int usbnet_resume (struct usb_interface *intf) { struct usbnet *dev = usb_get_intfdata(intf); - netif_device_attach (dev->net); - tasklet_schedule (&dev->bh); + if (!--dev->suspend_count) { + netif_device_attach (dev->net); + tasklet_schedule (&dev->bh); + } return 0; } EXPORT_SYMBOL_GPL(usbnet_resume); diff --git a/drivers/net/usb/usbnet.h b/drivers/net/usb/usbnet.h index 82db5a8e528e..a3f8b9e7bc00 100644 --- a/drivers/net/usb/usbnet.h +++ b/drivers/net/usb/usbnet.h @@ -32,6 +32,7 @@ struct usbnet { const char *driver_name; wait_queue_head_t *wait; struct mutex phy_mutex; + unsigned char suspend_count; /* i/o info: pipes etc */ unsigned in, out; diff --git a/drivers/usb/class/usblp.c b/drivers/usb/class/usblp.c index 15e740e3a5c4..7b1edfe46b28 100644 --- a/drivers/usb/class/usblp.c +++ b/drivers/usb/class/usblp.c @@ -1003,7 +1003,7 @@ abort: usblp->writebuf, usblp->writeurb->transfer_dma); if (usblp->readbuf) usb_buffer_free (usblp->dev, USBLP_BUF_SIZE, - usblp->readbuf, usblp->writeurb->transfer_dma); + usblp->readbuf, usblp->readurb->transfer_dma); kfree(usblp->statusbuf); kfree(usblp->device_id_string); usb_free_urb(usblp->writeurb); diff --git a/drivers/usb/core/config.c b/drivers/usb/core/config.c index bfb3731d42db..2d4fd530e5e4 100644 --- a/drivers/usb/core/config.c +++ b/drivers/usb/core/config.c @@ -185,10 +185,12 @@ static int usb_parse_interface(struct device *ddev, int cfgno, num_ep = USB_MAXENDPOINTS; } - len = sizeof(struct usb_host_endpoint) * num_ep; - alt->endpoint = kzalloc(len, GFP_KERNEL); - if (!alt->endpoint) - return -ENOMEM; + if (num_ep > 0) { /* Can't allocate 0 bytes */ + len = sizeof(struct usb_host_endpoint) * num_ep; + alt->endpoint = kzalloc(len, GFP_KERNEL); + if (!alt->endpoint) + return -ENOMEM; + } /* Parse all the endpoint descriptors */ n = 0; diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c index b9f7f90aef82..2619986e5300 100644 --- a/drivers/usb/core/driver.c +++ b/drivers/usb/core/driver.c @@ -983,7 +983,10 @@ static int autosuspend_check(struct usb_device *udev) #else -#define autosuspend_check(udev) 0 +static inline int autosuspend_check(struct usb_device *udev) +{ + return 0; +} #endif /* CONFIG_USB_SUSPEND */ @@ -1041,7 +1044,6 @@ static int usb_suspend_both(struct usb_device *udev, pm_message_t msg) if (status < 0) goto done; } - cancel_delayed_work(&udev->autosuspend); /* Suspend all the interfaces and then udev itself */ if (udev->actconfig) { @@ -1062,9 +1064,16 @@ static int usb_suspend_both(struct usb_device *udev, pm_message_t msg) usb_resume_interface(intf); } + /* Try another autosuspend when the interfaces aren't busy */ + if (udev->auto_pm) + autosuspend_check(udev); + /* If the suspend succeeded, propagate it up the tree */ - } else if (parent) - usb_autosuspend_device(parent); + } else { + cancel_delayed_work(&udev->autosuspend); + if (parent) + usb_autosuspend_device(parent); + } done: // dev_dbg(&udev->dev, "%s: status %d\n", __FUNCTION__, status); @@ -1475,6 +1484,7 @@ int usb_external_resume_device(struct usb_device *udev) usb_pm_lock(udev); udev->auto_pm = 0; status = usb_resume_both(udev); + udev->last_busy = jiffies; usb_pm_unlock(udev); /* Now that the device is awake, we can start trying to autosuspend diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index 40cf882293e6..e277258df382 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c @@ -1018,8 +1018,8 @@ done: atomic_dec (&urb->use_count); if (urb->reject) wake_up (&usb_kill_urb_queue); - usb_put_urb (urb); usbmon_urb_submit_error(&hcd->self, urb, status); + usb_put_urb (urb); } return status; } @@ -1175,10 +1175,6 @@ void usb_hcd_endpoint_disable (struct usb_device *udev, struct urb *urb; hcd = bus_to_hcd(udev->bus); - - WARN_ON (!HC_IS_RUNNING (hcd->state) && hcd->state != HC_STATE_HALT && - udev->state != USB_STATE_NOTATTACHED); - local_irq_disable (); /* ep is already gone from udev->ep_{in,out}[]; no more submits */ diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index f6b74a678de5..caaa46f2dec7 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -2201,14 +2201,9 @@ hub_port_init (struct usb_hub *hub, struct usb_device *udev, int port1, continue; } - /* Use a short timeout the first time through, - * so that recalcitrant full-speed devices with - * 8- or 16-byte ep0-maxpackets won't slow things - * down tremendously by NAKing the unexpectedly - * early status stage. Also, retry on all errors; - * some devices are flakey. - * 255 is for WUSB devices, we actually need to use 512. - * WUSB1.0[4.8.1]. + /* Retry on all errors; some devices are flakey. + * 255 is for WUSB devices, we actually need to use + * 512 (WUSB1.0[4.8.1]). */ for (j = 0; j < 3; ++j) { buf->bMaxPacketSize0 = 0; @@ -2216,7 +2211,7 @@ hub_port_init (struct usb_hub *hub, struct usb_device *udev, int port1, USB_REQ_GET_DESCRIPTOR, USB_DIR_IN, USB_DT_DEVICE << 8, 0, buf, GET_DESCRIPTOR_BUFSIZE, - (i ? USB_CTRL_GET_TIMEOUT : 1000)); + USB_CTRL_GET_TIMEOUT); switch (buf->bMaxPacketSize0) { case 8: case 16: case 32: case 64: case 255: if (buf->bDescriptorType == @@ -2426,10 +2421,10 @@ static void hub_port_connect_change(struct usb_hub *hub, int port1, if (portchange & USB_PORT_STAT_C_CONNECTION) { status = hub_port_debounce(hub, port1); - if (status < 0 && printk_ratelimit()) { - dev_err (hub_dev, - "connect-debounce failed, port %d disabled\n", - port1); + if (status < 0) { + if (printk_ratelimit()) + dev_err (hub_dev, "connect-debounce failed, " + "port %d disabled\n", port1); goto done; } portstatus = status; diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c index b7434787db5f..f9fed34bf7d8 100644 --- a/drivers/usb/core/message.c +++ b/drivers/usb/core/message.c @@ -221,15 +221,10 @@ int usb_bulk_msg(struct usb_device *usb_dev, unsigned int pipe, if ((ep->desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_INT) { - int interval; - - if (usb_dev->speed == USB_SPEED_HIGH) - interval = 1 << min(15, ep->desc.bInterval - 1); - else - interval = ep->desc.bInterval; pipe = (pipe & ~(3 << 30)) | (PIPE_INTERRUPT << 30); usb_fill_int_urb(urb, usb_dev, pipe, data, len, - usb_api_blocking_completion, NULL, interval); + usb_api_blocking_completion, NULL, + ep->desc.bInterval); } else usb_fill_bulk_urb(urb, usb_dev, pipe, data, len, usb_api_blocking_completion, NULL); diff --git a/drivers/usb/core/sysfs.c b/drivers/usb/core/sysfs.c index e7c982377488..be37c863fdfb 100644 --- a/drivers/usb/core/sysfs.c +++ b/drivers/usb/core/sysfs.c @@ -232,12 +232,15 @@ set_level(struct device *dev, struct device_attribute *attr, int len = count; char *cp; int rc = 0; + int old_autosuspend_disabled, old_autoresume_disabled; cp = memchr(buf, '\n', count); if (cp) len = cp - buf; usb_lock_device(udev); + old_autosuspend_disabled = udev->autosuspend_disabled; + old_autoresume_disabled = udev->autoresume_disabled; /* Setting the flags without calling usb_pm_lock is a subject to * races, but who cares... @@ -263,6 +266,10 @@ set_level(struct device *dev, struct device_attribute *attr, } else rc = -EINVAL; + if (rc) { + udev->autosuspend_disabled = old_autosuspend_disabled; + udev->autoresume_disabled = old_autoresume_disabled; + } usb_unlock_device(udev); return (rc < 0 ? rc : count); } diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c index 18ddc5e67e39..80627b6a2bf9 100644 --- a/drivers/usb/core/usb.c +++ b/drivers/usb/core/usb.c @@ -205,7 +205,11 @@ struct device_type usb_device_type = { static int ksuspend_usb_init(void) { - ksuspend_usb_wq = create_singlethread_workqueue("ksuspend_usbd"); + /* This workqueue is supposed to be both freezable and + * singlethreaded. Its job doesn't justify running on more + * than one CPU. + */ + ksuspend_usb_wq = create_freezeable_workqueue("ksuspend_usbd"); if (!ksuspend_usb_wq) return -ENOMEM; return 0; diff --git a/drivers/usb/gadget/fsl_usb2_udc.c b/drivers/usb/gadget/fsl_usb2_udc.c index 157054ea3978..3ca2b3159f00 100644 --- a/drivers/usb/gadget/fsl_usb2_udc.c +++ b/drivers/usb/gadget/fsl_usb2_udc.c @@ -228,13 +228,15 @@ static int dr_controller_setup(struct fsl_udc *udc) /* Config PHY interface */ portctrl = fsl_readl(&dr_regs->portsc1); - portctrl &= ~PORTSCX_PHY_TYPE_SEL; + portctrl &= ~(PORTSCX_PHY_TYPE_SEL & PORTSCX_PORT_WIDTH); switch (udc->phy_mode) { case FSL_USB2_PHY_ULPI: portctrl |= PORTSCX_PTS_ULPI; break; - case FSL_USB2_PHY_UTMI: case FSL_USB2_PHY_UTMI_WIDE: + portctrl |= PORTSCX_PTW_16BIT; + /* fall through */ + case FSL_USB2_PHY_UTMI: portctrl |= PORTSCX_PTS_UTMI; break; case FSL_USB2_PHY_SERIAL: @@ -625,7 +627,7 @@ static void fsl_free_buffer(struct usb_ep *_ep, void *buf, struct fsl_ep *ep; if (!_ep) - return NULL; + return; ep = container_of(_ep, struct fsl_ep, ep); diff --git a/drivers/usb/host/ohci-pci.c b/drivers/usb/host/ohci-pci.c index 79705609fd0c..ca62cb583221 100644 --- a/drivers/usb/host/ohci-pci.c +++ b/drivers/usb/host/ohci-pci.c @@ -137,7 +137,7 @@ static const struct pci_device_id ohci_pci_quirks[] = { /* Toshiba portege 4000 */ .vendor = PCI_VENDOR_ID_AL, .device = 0x5237, - .subvendor = PCI_VENDOR_ID_TOSHIBA_2, + .subvendor = PCI_VENDOR_ID_TOSHIBA, .subdevice = 0x0004, .driver_data = (unsigned long) broken_suspend, }, diff --git a/drivers/usb/host/pci-quirks.c b/drivers/usb/host/pci-quirks.c index 20861650905e..c225159ca3d3 100644 --- a/drivers/usb/host/pci-quirks.c +++ b/drivers/usb/host/pci-quirks.c @@ -44,6 +44,7 @@ #define EHCI_USBSTS 4 /* status register */ #define EHCI_USBSTS_HALTED (1 << 12) /* HCHalted bit */ #define EHCI_USBINTR 8 /* interrupt register */ +#define EHCI_CONFIGFLAG 0x40 /* configured flag register */ #define EHCI_USBLEGSUP 0 /* legacy support register */ #define EHCI_USBLEGSUP_BIOS (1 << 16) /* BIOS semaphore */ #define EHCI_USBLEGSUP_OS (1 << 24) /* OS semaphore */ @@ -216,6 +217,7 @@ static void __devinit quirk_usb_disable_ehci(struct pci_dev *pdev) u32 hcc_params, val; u8 offset, cap_length; int count = 256/4; + int tried_handoff = 0; if (!mmio_resource_enabled(pdev, 0)) return; @@ -273,6 +275,7 @@ static void __devinit quirk_usb_disable_ehci(struct pci_dev *pdev) */ msec = 5000; while ((cap & EHCI_USBLEGSUP_BIOS) && (msec > 0)) { + tried_handoff = 1; msleep(10); msec -= 10; pci_read_config_dword(pdev, offset, &cap); @@ -292,6 +295,12 @@ static void __devinit quirk_usb_disable_ehci(struct pci_dev *pdev) pci_write_config_dword(pdev, offset + EHCI_USBLEGCTLSTS, 0); + + /* If the BIOS ever owned the controller then we + * can't expect any power sessions to remain intact. + */ + if (tried_handoff) + writel(0, op_reg_base + EHCI_CONFIGFLAG); break; case 0: /* illegal reserved capability */ cap = 0; diff --git a/drivers/usb/host/u132-hcd.c b/drivers/usb/host/u132-hcd.c index ff0dba01f1c7..e98df2ee9901 100644 --- a/drivers/usb/host/u132-hcd.c +++ b/drivers/usb/host/u132-hcd.c @@ -57,6 +57,13 @@ #include <asm/system.h> #include <asm/byteorder.h> #include "../core/hcd.h" + + /* FIXME ohci.h is ONLY for internal use by the OHCI driver. + * If you're going to try stuff like this, you need to split + * out shareable stuff (register declarations?) into its own + * file, maybe name <linux/usb/ohci.h> + */ + #include "ohci.h" #define OHCI_CONTROL_INIT OHCI_CTRL_CBSR #define OHCI_INTR_INIT (OHCI_INTR_MIE | OHCI_INTR_UE | OHCI_INTR_RD | \ @@ -173,11 +180,6 @@ struct u132_ring { struct u132_endp *curr_endp; struct delayed_work scheduler; }; -#define OHCI_QUIRK_AMD756 0x01 -#define OHCI_QUIRK_SUPERIO 0x02 -#define OHCI_QUIRK_INITRESET 0x04 -#define OHCI_BIG_ENDIAN 0x08 -#define OHCI_QUIRK_ZFMICRO 0x10 struct u132 { struct kref kref; struct list_head u132_list; diff --git a/drivers/usb/misc/auerswald.c b/drivers/usb/misc/auerswald.c index 88fb56d5db8f..cac1500cba62 100644 --- a/drivers/usb/misc/auerswald.c +++ b/drivers/usb/misc/auerswald.c @@ -1822,16 +1822,10 @@ static int auerchar_release (struct inode *inode, struct file *file) pauerswald_t cp; dbg("release"); - /* get the mutexes */ - if (down_interruptible (&ccp->mutex)) { - return -ERESTARTSYS; - } + down(&ccp->mutex); cp = ccp->auerdev; if (cp) { - if (down_interruptible (&cp->mutex)) { - up (&ccp->mutex); - return -ERESTARTSYS; - } + down(&cp->mutex); /* remove an open service */ auerswald_removeservice (cp, &ccp->scontext); /* detach from device */ diff --git a/drivers/usb/misc/ftdi-elan.c b/drivers/usb/misc/ftdi-elan.c index e2172e5cf152..e0f122e131d7 100644 --- a/drivers/usb/misc/ftdi-elan.c +++ b/drivers/usb/misc/ftdi-elan.c @@ -73,6 +73,13 @@ static struct list_head ftdi_static_list; #include "usb_u132.h" #include <asm/io.h> #include "../core/hcd.h" + + /* FIXME ohci.h is ONLY for internal use by the OHCI driver. + * If you're going to try stuff like this, you need to split + * out shareable stuff (register declarations?) into its own + * file, maybe name <linux/usb/ohci.h> + */ + #include "../host/ohci.h" /* Define these values to match your devices*/ #define USB_FTDI_ELAN_VENDOR_ID 0x0403 @@ -2300,10 +2307,7 @@ static int ftdi_elan_checkingPCI(struct usb_ftdi *ftdi) offsetof(struct ohci_regs, member), 0, data); #define ftdi_write_pcimem(ftdi, member, data) ftdi_elan_write_pcimem(ftdi, \ offsetof(struct ohci_regs, member), 0, data); -#define OHCI_QUIRK_AMD756 0x01 -#define OHCI_QUIRK_SUPERIO 0x02 -#define OHCI_QUIRK_INITRESET 0x04 -#define OHCI_BIG_ENDIAN 0x08 + #define OHCI_CONTROL_INIT OHCI_CTRL_CBSR #define OHCI_INTR_INIT (OHCI_INTR_MIE | OHCI_INTR_UE | OHCI_INTR_RD | \ OHCI_INTR_WDH) diff --git a/drivers/usb/misc/ldusb.c b/drivers/usb/misc/ldusb.c index 11555bde655b..7bad49404762 100644 --- a/drivers/usb/misc/ldusb.c +++ b/drivers/usb/misc/ldusb.c @@ -165,6 +165,8 @@ struct ld_usb { size_t interrupt_in_endpoint_size; int interrupt_in_running; int interrupt_in_done; + int buffer_overflow; + spinlock_t rbsl; char* interrupt_out_buffer; struct usb_endpoint_descriptor* interrupt_out_endpoint; @@ -230,10 +232,12 @@ static void ld_usb_interrupt_in_callback(struct urb *urb) } else { dbg_info(&dev->intf->dev, "%s: nonzero status received: %d\n", __FUNCTION__, urb->status); + spin_lock(&dev->rbsl); goto resubmit; /* maybe we can recover */ } } + spin_lock(&dev->rbsl); if (urb->actual_length > 0) { next_ring_head = (dev->ring_head+1) % ring_buffer_size; if (next_ring_head != dev->ring_tail) { @@ -244,21 +248,25 @@ static void ld_usb_interrupt_in_callback(struct urb *urb) dev->ring_head = next_ring_head; dbg_info(&dev->intf->dev, "%s: received %d bytes\n", __FUNCTION__, urb->actual_length); - } else + } else { dev_warn(&dev->intf->dev, "Ring buffer overflow, %d bytes dropped\n", urb->actual_length); + dev->buffer_overflow = 1; + } } resubmit: /* resubmit if we're still running */ - if (dev->interrupt_in_running && dev->intf) { + if (dev->interrupt_in_running && !dev->buffer_overflow && dev->intf) { retval = usb_submit_urb(dev->interrupt_in_urb, GFP_ATOMIC); - if (retval) + if (retval) { dev_err(&dev->intf->dev, "usb_submit_urb failed (%d)\n", retval); + dev->buffer_overflow = 1; + } } - + spin_unlock(&dev->rbsl); exit: dev->interrupt_in_done = 1; wake_up_interruptible(&dev->read_wait); @@ -330,6 +338,7 @@ static int ld_usb_open(struct inode *inode, struct file *file) /* initialize in direction */ dev->ring_head = 0; dev->ring_tail = 0; + dev->buffer_overflow = 0; usb_fill_int_urb(dev->interrupt_in_urb, interface_to_usbdev(interface), usb_rcvintpipe(interface_to_usbdev(interface), @@ -439,6 +448,7 @@ static ssize_t ld_usb_read(struct file *file, char __user *buffer, size_t count, size_t *actual_buffer; size_t bytes_to_read; int retval = 0; + int rv; dev = file->private_data; @@ -460,7 +470,10 @@ static ssize_t ld_usb_read(struct file *file, char __user *buffer, size_t count, } /* wait for data */ + spin_lock_irq(&dev->rbsl); if (dev->ring_head == dev->ring_tail) { + dev->interrupt_in_done = 0; + spin_unlock_irq(&dev->rbsl); if (file->f_flags & O_NONBLOCK) { retval = -EAGAIN; goto unlock_exit; @@ -468,6 +481,8 @@ static ssize_t ld_usb_read(struct file *file, char __user *buffer, size_t count, retval = wait_event_interruptible(dev->read_wait, dev->interrupt_in_done); if (retval < 0) goto unlock_exit; + } else { + spin_unlock_irq(&dev->rbsl); } /* actual_buffer contains actual_length + interrupt_in_buffer */ @@ -486,6 +501,17 @@ static ssize_t ld_usb_read(struct file *file, char __user *buffer, size_t count, retval = bytes_to_read; + spin_lock_irq(&dev->rbsl); + if (dev->buffer_overflow) { + dev->buffer_overflow = 0; + spin_unlock_irq(&dev->rbsl); + rv = usb_submit_urb(dev->interrupt_in_urb, GFP_KERNEL); + if (rv < 0) + dev->buffer_overflow = 1; + } else { + spin_unlock_irq(&dev->rbsl); + } + unlock_exit: /* unlock the device */ up(&dev->sem); @@ -635,6 +661,7 @@ static int ld_usb_probe(struct usb_interface *intf, const struct usb_device_id * goto exit; } init_MUTEX(&dev->sem); + spin_lock_init(&dev->rbsl); dev->intf = intf; init_waitqueue_head(&dev->read_wait); init_waitqueue_head(&dev->write_wait); diff --git a/drivers/usb/serial/ark3116.c b/drivers/usb/serial/ark3116.c index ea2175bb2274..fe437125f14b 100644 --- a/drivers/usb/serial/ark3116.c +++ b/drivers/usb/serial/ark3116.c @@ -63,7 +63,8 @@ static inline void ARK3116_RCV(struct usb_serial *serial, int seq, request, requesttype, value, index, buf, 0x0000001, 1000); if (result) - dbg("%03d < %d bytes [0x%02X]", seq, result, buf[0]); + dbg("%03d < %d bytes [0x%02X]", seq, result, + ((unsigned char *)buf)[0]); else dbg("%03d < 0 bytes", seq); } diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index 95a1805b064f..2353679f601e 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c @@ -273,12 +273,18 @@ static __u16 product; /* struct ftdi_sio_quirk is used by devices requiring special attention. */ struct ftdi_sio_quirk { + int (*probe)(struct usb_serial *); void (*setup)(struct usb_serial *); /* Special settings during startup. */ }; +static int ftdi_olimex_probe (struct usb_serial *serial); static void ftdi_USB_UIRT_setup (struct usb_serial *serial); static void ftdi_HE_TIRA1_setup (struct usb_serial *serial); +static struct ftdi_sio_quirk ftdi_olimex_quirk = { + .probe = ftdi_olimex_probe, +}; + static struct ftdi_sio_quirk ftdi_USB_UIRT_quirk = { .setup = ftdi_USB_UIRT_setup, }; @@ -319,6 +325,7 @@ static struct usb_device_id id_table_combined [] = { { USB_DEVICE(FTDI_VID, FTDI_8U2232C_PID) }, { USB_DEVICE(FTDI_VID, FTDI_MICRO_CHAMELEON_PID) }, { USB_DEVICE(FTDI_VID, FTDI_RELAIS_PID) }, + { USB_DEVICE(FTDI_VID, FTDI_OPENDCC_PID) }, { USB_DEVICE(INTERBIOMETRICS_VID, INTERBIOMETRICS_IOBOARD_PID) }, { USB_DEVICE(INTERBIOMETRICS_VID, INTERBIOMETRICS_MINI_IOBOARD_PID) }, { USB_DEVICE(FTDI_VID, FTDI_XF_632_PID) }, @@ -525,6 +532,9 @@ static struct usb_device_id id_table_combined [] = { { USB_DEVICE(FTDI_VID, FTDI_TACTRIX_OPENPORT_13U_PID) }, { USB_DEVICE(ELEKTOR_VID, ELEKTOR_FT323R_PID) }, { USB_DEVICE(TELLDUS_VID, TELLDUS_TELLSTICK_PID) }, + { USB_DEVICE(FTDI_VID, FTDI_MAXSTREAM_PID) }, + { USB_DEVICE(OLIMEX_VID, OLIMEX_ARM_USB_OCD_PID), + .driver_info = (kernel_ulong_t)&ftdi_olimex_quirk }, { }, /* Optional parameter entry */ { } /* Terminating entry */ }; @@ -669,7 +679,7 @@ static struct usb_serial_driver ftdi_sio_device = { /* * *************************************************************************** - * Utlity functions + * Utility functions * *************************************************************************** */ @@ -1171,9 +1181,17 @@ static void remove_sysfs_attrs(struct usb_serial_port *port) /* Probe function to check for special devices */ static int ftdi_sio_probe (struct usb_serial *serial, const struct usb_device_id *id) { + struct ftdi_sio_quirk *quirk = (struct ftdi_sio_quirk *)id->driver_info; + + if (quirk && quirk->probe) { + int ret = quirk->probe(serial); + if (ret != 0) + return ret; + } + usb_set_serial_data(serial, (void *)id->driver_info); - return (0); + return 0; } static int ftdi_sio_port_probe(struct usb_serial_port *port) @@ -1268,6 +1286,24 @@ static void ftdi_HE_TIRA1_setup (struct usb_serial *serial) priv->force_rtscts = 1; } /* ftdi_HE_TIRA1_setup */ +/* + * First port on Olimex arm-usb-ocd is reserved for JTAG interface + * and can be accessed from userspace using openocd. + */ +static int ftdi_olimex_probe(struct usb_serial *serial) +{ + struct usb_device *udev = serial->dev; + struct usb_interface *interface = serial->interface; + + dbg("%s",__FUNCTION__); + + if (interface == udev->actconfig->interface[0]) { + info("Ignoring reserved serial port on Olimex arm-usb-ocd\n"); + return -ENODEV; + } + + return 0; +} /* ftdi_shutdown is called from usbserial:usb_serial_disconnect * it is called when the usb device is disconnected diff --git a/drivers/usb/serial/ftdi_sio.h b/drivers/usb/serial/ftdi_sio.h index 77ad0a09b384..33aee9047242 100644 --- a/drivers/usb/serial/ftdi_sio.h +++ b/drivers/usb/serial/ftdi_sio.h @@ -60,6 +60,9 @@ /* DMX4ALL DMX Interfaces */ #define FTDI_DMX4ALL 0xC850 +/* OpenDCC (www.opendcc.de) product id */ +#define FTDI_OPENDCC_PID 0xBFD8 + /* www.crystalfontz.com devices - thanx for providing free devices for evaluation ! */ /* they use the ftdi chipset for the USB interface and the vendor id is the same */ #define FTDI_XF_632_PID 0xFC08 /* 632: 16x2 Character Display */ @@ -518,6 +521,15 @@ #define FTDI_IBS_PEDO_PID 0xff3e /* IBS PEDO-Modem (RF modem 868.35 MHz) */ #define FTDI_IBS_PROD_PID 0xff3f /* future device */ +/* + * MaxStream devices www.maxstream.net + */ +#define FTDI_MAXSTREAM_PID 0xEE18 /* Xbee PKG-U Module */ + +/* Olimex */ +#define OLIMEX_VID 0x15BA +#define OLIMEX_ARM_USB_OCD_PID 0x0003 + /* Commands */ #define FTDI_SIO_RESET 0 /* Reset the port */ #define FTDI_SIO_MODEM_CTRL 1 /* Set the modem control register */ diff --git a/drivers/usb/serial/mos7840.c b/drivers/usb/serial/mos7840.c index 2366e7b63ece..36620c651079 100644 --- a/drivers/usb/serial/mos7840.c +++ b/drivers/usb/serial/mos7840.c @@ -769,11 +769,6 @@ static void mos7840_bulk_out_data_callback(struct urb *urb) return; } - if (!mos7840_port) { - dbg("%s", "NULL mos7840_port pointer \n"); - return; - } - if (mos7840_port_paranoia_check(mos7840_port->port, __FUNCTION__)) { dbg("%s", "Port Paranoia failed \n"); return; diff --git a/drivers/usb/serial/omninet.c b/drivers/usb/serial/omninet.c index 4adfab988e86..00afc1712c39 100644 --- a/drivers/usb/serial/omninet.c +++ b/drivers/usb/serial/omninet.c @@ -165,12 +165,10 @@ static int omninet_open (struct usb_serial_port *port, struct file *filp) { struct usb_serial *serial = port->serial; struct usb_serial_port *wport; - struct omninet_data *od = usb_get_serial_port_data(port); int result = 0; dbg("%s - port %d", __FUNCTION__, port->number); - od = kmalloc( sizeof(struct omninet_data), GFP_KERNEL ); wport = serial->port[1]; wport->tty = port->tty; diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index 8c3f55b080b4..89f067d95076 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c @@ -165,7 +165,6 @@ static struct usb_device_id option_ids[] = { { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, 0x1410) }, /* Novatel U740 */ { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, 0x1420) }, /* Novatel EU870 */ { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, 0x1430) }, /* Novatel Merlin XU870 HSDPA/3G */ - { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, 0x1430) }, /* Novatel XU870 */ { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, 0x2100) }, /* Novatel EV620 CDMA/EV-DO */ { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, 0x2110) }, /* Novatel Merlin ES620 / Merlin ES720 / Ovation U720 */ { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, 0x2130) }, /* Novatel Merlin ES620 SM Bus */ diff --git a/drivers/usb/serial/sierra.c b/drivers/usb/serial/sierra.c index 644607de4c11..ac1829c6e8f0 100644 --- a/drivers/usb/serial/sierra.c +++ b/drivers/usb/serial/sierra.c @@ -35,6 +35,7 @@ static struct usb_device_id id_table [] = { { USB_DEVICE(0x1199, 0x0218) }, /* Sierra Wireless MC5720 */ { USB_DEVICE(0x1199, 0x0020) }, /* Sierra Wireless MC5725 */ { USB_DEVICE(0x1199, 0x0019) }, /* Sierra Wireless AirCard 595 */ + { USB_DEVICE(0x1199, 0x0120) }, /* Sierra Wireless AirCard 595U */ { USB_DEVICE(0x1199, 0x0021) }, /* Sierra Wireless AirCard 597E */ { USB_DEVICE(0x1199, 0x6802) }, /* Sierra Wireless MC8755 */ { USB_DEVICE(0x1199, 0x6804) }, /* Sierra Wireless MC8755 */ @@ -60,6 +61,7 @@ static struct usb_device_id id_table_3port [] = { { USB_DEVICE(0x1199, 0x0218) }, /* Sierra Wireless MC5720 */ { USB_DEVICE(0x1199, 0x0020) }, /* Sierra Wireless MC5725 */ { USB_DEVICE(0x1199, 0x0019) }, /* Sierra Wireless AirCard 595 */ + { USB_DEVICE(0x1199, 0x0120) }, /* Sierra Wireless AirCard 595U */ { USB_DEVICE(0x1199, 0x0021) }, /* Sierra Wireless AirCard 597E */ { USB_DEVICE(0x1199, 0x6802) }, /* Sierra Wireless MC8755 */ { USB_DEVICE(0x1199, 0x6804) }, /* Sierra Wireless MC8755 */ diff --git a/drivers/usb/storage/onetouch.c b/drivers/usb/storage/onetouch.c index 6d3dad3d1dae..d35369392fed 100644 --- a/drivers/usb/storage/onetouch.c +++ b/drivers/usb/storage/onetouch.c @@ -84,7 +84,7 @@ resubmit: static int usb_onetouch_open(struct input_dev *dev) { - struct usb_onetouch *onetouch = dev->private; + struct usb_onetouch *onetouch = input_get_drvdata(dev); onetouch->is_open = 1; onetouch->irq->dev = onetouch->udev; @@ -98,7 +98,7 @@ static int usb_onetouch_open(struct input_dev *dev) static void usb_onetouch_close(struct input_dev *dev) { - struct usb_onetouch *onetouch = dev->private; + struct usb_onetouch *onetouch = input_get_drvdata(dev); usb_kill_urb(onetouch->irq); onetouch->is_open = 0; @@ -185,13 +185,14 @@ int onetouch_connect_input(struct us_data *ss) input_dev->name = onetouch->name; input_dev->phys = onetouch->phys; usb_to_input_id(udev, &input_dev->id); - input_dev->cdev.dev = &udev->dev; + input_dev->dev.parent = &udev->dev; set_bit(EV_KEY, input_dev->evbit); set_bit(ONETOUCH_BUTTON, input_dev->keybit); clear_bit(0, input_dev->keybit); - input_dev->private = onetouch; + input_set_drvdata(input_dev, onetouch); + input_dev->open = usb_onetouch_open; input_dev->close = usb_onetouch_close; diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h index 8b3145ab7757..d230ee72f9cd 100644 --- a/drivers/usb/storage/unusual_devs.h +++ b/drivers/usb/storage/unusual_devs.h @@ -1179,14 +1179,20 @@ UNUSUAL_DEV( 0x0a17, 0x006, 0x0000, 0xffff, US_SC_DEVICE, US_PR_DEVICE, NULL, US_FL_FIX_INQUIRY ), -/* This is a virtual windows driver CD, which the zd1211rw driver automatically - * converts into a WLAN device. */ +/* These are virtual windows driver CDs, which the zd1211rw driver automatically + * converts into a WLAN devices. */ UNUSUAL_DEV( 0x0ace, 0x2011, 0x0101, 0x0101, "ZyXEL", "G-220F USB-WLAN Install", US_SC_DEVICE, US_PR_DEVICE, NULL, US_FL_IGNORE_DEVICE ), +UNUSUAL_DEV( 0x0ace, 0x20ff, 0x0101, 0x0101, + "SiteCom", + "WL-117 USB-WLAN Install", + US_SC_DEVICE, US_PR_DEVICE, NULL, + US_FL_IGNORE_DEVICE ), + #ifdef CONFIG_USB_STORAGE_ISD200 UNUSUAL_DEV( 0x0bf6, 0xa001, 0x0100, 0x0110, "ATI", |