diff options
author | Dmitry Torokhov <dtor@insightbb.com> | 2006-11-20 08:23:04 -0500 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@infradead.org> | 2006-12-10 06:04:52 -0500 |
commit | b07b4783fb30dee8c542fc76ed8993108d46d6aa (patch) | |
tree | 0e57cc5887511b31e964299820a7adf37e6e45ae /drivers/media/video/bt8xx | |
parent | ff67c614e23bf5a3c16968e2c42ab442121c4beb (diff) |
V4L/DVB (4854): Handle errors from input_register_device()
Also sprinkled some input_sync() throughout the code.
Acked-by: Ricardo Cerqueira <v4l@cerqueira.org>
Acked-by: Oliver Endriss <o.endriss@gmx.de>
Acked-by: Andrew de Quincey <adq_dvb@lidskialf.net>
Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
Diffstat (limited to 'drivers/media/video/bt8xx')
-rw-r--r-- | drivers/media/video/bt8xx/bttv-input.c | 101 |
1 files changed, 57 insertions, 44 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; |