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/ir-kbd-i2c.c | |
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/ir-kbd-i2c.c')
-rw-r--r-- | drivers/media/video/ir-kbd-i2c.c | 43 |
1 files changed, 26 insertions, 17 deletions
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 */ |