diff options
Diffstat (limited to 'drivers/i2c/chips')
-rw-r--r-- | drivers/i2c/chips/tps65010.c | 21 |
1 files changed, 12 insertions, 9 deletions
diff --git a/drivers/i2c/chips/tps65010.c b/drivers/i2c/chips/tps65010.c index 60bef94cd25f..4ee56def61f2 100644 --- a/drivers/i2c/chips/tps65010.c +++ b/drivers/i2c/chips/tps65010.c | |||
@@ -82,7 +82,7 @@ struct tps65010 { | |||
82 | struct i2c_client client; | 82 | struct i2c_client client; |
83 | struct mutex lock; | 83 | struct mutex lock; |
84 | int irq; | 84 | int irq; |
85 | struct work_struct work; | 85 | struct delayed_work work; |
86 | struct dentry *file; | 86 | struct dentry *file; |
87 | unsigned charging:1; | 87 | unsigned charging:1; |
88 | unsigned por:1; | 88 | unsigned por:1; |
@@ -328,7 +328,7 @@ static void tps65010_interrupt(struct tps65010 *tps) | |||
328 | { | 328 | { |
329 | u8 tmp = 0, mask, poll; | 329 | u8 tmp = 0, mask, poll; |
330 | 330 | ||
331 | /* IRQs won't trigger irqs for certain events, but we can get | 331 | /* IRQs won't trigger for certain events, but we can get |
332 | * others by polling (normally, with external power applied). | 332 | * others by polling (normally, with external power applied). |
333 | */ | 333 | */ |
334 | poll = 0; | 334 | poll = 0; |
@@ -411,10 +411,11 @@ static void tps65010_interrupt(struct tps65010 *tps) | |||
411 | } | 411 | } |
412 | 412 | ||
413 | /* handle IRQs and polling using keventd for now */ | 413 | /* handle IRQs and polling using keventd for now */ |
414 | static void tps65010_work(void *_tps) | 414 | static void tps65010_work(struct work_struct *work) |
415 | { | 415 | { |
416 | struct tps65010 *tps = _tps; | 416 | struct tps65010 *tps; |
417 | 417 | ||
418 | tps = container_of(work, struct tps65010, work.work); | ||
418 | mutex_lock(&tps->lock); | 419 | mutex_lock(&tps->lock); |
419 | 420 | ||
420 | tps65010_interrupt(tps); | 421 | tps65010_interrupt(tps); |
@@ -452,7 +453,7 @@ static irqreturn_t tps65010_irq(int irq, void *_tps) | |||
452 | 453 | ||
453 | disable_irq_nosync(irq); | 454 | disable_irq_nosync(irq); |
454 | set_bit(FLAG_IRQ_ENABLE, &tps->flags); | 455 | set_bit(FLAG_IRQ_ENABLE, &tps->flags); |
455 | (void) schedule_work(&tps->work); | 456 | (void) schedule_work(&tps->work.work); |
456 | return IRQ_HANDLED; | 457 | return IRQ_HANDLED; |
457 | } | 458 | } |
458 | 459 | ||
@@ -465,13 +466,15 @@ static int __exit tps65010_detach_client(struct i2c_client *client) | |||
465 | struct tps65010 *tps; | 466 | struct tps65010 *tps; |
466 | 467 | ||
467 | tps = container_of(client, struct tps65010, client); | 468 | tps = container_of(client, struct tps65010, client); |
469 | free_irq(tps->irq, tps); | ||
468 | #ifdef CONFIG_ARM | 470 | #ifdef CONFIG_ARM |
469 | if (machine_is_omap_h2()) | 471 | if (machine_is_omap_h2()) |
470 | omap_free_gpio(58); | 472 | omap_free_gpio(58); |
471 | if (machine_is_omap_osk()) | 473 | if (machine_is_omap_osk()) |
472 | omap_free_gpio(OMAP_MPUIO(1)); | 474 | omap_free_gpio(OMAP_MPUIO(1)); |
473 | #endif | 475 | #endif |
474 | free_irq(tps->irq, tps); | 476 | cancel_delayed_work(&tps->work); |
477 | flush_scheduled_work(); | ||
475 | debugfs_remove(tps->file); | 478 | debugfs_remove(tps->file); |
476 | if (i2c_detach_client(client) == 0) | 479 | if (i2c_detach_client(client) == 0) |
477 | kfree(tps); | 480 | kfree(tps); |
@@ -505,7 +508,7 @@ tps65010_probe(struct i2c_adapter *bus, int address, int kind) | |||
505 | return 0; | 508 | return 0; |
506 | 509 | ||
507 | mutex_init(&tps->lock); | 510 | mutex_init(&tps->lock); |
508 | INIT_WORK(&tps->work, tps65010_work, tps); | 511 | INIT_DELAYED_WORK(&tps->work, tps65010_work); |
509 | tps->irq = -1; | 512 | tps->irq = -1; |
510 | tps->client.addr = address; | 513 | tps->client.addr = address; |
511 | tps->client.adapter = bus; | 514 | tps->client.adapter = bus; |
@@ -620,7 +623,7 @@ tps65010_probe(struct i2c_adapter *bus, int address, int kind) | |||
620 | (void) i2c_smbus_write_byte_data(&tps->client, TPS_MASK3, 0x0f | 623 | (void) i2c_smbus_write_byte_data(&tps->client, TPS_MASK3, 0x0f |
621 | | i2c_smbus_read_byte_data(&tps->client, TPS_MASK3)); | 624 | | i2c_smbus_read_byte_data(&tps->client, TPS_MASK3)); |
622 | 625 | ||
623 | tps65010_work(tps); | 626 | tps65010_work(&tps->work.work); |
624 | 627 | ||
625 | tps->file = debugfs_create_file(DRIVER_NAME, S_IRUGO, NULL, | 628 | tps->file = debugfs_create_file(DRIVER_NAME, S_IRUGO, NULL, |
626 | tps, DEBUG_FOPS); | 629 | tps, DEBUG_FOPS); |
@@ -672,7 +675,7 @@ int tps65010_set_vbus_draw(unsigned mA) | |||
672 | && test_and_set_bit( | 675 | && test_and_set_bit( |
673 | FLAG_VBUS_CHANGED, &the_tps->flags)) { | 676 | FLAG_VBUS_CHANGED, &the_tps->flags)) { |
674 | /* gadget drivers call this in_irq() */ | 677 | /* gadget drivers call this in_irq() */ |
675 | (void) schedule_work(&the_tps->work); | 678 | (void) schedule_work(&the_tps->work.work); |
676 | } | 679 | } |
677 | local_irq_restore(flags); | 680 | local_irq_restore(flags); |
678 | 681 | ||