diff options
Diffstat (limited to 'drivers/media/video')
-rw-r--r-- | drivers/media/video/bt8xx/bttv-input.c | 101 | ||||
-rw-r--r-- | drivers/media/video/cx88/cx88-input.c | 77 | ||||
-rw-r--r-- | drivers/media/video/ir-kbd-i2c.c | 43 | ||||
-rw-r--r-- | drivers/media/video/saa7134/saa7134-input.c | 48 | ||||
-rw-r--r-- | drivers/media/video/usbvideo/quickcam_messenger.c | 9 |
5 files changed, 172 insertions, 106 deletions
diff --git a/drivers/media/video/bt8xx/bttv-input.c b/drivers/media/video/bt8xx/bttv-input.c index 933d6db09acb..cbc012f71f52 100644 --- a/drivers/media/video/bt8xx/bttv-input.c +++ b/drivers/media/video/bt8xx/bttv-input.c | |||
@@ -259,24 +259,59 @@ static void bttv_rc5_timer_keyup(unsigned long data) | |||
259 | 259 | ||
260 | /* ---------------------------------------------------------------------- */ | 260 | /* ---------------------------------------------------------------------- */ |
261 | 261 | ||
262 | static void bttv_ir_start(struct bttv *btv, struct bttv_ir *ir) | ||
263 | { | ||
264 | if (ir->polling) { | ||
265 | init_timer(&ir->timer); | ||
266 | ir->timer.function = bttv_input_timer; | ||
267 | ir->timer.data = (unsigned long)btv; | ||
268 | ir->timer.expires = jiffies + HZ; | ||
269 | add_timer(&ir->timer); | ||
270 | } else if (ir->rc5_gpio) { | ||
271 | /* set timer_end for code completion */ | ||
272 | init_timer(&ir->timer_end); | ||
273 | ir->timer_end.function = bttv_rc5_timer_end; | ||
274 | ir->timer_end.data = (unsigned long)ir; | ||
275 | |||
276 | init_timer(&ir->timer_keyup); | ||
277 | ir->timer_keyup.function = bttv_rc5_timer_keyup; | ||
278 | ir->timer_keyup.data = (unsigned long)ir; | ||
279 | } | ||
280 | } | ||
281 | |||
282 | static void bttv_ir_stop(struct bttv *btv) | ||
283 | { | ||
284 | if (btv->remote->polling) { | ||
285 | del_timer_sync(&btv->remote->timer); | ||
286 | flush_scheduled_work(); | ||
287 | } | ||
288 | |||
289 | if (btv->remote->rc5_gpio) { | ||
290 | u32 gpio; | ||
291 | |||
292 | del_timer_sync(&btv->remote->timer_end); | ||
293 | flush_scheduled_work(); | ||
294 | |||
295 | gpio = bttv_gpio_read(&btv->c); | ||
296 | bttv_gpio_write(&btv->c, gpio & ~(1 << 4)); | ||
297 | } | ||
298 | } | ||
299 | |||
262 | int bttv_input_init(struct bttv *btv) | 300 | int bttv_input_init(struct bttv *btv) |
263 | { | 301 | { |
264 | struct bttv_ir *ir; | 302 | struct bttv_ir *ir; |
265 | IR_KEYTAB_TYPE *ir_codes = NULL; | 303 | IR_KEYTAB_TYPE *ir_codes = NULL; |
266 | struct input_dev *input_dev; | 304 | struct input_dev *input_dev; |
267 | int ir_type = IR_TYPE_OTHER; | 305 | int ir_type = IR_TYPE_OTHER; |
306 | int err = -ENOMEM; | ||
268 | 307 | ||
269 | if (!btv->has_remote) | 308 | if (!btv->has_remote) |
270 | return -ENODEV; | 309 | return -ENODEV; |
271 | 310 | ||
272 | ir = kzalloc(sizeof(*ir),GFP_KERNEL); | 311 | ir = kzalloc(sizeof(*ir),GFP_KERNEL); |
273 | input_dev = input_allocate_device(); | 312 | input_dev = input_allocate_device(); |
274 | if (!ir || !input_dev) { | 313 | if (!ir || !input_dev) |
275 | kfree(ir); | 314 | goto err_out_free; |
276 | input_free_device(input_dev); | ||
277 | return -ENOMEM; | ||
278 | } | ||
279 | memset(ir,0,sizeof(*ir)); | ||
280 | 315 | ||
281 | /* detect & configure */ | 316 | /* detect & configure */ |
282 | switch (btv->c.type) { | 317 | switch (btv->c.type) { |
@@ -348,10 +383,9 @@ int bttv_input_init(struct bttv *btv) | |||
348 | break; | 383 | break; |
349 | } | 384 | } |
350 | if (NULL == ir_codes) { | 385 | if (NULL == ir_codes) { |
351 | dprintk(KERN_INFO "Ooops: IR config error [card=%d]\n",btv->c.type); | 386 | dprintk(KERN_INFO "Ooops: IR config error [card=%d]\n", btv->c.type); |
352 | kfree(ir); | 387 | err = -ENODEV; |
353 | input_free_device(input_dev); | 388 | goto err_out_free; |
354 | return -ENODEV; | ||
355 | } | 389 | } |
356 | 390 | ||
357 | if (ir->rc5_gpio) { | 391 | if (ir->rc5_gpio) { |
@@ -389,32 +423,26 @@ int bttv_input_init(struct bttv *btv) | |||
389 | input_dev->cdev.dev = &btv->c.pci->dev; | 423 | input_dev->cdev.dev = &btv->c.pci->dev; |
390 | 424 | ||
391 | btv->remote = ir; | 425 | btv->remote = ir; |
392 | if (ir->polling) { | 426 | bttv_ir_start(btv, ir); |
393 | init_timer(&ir->timer); | ||
394 | ir->timer.function = bttv_input_timer; | ||
395 | ir->timer.data = (unsigned long)btv; | ||
396 | ir->timer.expires = jiffies + HZ; | ||
397 | add_timer(&ir->timer); | ||
398 | } else if (ir->rc5_gpio) { | ||
399 | /* set timer_end for code completion */ | ||
400 | init_timer(&ir->timer_end); | ||
401 | ir->timer_end.function = bttv_rc5_timer_end; | ||
402 | ir->timer_end.data = (unsigned long)ir; | ||
403 | |||
404 | init_timer(&ir->timer_keyup); | ||
405 | ir->timer_keyup.function = bttv_rc5_timer_keyup; | ||
406 | ir->timer_keyup.data = (unsigned long)ir; | ||
407 | } | ||
408 | 427 | ||
409 | /* all done */ | 428 | /* all done */ |
410 | input_register_device(btv->remote->dev); | 429 | err = input_register_device(btv->remote->dev); |
411 | printk(DEVNAME ": %s detected at %s\n",ir->name,ir->phys); | 430 | if (err) |
431 | goto err_out_stop; | ||
412 | 432 | ||
413 | /* the remote isn't as bouncy as a keyboard */ | 433 | /* the remote isn't as bouncy as a keyboard */ |
414 | ir->dev->rep[REP_DELAY] = repeat_delay; | 434 | ir->dev->rep[REP_DELAY] = repeat_delay; |
415 | ir->dev->rep[REP_PERIOD] = repeat_period; | 435 | ir->dev->rep[REP_PERIOD] = repeat_period; |
416 | 436 | ||
417 | return 0; | 437 | return 0; |
438 | |||
439 | err_out_stop: | ||
440 | bttv_ir_stop(btv); | ||
441 | btv->remote = NULL; | ||
442 | err_out_free: | ||
443 | input_free_device(input_dev); | ||
444 | kfree(ir); | ||
445 | return err; | ||
418 | } | 446 | } |
419 | 447 | ||
420 | void bttv_input_fini(struct bttv *btv) | 448 | void bttv_input_fini(struct bttv *btv) |
@@ -422,22 +450,7 @@ void bttv_input_fini(struct bttv *btv) | |||
422 | if (btv->remote == NULL) | 450 | if (btv->remote == NULL) |
423 | return; | 451 | return; |
424 | 452 | ||
425 | if (btv->remote->polling) { | 453 | bttv_ir_stop(btv); |
426 | del_timer_sync(&btv->remote->timer); | ||
427 | flush_scheduled_work(); | ||
428 | } | ||
429 | |||
430 | |||
431 | if (btv->remote->rc5_gpio) { | ||
432 | u32 gpio; | ||
433 | |||
434 | del_timer_sync(&btv->remote->timer_end); | ||
435 | flush_scheduled_work(); | ||
436 | |||
437 | gpio = bttv_gpio_read(&btv->c); | ||
438 | bttv_gpio_write(&btv->c, gpio & ~(1 << 4)); | ||
439 | } | ||
440 | |||
441 | input_unregister_device(btv->remote->dev); | 454 | input_unregister_device(btv->remote->dev); |
442 | kfree(btv->remote); | 455 | kfree(btv->remote); |
443 | btv->remote = NULL; | 456 | btv->remote = NULL; |
diff --git a/drivers/media/video/cx88/cx88-input.c b/drivers/media/video/cx88/cx88-input.c index e60a0a52e4b2..c6d412b1f218 100644 --- a/drivers/media/video/cx88/cx88-input.c +++ b/drivers/media/video/cx88/cx88-input.c | |||
@@ -155,6 +155,35 @@ static void cx88_ir_work(struct work_struct *work) | |||
155 | mod_timer(&ir->timer, timeout); | 155 | mod_timer(&ir->timer, timeout); |
156 | } | 156 | } |
157 | 157 | ||
158 | static void cx88_ir_start(struct cx88_core *core, struct cx88_IR *ir) | ||
159 | { | ||
160 | if (ir->polling) { | ||
161 | INIT_WORK(&ir->work, cx88_ir_work, ir); | ||
162 | init_timer(&ir->timer); | ||
163 | ir->timer.function = ir_timer; | ||
164 | ir->timer.data = (unsigned long)ir; | ||
165 | schedule_work(&ir->work); | ||
166 | } | ||
167 | if (ir->sampling) { | ||
168 | core->pci_irqmask |= (1 << 18); /* IR_SMP_INT */ | ||
169 | cx_write(MO_DDS_IO, 0xa80a80); /* 4 kHz sample rate */ | ||
170 | cx_write(MO_DDSCFG_IO, 0x5); /* enable */ | ||
171 | } | ||
172 | } | ||
173 | |||
174 | static void cx88_ir_stop(struct cx88_core *core, struct cx88_IR *ir) | ||
175 | { | ||
176 | if (ir->sampling) { | ||
177 | cx_write(MO_DDSCFG_IO, 0x0); | ||
178 | core->pci_irqmask &= ~(1 << 18); | ||
179 | } | ||
180 | |||
181 | if (ir->polling) { | ||
182 | del_timer_sync(&ir->timer); | ||
183 | flush_scheduled_work(); | ||
184 | } | ||
185 | } | ||
186 | |||
158 | /* ---------------------------------------------------------------------- */ | 187 | /* ---------------------------------------------------------------------- */ |
159 | 188 | ||
160 | int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci) | 189 | int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci) |
@@ -163,14 +192,12 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci) | |||
163 | struct input_dev *input_dev; | 192 | struct input_dev *input_dev; |
164 | IR_KEYTAB_TYPE *ir_codes = NULL; | 193 | IR_KEYTAB_TYPE *ir_codes = NULL; |
165 | int ir_type = IR_TYPE_OTHER; | 194 | int ir_type = IR_TYPE_OTHER; |
195 | int err = -ENOMEM; | ||
166 | 196 | ||
167 | ir = kzalloc(sizeof(*ir), GFP_KERNEL); | 197 | ir = kzalloc(sizeof(*ir), GFP_KERNEL); |
168 | input_dev = input_allocate_device(); | 198 | input_dev = input_allocate_device(); |
169 | if (!ir || !input_dev) { | 199 | if (!ir || !input_dev) |
170 | kfree(ir); | 200 | goto err_out_free; |
171 | input_free_device(input_dev); | ||
172 | return -ENOMEM; | ||
173 | } | ||
174 | 201 | ||
175 | ir->input = input_dev; | 202 | ir->input = input_dev; |
176 | 203 | ||
@@ -280,9 +307,8 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci) | |||
280 | } | 307 | } |
281 | 308 | ||
282 | if (NULL == ir_codes) { | 309 | if (NULL == ir_codes) { |
283 | kfree(ir); | 310 | err = -ENODEV; |
284 | input_free_device(input_dev); | 311 | goto err_out_free; |
285 | return -ENODEV; | ||
286 | } | 312 | } |
287 | 313 | ||
288 | /* init input device */ | 314 | /* init input device */ |
@@ -307,23 +333,22 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci) | |||
307 | ir->core = core; | 333 | ir->core = core; |
308 | core->ir = ir; | 334 | core->ir = ir; |
309 | 335 | ||
310 | if (ir->polling) { | 336 | cx88_ir_start(core, ir); |
311 | INIT_WORK(&ir->work, cx88_ir_work); | ||
312 | init_timer(&ir->timer); | ||
313 | ir->timer.function = ir_timer; | ||
314 | ir->timer.data = (unsigned long)ir; | ||
315 | schedule_work(&ir->work); | ||
316 | } | ||
317 | if (ir->sampling) { | ||
318 | core->pci_irqmask |= (1 << 18); /* IR_SMP_INT */ | ||
319 | cx_write(MO_DDS_IO, 0xa80a80); /* 4 kHz sample rate */ | ||
320 | cx_write(MO_DDSCFG_IO, 0x5); /* enable */ | ||
321 | } | ||
322 | 337 | ||
323 | /* all done */ | 338 | /* all done */ |
324 | input_register_device(ir->input); | 339 | err = input_register_device(ir->input); |
340 | if (err) | ||
341 | goto err_out_stop; | ||
325 | 342 | ||
326 | return 0; | 343 | return 0; |
344 | |||
345 | err_out_stop: | ||
346 | cx88_ir_stop(core, ir); | ||
347 | core->ir = NULL; | ||
348 | err_out_free: | ||
349 | input_free_device(input_dev); | ||
350 | kfree(ir); | ||
351 | return err; | ||
327 | } | 352 | } |
328 | 353 | ||
329 | int cx88_ir_fini(struct cx88_core *core) | 354 | int cx88_ir_fini(struct cx88_core *core) |
@@ -334,15 +359,7 @@ int cx88_ir_fini(struct cx88_core *core) | |||
334 | if (NULL == ir) | 359 | if (NULL == ir) |
335 | return 0; | 360 | return 0; |
336 | 361 | ||
337 | if (ir->sampling) { | 362 | cx88_ir_stop(core, ir); |
338 | cx_write(MO_DDSCFG_IO, 0x0); | ||
339 | core->pci_irqmask &= ~(1 << 18); | ||
340 | } | ||
341 | if (ir->polling) { | ||
342 | del_timer(&ir->timer); | ||
343 | flush_scheduled_work(); | ||
344 | } | ||
345 | |||
346 | input_unregister_device(ir->input); | 363 | input_unregister_device(ir->input); |
347 | kfree(ir); | 364 | kfree(ir); |
348 | 365 | ||
diff --git a/drivers/media/video/ir-kbd-i2c.c b/drivers/media/video/ir-kbd-i2c.c index ab87e7bfe84f..dd6341f2e390 100644 --- a/drivers/media/video/ir-kbd-i2c.c +++ b/drivers/media/video/ir-kbd-i2c.c | |||
@@ -305,15 +305,14 @@ static int ir_attach(struct i2c_adapter *adap, int addr, | |||
305 | int ir_type; | 305 | int ir_type; |
306 | struct IR_i2c *ir; | 306 | struct IR_i2c *ir; |
307 | struct input_dev *input_dev; | 307 | struct input_dev *input_dev; |
308 | int err; | ||
308 | 309 | ||
309 | ir = kzalloc(sizeof(struct IR_i2c),GFP_KERNEL); | 310 | ir = kzalloc(sizeof(struct IR_i2c),GFP_KERNEL); |
310 | input_dev = input_allocate_device(); | 311 | input_dev = input_allocate_device(); |
311 | if (!ir || !input_dev) { | 312 | if (!ir || !input_dev) { |
312 | input_free_device(input_dev); | 313 | err = -ENOMEM; |
313 | kfree(ir); | 314 | goto err_out_free; |
314 | return -ENOMEM; | ||
315 | } | 315 | } |
316 | memset(ir,0,sizeof(*ir)); | ||
317 | 316 | ||
318 | ir->c = client_template; | 317 | ir->c = client_template; |
319 | ir->input = input_dev; | 318 | ir->input = input_dev; |
@@ -361,26 +360,27 @@ static int ir_attach(struct i2c_adapter *adap, int addr, | |||
361 | break; | 360 | break; |
362 | default: | 361 | default: |
363 | /* shouldn't happen */ | 362 | /* shouldn't happen */ |
364 | printk(DEVNAME ": Huh? unknown i2c address (0x%02x)?\n",addr); | 363 | printk(DEVNAME ": Huh? unknown i2c address (0x%02x)?\n", addr); |
365 | kfree(ir); | 364 | err = -ENODEV; |
366 | return -1; | 365 | goto err_out_free; |
367 | } | 366 | } |
368 | 367 | ||
369 | /* Sets name */ | 368 | /* Sets name */ |
370 | snprintf(ir->c.name, sizeof(ir->c.name), "i2c IR (%s)", name); | 369 | snprintf(ir->c.name, sizeof(ir->c.name), "i2c IR (%s)", name); |
371 | ir->ir_codes=ir_codes; | 370 | ir->ir_codes = ir_codes; |
372 | 371 | ||
373 | /* register i2c device | 372 | /* register i2c device |
374 | * At device register, IR codes may be changed to be | 373 | * At device register, IR codes may be changed to be |
375 | * board dependent. | 374 | * board dependent. |
376 | */ | 375 | */ |
377 | i2c_attach_client(&ir->c); | 376 | err = i2c_attach_client(&ir->c); |
377 | if (err) | ||
378 | goto err_out_free; | ||
378 | 379 | ||
379 | /* If IR not supported or disabled, unregisters driver */ | 380 | /* If IR not supported or disabled, unregisters driver */ |
380 | if (ir->get_key == NULL) { | 381 | if (ir->get_key == NULL) { |
381 | i2c_detach_client(&ir->c); | 382 | err = -ENODEV; |
382 | kfree(ir); | 383 | goto err_out_detach; |
383 | return -1; | ||
384 | } | 384 | } |
385 | 385 | ||
386 | /* Phys addr can only be set after attaching (for ir->c.dev.bus_id) */ | 386 | /* Phys addr can only be set after attaching (for ir->c.dev.bus_id) */ |
@@ -389,15 +389,17 @@ static int ir_attach(struct i2c_adapter *adap, int addr, | |||
389 | ir->c.dev.bus_id); | 389 | ir->c.dev.bus_id); |
390 | 390 | ||
391 | /* init + register input device */ | 391 | /* init + register input device */ |
392 | ir_input_init(input_dev,&ir->ir,ir_type,ir->ir_codes); | 392 | ir_input_init(input_dev, &ir->ir, ir_type, ir->ir_codes); |
393 | input_dev->id.bustype = BUS_I2C; | 393 | input_dev->id.bustype = BUS_I2C; |
394 | input_dev->name = ir->c.name; | 394 | input_dev->name = ir->c.name; |
395 | input_dev->phys = ir->phys; | 395 | input_dev->phys = ir->phys; |
396 | 396 | ||
397 | /* register event device */ | 397 | err = input_register_device(ir->input); |
398 | input_register_device(ir->input); | 398 | if (err) |
399 | goto err_out_detach; | ||
400 | |||
399 | printk(DEVNAME ": %s detected at %s [%s]\n", | 401 | printk(DEVNAME ": %s detected at %s [%s]\n", |
400 | ir->input->name,ir->input->phys,adap->name); | 402 | ir->input->name, ir->input->phys, adap->name); |
401 | 403 | ||
402 | /* start polling via eventd */ | 404 | /* start polling via eventd */ |
403 | INIT_WORK(&ir->work, ir_work); | 405 | INIT_WORK(&ir->work, ir_work); |
@@ -407,6 +409,13 @@ static int ir_attach(struct i2c_adapter *adap, int addr, | |||
407 | schedule_work(&ir->work); | 409 | schedule_work(&ir->work); |
408 | 410 | ||
409 | return 0; | 411 | return 0; |
412 | |||
413 | err_out_detach: | ||
414 | i2c_detach_client(&ir->c); | ||
415 | err_out_free: | ||
416 | input_free_device(input_dev); | ||
417 | kfree(ir); | ||
418 | return err; | ||
410 | } | 419 | } |
411 | 420 | ||
412 | static int ir_detach(struct i2c_client *client) | 421 | static int ir_detach(struct i2c_client *client) |
@@ -414,7 +423,7 @@ static int ir_detach(struct i2c_client *client) | |||
414 | struct IR_i2c *ir = i2c_get_clientdata(client); | 423 | struct IR_i2c *ir = i2c_get_clientdata(client); |
415 | 424 | ||
416 | /* kill outstanding polls */ | 425 | /* kill outstanding polls */ |
417 | del_timer(&ir->timer); | 426 | del_timer_sync(&ir->timer); |
418 | flush_scheduled_work(); | 427 | flush_scheduled_work(); |
419 | 428 | ||
420 | /* unregister devices */ | 429 | /* unregister devices */ |
diff --git a/drivers/media/video/saa7134/saa7134-input.c b/drivers/media/video/saa7134/saa7134-input.c index 83887d1876a9..5d2bf15239f7 100644 --- a/drivers/media/video/saa7134/saa7134-input.c +++ b/drivers/media/video/saa7134/saa7134-input.c | |||
@@ -131,6 +131,23 @@ static void saa7134_input_timer(unsigned long data) | |||
131 | mod_timer(&ir->timer, timeout); | 131 | mod_timer(&ir->timer, timeout); |
132 | } | 132 | } |
133 | 133 | ||
134 | static void saa7134_ir_start(struct saa7134_dev *dev, struct saa7134_ir *ir) | ||
135 | { | ||
136 | if (ir->polling) { | ||
137 | init_timer(&ir->timer); | ||
138 | ir->timer.function = saa7134_input_timer; | ||
139 | ir->timer.data = (unsigned long)dev; | ||
140 | ir->timer.expires = jiffies + HZ; | ||
141 | add_timer(&ir->timer); | ||
142 | } | ||
143 | } | ||
144 | |||
145 | static void saa7134_ir_stop(struct saa7134_dev *dev) | ||
146 | { | ||
147 | if (dev->remote->polling) | ||
148 | del_timer_sync(&dev->remote->timer); | ||
149 | } | ||
150 | |||
134 | int saa7134_input_init1(struct saa7134_dev *dev) | 151 | int saa7134_input_init1(struct saa7134_dev *dev) |
135 | { | 152 | { |
136 | struct saa7134_ir *ir; | 153 | struct saa7134_ir *ir; |
@@ -141,6 +158,7 @@ int saa7134_input_init1(struct saa7134_dev *dev) | |||
141 | u32 mask_keyup = 0; | 158 | u32 mask_keyup = 0; |
142 | int polling = 0; | 159 | int polling = 0; |
143 | int ir_type = IR_TYPE_OTHER; | 160 | int ir_type = IR_TYPE_OTHER; |
161 | int err; | ||
144 | 162 | ||
145 | if (dev->has_remote != SAA7134_REMOTE_GPIO) | 163 | if (dev->has_remote != SAA7134_REMOTE_GPIO) |
146 | return -ENODEV; | 164 | return -ENODEV; |
@@ -267,9 +285,8 @@ int saa7134_input_init1(struct saa7134_dev *dev) | |||
267 | ir = kzalloc(sizeof(*ir), GFP_KERNEL); | 285 | ir = kzalloc(sizeof(*ir), GFP_KERNEL); |
268 | input_dev = input_allocate_device(); | 286 | input_dev = input_allocate_device(); |
269 | if (!ir || !input_dev) { | 287 | if (!ir || !input_dev) { |
270 | kfree(ir); | 288 | err = -ENOMEM; |
271 | input_free_device(input_dev); | 289 | goto err_out_free; |
272 | return -ENOMEM; | ||
273 | } | 290 | } |
274 | 291 | ||
275 | ir->dev = input_dev; | 292 | ir->dev = input_dev; |
@@ -300,18 +317,22 @@ int saa7134_input_init1(struct saa7134_dev *dev) | |||
300 | } | 317 | } |
301 | input_dev->cdev.dev = &dev->pci->dev; | 318 | input_dev->cdev.dev = &dev->pci->dev; |
302 | 319 | ||
303 | /* all done */ | ||
304 | dev->remote = ir; | 320 | dev->remote = ir; |
305 | if (ir->polling) { | 321 | saa7134_ir_start(dev, ir); |
306 | init_timer(&ir->timer); | 322 | |
307 | ir->timer.function = saa7134_input_timer; | 323 | err = input_register_device(ir->dev); |
308 | ir->timer.data = (unsigned long)dev; | 324 | if (err) |
309 | ir->timer.expires = jiffies + HZ; | 325 | goto err_out_stop; |
310 | add_timer(&ir->timer); | ||
311 | } | ||
312 | 326 | ||
313 | input_register_device(ir->dev); | ||
314 | return 0; | 327 | return 0; |
328 | |||
329 | err_out_stop: | ||
330 | saa7134_ir_stop(dev); | ||
331 | dev->remote = NULL; | ||
332 | err_out_free: | ||
333 | input_free_device(input_dev); | ||
334 | kfree(ir); | ||
335 | return err; | ||
315 | } | 336 | } |
316 | 337 | ||
317 | void saa7134_input_fini(struct saa7134_dev *dev) | 338 | void saa7134_input_fini(struct saa7134_dev *dev) |
@@ -319,8 +340,7 @@ void saa7134_input_fini(struct saa7134_dev *dev) | |||
319 | if (NULL == dev->remote) | 340 | if (NULL == dev->remote) |
320 | return; | 341 | return; |
321 | 342 | ||
322 | if (dev->remote->polling) | 343 | saa7134_ir_stop(dev); |
323 | del_timer_sync(&dev->remote->timer); | ||
324 | input_unregister_device(dev->remote->dev); | 344 | input_unregister_device(dev->remote->dev); |
325 | kfree(dev->remote); | 345 | kfree(dev->remote); |
326 | dev->remote = NULL; | 346 | dev->remote = NULL; |
diff --git a/drivers/media/video/usbvideo/quickcam_messenger.c b/drivers/media/video/usbvideo/quickcam_messenger.c index bbf2beeeb449..ec0ff2247f06 100644 --- a/drivers/media/video/usbvideo/quickcam_messenger.c +++ b/drivers/media/video/usbvideo/quickcam_messenger.c | |||
@@ -86,6 +86,7 @@ MODULE_DEVICE_TABLE(usb, qcm_table); | |||
86 | static void qcm_register_input(struct qcm *cam, struct usb_device *dev) | 86 | static void qcm_register_input(struct qcm *cam, struct usb_device *dev) |
87 | { | 87 | { |
88 | struct input_dev *input_dev; | 88 | struct input_dev *input_dev; |
89 | int error; | ||
89 | 90 | ||
90 | usb_make_path(dev, cam->input_physname, sizeof(cam->input_physname)); | 91 | usb_make_path(dev, cam->input_physname, sizeof(cam->input_physname)); |
91 | strncat(cam->input_physname, "/input0", sizeof(cam->input_physname)); | 92 | strncat(cam->input_physname, "/input0", sizeof(cam->input_physname)); |
@@ -106,7 +107,13 @@ static void qcm_register_input(struct qcm *cam, struct usb_device *dev) | |||
106 | 107 | ||
107 | input_dev->private = cam; | 108 | input_dev->private = cam; |
108 | 109 | ||
109 | input_register_device(cam->input); | 110 | error = input_register_device(cam->input); |
111 | if (error) { | ||
112 | warn("Failed to register camera's input device, err: %d\n", | ||
113 | error); | ||
114 | input_free_device(cam->input); | ||
115 | cam->input = NULL; | ||
116 | } | ||
110 | } | 117 | } |
111 | 118 | ||
112 | static void qcm_unregister_input(struct qcm *cam) | 119 | static void qcm_unregister_input(struct qcm *cam) |