diff options
Diffstat (limited to 'drivers/media/video/ir-kbd-i2c.c')
-rw-r--r-- | drivers/media/video/ir-kbd-i2c.c | 46 |
1 files changed, 28 insertions, 18 deletions
diff --git a/drivers/media/video/ir-kbd-i2c.c b/drivers/media/video/ir-kbd-i2c.c index ab87e7bfe84f..59edf58204de 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; |
@@ -355,32 +354,34 @@ static int ir_attach(struct i2c_adapter *adap, int addr, | |||
355 | break; | 354 | break; |
356 | case 0x7a: | 355 | case 0x7a: |
357 | case 0x47: | 356 | case 0x47: |
357 | case 0x71: | ||
358 | /* Handled by saa7134-input */ | 358 | /* Handled by saa7134-input */ |
359 | name = "SAA713x remote"; | 359 | name = "SAA713x remote"; |
360 | ir_type = IR_TYPE_OTHER; | 360 | ir_type = IR_TYPE_OTHER; |
361 | break; | 361 | break; |
362 | default: | 362 | default: |
363 | /* shouldn't happen */ | 363 | /* shouldn't happen */ |
364 | printk(DEVNAME ": Huh? unknown i2c address (0x%02x)?\n",addr); | 364 | printk(DEVNAME ": Huh? unknown i2c address (0x%02x)?\n", addr); |
365 | kfree(ir); | 365 | err = -ENODEV; |
366 | return -1; | 366 | goto err_out_free; |
367 | } | 367 | } |
368 | 368 | ||
369 | /* Sets name */ | 369 | /* Sets name */ |
370 | snprintf(ir->c.name, sizeof(ir->c.name), "i2c IR (%s)", name); | 370 | snprintf(ir->c.name, sizeof(ir->c.name), "i2c IR (%s)", name); |
371 | ir->ir_codes=ir_codes; | 371 | ir->ir_codes = ir_codes; |
372 | 372 | ||
373 | /* register i2c device | 373 | /* register i2c device |
374 | * At device register, IR codes may be changed to be | 374 | * At device register, IR codes may be changed to be |
375 | * board dependent. | 375 | * board dependent. |
376 | */ | 376 | */ |
377 | i2c_attach_client(&ir->c); | 377 | err = i2c_attach_client(&ir->c); |
378 | if (err) | ||
379 | goto err_out_free; | ||
378 | 380 | ||
379 | /* If IR not supported or disabled, unregisters driver */ | 381 | /* If IR not supported or disabled, unregisters driver */ |
380 | if (ir->get_key == NULL) { | 382 | if (ir->get_key == NULL) { |
381 | i2c_detach_client(&ir->c); | 383 | err = -ENODEV; |
382 | kfree(ir); | 384 | goto err_out_detach; |
383 | return -1; | ||
384 | } | 385 | } |
385 | 386 | ||
386 | /* Phys addr can only be set after attaching (for ir->c.dev.bus_id) */ | 387 | /* Phys addr can only be set after attaching (for ir->c.dev.bus_id) */ |
@@ -389,15 +390,17 @@ static int ir_attach(struct i2c_adapter *adap, int addr, | |||
389 | ir->c.dev.bus_id); | 390 | ir->c.dev.bus_id); |
390 | 391 | ||
391 | /* init + register input device */ | 392 | /* init + register input device */ |
392 | ir_input_init(input_dev,&ir->ir,ir_type,ir->ir_codes); | 393 | ir_input_init(input_dev, &ir->ir, ir_type, ir->ir_codes); |
393 | input_dev->id.bustype = BUS_I2C; | 394 | input_dev->id.bustype = BUS_I2C; |
394 | input_dev->name = ir->c.name; | 395 | input_dev->name = ir->c.name; |
395 | input_dev->phys = ir->phys; | 396 | input_dev->phys = ir->phys; |
396 | 397 | ||
397 | /* register event device */ | 398 | err = input_register_device(ir->input); |
398 | input_register_device(ir->input); | 399 | if (err) |
400 | goto err_out_detach; | ||
401 | |||
399 | printk(DEVNAME ": %s detected at %s [%s]\n", | 402 | printk(DEVNAME ": %s detected at %s [%s]\n", |
400 | ir->input->name,ir->input->phys,adap->name); | 403 | ir->input->name, ir->input->phys, adap->name); |
401 | 404 | ||
402 | /* start polling via eventd */ | 405 | /* start polling via eventd */ |
403 | INIT_WORK(&ir->work, ir_work); | 406 | INIT_WORK(&ir->work, ir_work); |
@@ -407,6 +410,13 @@ static int ir_attach(struct i2c_adapter *adap, int addr, | |||
407 | schedule_work(&ir->work); | 410 | schedule_work(&ir->work); |
408 | 411 | ||
409 | return 0; | 412 | return 0; |
413 | |||
414 | err_out_detach: | ||
415 | i2c_detach_client(&ir->c); | ||
416 | err_out_free: | ||
417 | input_free_device(input_dev); | ||
418 | kfree(ir); | ||
419 | return err; | ||
410 | } | 420 | } |
411 | 421 | ||
412 | static int ir_detach(struct i2c_client *client) | 422 | static int ir_detach(struct i2c_client *client) |
@@ -414,7 +424,7 @@ static int ir_detach(struct i2c_client *client) | |||
414 | struct IR_i2c *ir = i2c_get_clientdata(client); | 424 | struct IR_i2c *ir = i2c_get_clientdata(client); |
415 | 425 | ||
416 | /* kill outstanding polls */ | 426 | /* kill outstanding polls */ |
417 | del_timer(&ir->timer); | 427 | del_timer_sync(&ir->timer); |
418 | flush_scheduled_work(); | 428 | flush_scheduled_work(); |
419 | 429 | ||
420 | /* unregister devices */ | 430 | /* unregister devices */ |
@@ -439,7 +449,7 @@ static int ir_probe(struct i2c_adapter *adap) | |||
439 | */ | 449 | */ |
440 | 450 | ||
441 | static const int probe_bttv[] = { 0x1a, 0x18, 0x4b, 0x64, 0x30, -1}; | 451 | static const int probe_bttv[] = { 0x1a, 0x18, 0x4b, 0x64, 0x30, -1}; |
442 | static const int probe_saa7134[] = { 0x7a, 0x47, -1 }; | 452 | static const int probe_saa7134[] = { 0x7a, 0x47, 0x71, -1 }; |
443 | static const int probe_em28XX[] = { 0x30, 0x47, -1 }; | 453 | static const int probe_em28XX[] = { 0x30, 0x47, -1 }; |
444 | const int *probe = NULL; | 454 | const int *probe = NULL; |
445 | struct i2c_client c; | 455 | struct i2c_client c; |