aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char/tpm/tpm.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/char/tpm/tpm.c')
-rw-r--r--drivers/char/tpm/tpm.c16
1 files changed, 13 insertions, 3 deletions
diff --git a/drivers/char/tpm/tpm.c b/drivers/char/tpm/tpm.c
index 303f15880466..a9be0e8eaea5 100644
--- a/drivers/char/tpm/tpm.c
+++ b/drivers/char/tpm/tpm.c
@@ -43,6 +43,13 @@ static void user_reader_timeout(unsigned long ptr)
43{ 43{
44 struct tpm_chip *chip = (struct tpm_chip *) ptr; 44 struct tpm_chip *chip = (struct tpm_chip *) ptr;
45 45
46 schedule_work(&chip->work);
47}
48
49static void timeout_work(void * ptr)
50{
51 struct tpm_chip *chip = ptr;
52
46 down(&chip->buffer_mutex); 53 down(&chip->buffer_mutex);
47 atomic_set(&chip->data_pending, 0); 54 atomic_set(&chip->data_pending, 0);
48 memset(chip->data_buffer, 0, TPM_BUFSIZE); 55 memset(chip->data_buffer, 0, TPM_BUFSIZE);
@@ -370,6 +377,7 @@ int tpm_release(struct inode *inode, struct file *file)
370 file->private_data = NULL; 377 file->private_data = NULL;
371 chip->num_opens--; 378 chip->num_opens--;
372 del_singleshot_timer_sync(&chip->user_read_timer); 379 del_singleshot_timer_sync(&chip->user_read_timer);
380 flush_scheduled_work();
373 atomic_set(&chip->data_pending, 0); 381 atomic_set(&chip->data_pending, 0);
374 put_device(chip->dev); 382 put_device(chip->dev);
375 kfree(chip->data_buffer); 383 kfree(chip->data_buffer);
@@ -421,6 +429,7 @@ ssize_t tpm_read(struct file * file, char __user *buf,
421 int ret_size; 429 int ret_size;
422 430
423 del_singleshot_timer_sync(&chip->user_read_timer); 431 del_singleshot_timer_sync(&chip->user_read_timer);
432 flush_scheduled_work();
424 ret_size = atomic_read(&chip->data_pending); 433 ret_size = atomic_read(&chip->data_pending);
425 atomic_set(&chip->data_pending, 0); 434 atomic_set(&chip->data_pending, 0);
426 if (ret_size > 0) { /* relay data */ 435 if (ret_size > 0) { /* relay data */
@@ -428,8 +437,7 @@ ssize_t tpm_read(struct file * file, char __user *buf,
428 ret_size = size; 437 ret_size = size;
429 438
430 down(&chip->buffer_mutex); 439 down(&chip->buffer_mutex);
431 if (copy_to_user 440 if (copy_to_user(buf, chip->data_buffer, ret_size))
432 ((void __user *) buf, chip->data_buffer, ret_size))
433 ret_size = -EFAULT; 441 ret_size = -EFAULT;
434 up(&chip->buffer_mutex); 442 up(&chip->buffer_mutex);
435 } 443 }
@@ -460,7 +468,7 @@ void tpm_remove_hardware(struct device *dev)
460 sysfs_remove_group(&dev->kobj, chip->vendor->attr_group); 468 sysfs_remove_group(&dev->kobj, chip->vendor->attr_group);
461 469
462 dev_mask[chip->dev_num / TPM_NUM_MASK_ENTRIES ] &= 470 dev_mask[chip->dev_num / TPM_NUM_MASK_ENTRIES ] &=
463 !(1 << (chip->dev_num % TPM_NUM_MASK_ENTRIES)); 471 ~(1 << (chip->dev_num % TPM_NUM_MASK_ENTRIES));
464 472
465 kfree(chip); 473 kfree(chip);
466 474
@@ -528,6 +536,8 @@ int tpm_register_hardware(struct device *dev, struct tpm_vendor_specific *entry)
528 init_MUTEX(&chip->tpm_mutex); 536 init_MUTEX(&chip->tpm_mutex);
529 INIT_LIST_HEAD(&chip->list); 537 INIT_LIST_HEAD(&chip->list);
530 538
539 INIT_WORK(&chip->work, timeout_work, chip);
540
531 init_timer(&chip->user_read_timer); 541 init_timer(&chip->user_read_timer);
532 chip->user_read_timer.function = user_reader_timeout; 542 chip->user_read_timer.function = user_reader_timeout;
533 chip->user_read_timer.data = (unsigned long) chip; 543 chip->user_read_timer.data = (unsigned long) chip;