[PATCH] char/tpm: use msleep(), clean-up timers,
Nishanth Aravamudan [Fri, 24 Jun 2005 05:01:47 +0000 (22:01 -0700)]
The TPM driver unnecessarily uses timers when it simply needs to maintain a
maximum delay via time_before().  msleep() is used instead of
schedule_timeout() to guarantee the task delays as expected.  While
compile-testing, I found a typo in the driver, using tpm_chp instead of
tpm_chip.  Remove the now unused timer callback function and change
TPM_TIMEOUT's units to milliseconds.  Patch is compile-tested.

Signed-off-by: Nishanth Aravamudan <nacc@us.ibm.com>
Acked-by: Kylene Hall <kjhall@us.ibm.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>

drivers/char/tpm/tpm.c
drivers/char/tpm/tpm.h
drivers/char/tpm/tpm_nsc.c

index 8ce508b..c937ea2 100644 (file)
@@ -19,7 +19,7 @@
  * 
  * Note, the TPM chip is not interrupt driven (only polling)
  * and can have very long timeouts (minutes!). Hence the unusual
- * calls to schedule_timeout.
+ * calls to msleep.
  *
  */
 
@@ -52,14 +52,6 @@ static void user_reader_timeout(unsigned long ptr)
        up(&chip->buffer_mutex);
 }
 
-void tpm_time_expired(unsigned long ptr)
-{
-       int *exp = (int *) ptr;
-       *exp = 1;
-}
-
-EXPORT_SYMBOL_GPL(tpm_time_expired);
-
 /*
  * Initialize the LPC bus and enable the TPM ports
  */
@@ -135,6 +127,7 @@ static ssize_t tpm_transmit(struct tpm_chip *chip, const char *buf,
        ssize_t len;
        u32 count;
        __be32 *native_size;
+       unsigned long stop;
 
        native_size = (__force __be32 *) (buf + 2);
        count = be32_to_cpu(*native_size);
@@ -155,28 +148,16 @@ static ssize_t tpm_transmit(struct tpm_chip *chip, const char *buf,
                return len;
        }
 
-       down(&chip->timer_manipulation_mutex);
-       chip->time_expired = 0;
-       init_timer(&chip->device_timer);
-       chip->device_timer.function = tpm_time_expired;
-       chip->device_timer.expires = jiffies + 2 * 60 * HZ;
-       chip->device_timer.data = (unsigned long) &chip->time_expired;
-       add_timer(&chip->device_timer);
-       up(&chip->timer_manipulation_mutex);
-
+       stop = jiffies + 2 * 60 * HZ;
        do {
                u8 status = inb(chip->vendor->base + 1);
                if ((status & chip->vendor->req_complete_mask) ==
                    chip->vendor->req_complete_val) {
-                       down(&chip->timer_manipulation_mutex);
-                       del_singleshot_timer_sync(&chip->device_timer);
-                       up(&chip->timer_manipulation_mutex);
                        goto out_recv;
                }
-               set_current_state(TASK_UNINTERRUPTIBLE);
-               schedule_timeout(TPM_TIMEOUT);
+               msleep(TPM_TIMEOUT); /* CHECK */
                rmb();
-       } while (!chip->time_expired);
+       } while (time_before(jiffies, stop));
 
 
        chip->vendor->cancel(chip);
@@ -453,10 +434,8 @@ ssize_t tpm_write(struct file * file, const char __user * buf,
 
        /* cannot perform a write until the read has cleared
           either via tpm_read or a user_read_timer timeout */
-       while (atomic_read(&chip->data_pending) != 0) {
-               set_current_state(TASK_UNINTERRUPTIBLE);
-               schedule_timeout(TPM_TIMEOUT);
-       }
+       while (atomic_read(&chip->data_pending) != 0)
+               msleep(TPM_TIMEOUT);
 
        down(&chip->buffer_mutex);
 
index de0c796..3c4ee43 100644 (file)
@@ -25,7 +25,7 @@
 #include <linux/fs.h>
 #include <linux/miscdevice.h>
 
-#define TPM_TIMEOUT msecs_to_jiffies(5)
+#define TPM_TIMEOUT    5       /* msecs */
 
 /* TPM addresses */
 #define        TPM_ADDR                        0x4E
@@ -78,7 +78,6 @@ static inline void tpm_write_index(int index, int value)
        outb(value & 0xFF, TPM_DATA);
 }
 
-extern void tpm_time_expired(unsigned long);
 extern int tpm_lpc_bus_init(struct pci_dev *, u16);
 
 extern int tpm_register_hardware(struct pci_dev *,
index 9cce833..6e5ffca 100644 (file)
  */
 static int wait_for_stat(struct tpm_chip *chip, u8 mask, u8 val, u8 * data)
 {
-       int expired = 0;
-       struct timer_list status_timer =
-           TIMER_INITIALIZER(tpm_time_expired, jiffies + 10 * HZ,
-                             (unsigned long) &expired);
+       unsigned long stop;
 
        /* status immediately available check */
        *data = inb(chip->vendor->base + NSC_STATUS);
@@ -66,17 +63,14 @@ static int wait_for_stat(struct tpm_chip *chip, u8 mask, u8 val, u8 * data)
                return 0;
 
        /* wait for status */
-       add_timer(&status_timer);
+       stop = jiffies + 10 * HZ;
        do {
-               set_current_state(TASK_UNINTERRUPTIBLE);
-               schedule_timeout(TPM_TIMEOUT);
+               msleep(TPM_TIMEOUT);
                *data = inb(chip->vendor->base + 1);
-               if ((*data & mask) == val) {
-                       del_singleshot_timer_sync(&status_timer);
+               if ((*data & mask) == val)
                        return 0;
-               }
        }
-       while (!expired);
+       while (time_before(jiffies, stop));
 
        return -EBUSY;
 }
@@ -84,10 +78,7 @@ static int wait_for_stat(struct tpm_chip *chip, u8 mask, u8 val, u8 * data)
 static int nsc_wait_for_ready(struct tpm_chip *chip)
 {
        int status;
-       int expired = 0;
-       struct timer_list status_timer =
-           TIMER_INITIALIZER(tpm_time_expired, jiffies + 100,
-                             (unsigned long) &expired);
+       unsigned long stop;
 
        /* status immediately available check */
        status = inb(chip->vendor->base + NSC_STATUS);
@@ -97,19 +88,16 @@ static int nsc_wait_for_ready(struct tpm_chip *chip)
                return 0;
 
        /* wait for status */
-       add_timer(&status_timer);
+       stop = jiffies + 100;
        do {
-               set_current_state(TASK_UNINTERRUPTIBLE);
-               schedule_timeout(TPM_TIMEOUT);
+               msleep(TPM_TIMEOUT);
                status = inb(chip->vendor->base + NSC_STATUS);
                if (status & NSC_STATUS_OBF)
                        status = inb(chip->vendor->base + NSC_DATA);
-               if (status & NSC_STATUS_RDY) {
-                       del_singleshot_timer_sync(&status_timer);
+               if (status & NSC_STATUS_RDY)
                        return 0;
-               }
        }
-       while (!expired);
+       while (time_before(jiffies, stop));
 
        dev_info(&chip->pci_dev->dev, "wait for ready failed\n");
        return -EBUSY;