summaryrefslogtreecommitdiff
path: root/drivers/char
diff options
context:
space:
mode:
authorKylene Jo Hall <kjhall@us.ibm.com>2005-11-13 16:07:43 -0800
committerLinus Torvalds <torvalds@g5.osdl.org>2005-11-13 18:14:17 -0800
commit09e12f9f6bcd9af516d901223cebdbae58b32c9f (patch)
treee6f56aea2eb1b3aefe483475291580d862fb00e7 /drivers/char
parentf6a2382cec3ed9b67b01febfa85d7d72b254844a (diff)
downloadlinux-3.10-09e12f9f6bcd9af516d901223cebdbae58b32c9f.tar.gz
linux-3.10-09e12f9f6bcd9af516d901223cebdbae58b32c9f.tar.bz2
linux-3.10-09e12f9f6bcd9af516d901223cebdbae58b32c9f.zip
[PATCH] tpm: locking fix
Use schedule_work() to avoid down()-in-timer-handler problem. Signed-off-by: Kylene Hall <kjhall@us.ibm.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'drivers/char')
-rw-r--r--drivers/char/tpm/tpm.c9
-rw-r--r--drivers/char/tpm/tpm.h1
2 files changed, 10 insertions, 0 deletions
diff --git a/drivers/char/tpm/tpm.c b/drivers/char/tpm/tpm.c
index 1a53da99b58..0b283d24673 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)
{
struct tpm_chip *chip = (struct tpm_chip *) ptr;
+ schedule_work(&chip->work);
+}
+
+static void timeout_work(void * ptr)
+{
+ struct tpm_chip *chip = ptr;
+
down(&chip->buffer_mutex);
atomic_set(&chip->data_pending, 0);
memset(chip->data_buffer, 0, TPM_BUFSIZE);
@@ -527,6 +534,8 @@ int tpm_register_hardware(struct device *dev, struct tpm_vendor_specific *entry)
init_MUTEX(&chip->tpm_mutex);
INIT_LIST_HEAD(&chip->list);
+ INIT_WORK(&chip->work, timeout_work, chip);
+
init_timer(&chip->user_read_timer);
chip->user_read_timer.function = user_reader_timeout;
chip->user_read_timer.data = (unsigned long) chip;
diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h
index ad51c653803..159882ca69d 100644
--- a/drivers/char/tpm/tpm.h
+++ b/drivers/char/tpm/tpm.h
@@ -77,6 +77,7 @@ struct tpm_chip {
struct semaphore buffer_mutex;
struct timer_list user_read_timer; /* user needs to claim result */
+ struct work_struct work;
struct semaphore tpm_mutex; /* tpm is processing */
struct tpm_vendor_specific *vendor;