diff options
-rw-r--r-- | drivers/char/tpm/tpm_tis.c | 28 |
1 files changed, 23 insertions, 5 deletions
diff --git a/drivers/char/tpm/tpm_tis.c b/drivers/char/tpm/tpm_tis.c index 88de8fc41586..b97ce2b205d7 100644 --- a/drivers/char/tpm/tpm_tis.c +++ b/drivers/char/tpm/tpm_tis.c | |||
@@ -26,6 +26,7 @@ | |||
26 | #include <linux/interrupt.h> | 26 | #include <linux/interrupt.h> |
27 | #include <linux/wait.h> | 27 | #include <linux/wait.h> |
28 | #include <linux/acpi.h> | 28 | #include <linux/acpi.h> |
29 | #include <linux/freezer.h> | ||
29 | #include "tpm.h" | 30 | #include "tpm.h" |
30 | 31 | ||
31 | #define TPM_HEADER_SIZE 10 | 32 | #define TPM_HEADER_SIZE 10 |
@@ -120,7 +121,7 @@ static void release_locality(struct tpm_chip *chip, int l, int force) | |||
120 | 121 | ||
121 | static int request_locality(struct tpm_chip *chip, int l) | 122 | static int request_locality(struct tpm_chip *chip, int l) |
122 | { | 123 | { |
123 | unsigned long stop; | 124 | unsigned long stop, timeout; |
124 | long rc; | 125 | long rc; |
125 | 126 | ||
126 | if (check_locality(chip, l) >= 0) | 127 | if (check_locality(chip, l) >= 0) |
@@ -129,17 +130,25 @@ static int request_locality(struct tpm_chip *chip, int l) | |||
129 | iowrite8(TPM_ACCESS_REQUEST_USE, | 130 | iowrite8(TPM_ACCESS_REQUEST_USE, |
130 | chip->vendor.iobase + TPM_ACCESS(l)); | 131 | chip->vendor.iobase + TPM_ACCESS(l)); |
131 | 132 | ||
133 | stop = jiffies + chip->vendor.timeout_a; | ||
134 | |||
132 | if (chip->vendor.irq) { | 135 | if (chip->vendor.irq) { |
136 | again: | ||
137 | timeout = stop - jiffies; | ||
138 | if ((long)timeout <= 0) | ||
139 | return -1; | ||
133 | rc = wait_event_interruptible_timeout(chip->vendor.int_queue, | 140 | rc = wait_event_interruptible_timeout(chip->vendor.int_queue, |
134 | (check_locality | 141 | (check_locality |
135 | (chip, l) >= 0), | 142 | (chip, l) >= 0), |
136 | chip->vendor.timeout_a); | 143 | timeout); |
137 | if (rc > 0) | 144 | if (rc > 0) |
138 | return l; | 145 | return l; |
139 | 146 | if (rc == -ERESTARTSYS && freezing(current)) { | |
147 | clear_thread_flag(TIF_SIGPENDING); | ||
148 | goto again; | ||
149 | } | ||
140 | } else { | 150 | } else { |
141 | /* wait for burstcount */ | 151 | /* wait for burstcount */ |
142 | stop = jiffies + chip->vendor.timeout_a; | ||
143 | do { | 152 | do { |
144 | if (check_locality(chip, l) >= 0) | 153 | if (check_locality(chip, l) >= 0) |
145 | return l; | 154 | return l; |
@@ -196,15 +205,24 @@ static int wait_for_stat(struct tpm_chip *chip, u8 mask, unsigned long timeout, | |||
196 | if ((status & mask) == mask) | 205 | if ((status & mask) == mask) |
197 | return 0; | 206 | return 0; |
198 | 207 | ||
208 | stop = jiffies + timeout; | ||
209 | |||
199 | if (chip->vendor.irq) { | 210 | if (chip->vendor.irq) { |
211 | again: | ||
212 | timeout = stop - jiffies; | ||
213 | if ((long)timeout <= 0) | ||
214 | return -ETIME; | ||
200 | rc = wait_event_interruptible_timeout(*queue, | 215 | rc = wait_event_interruptible_timeout(*queue, |
201 | ((tpm_tis_status | 216 | ((tpm_tis_status |
202 | (chip) & mask) == | 217 | (chip) & mask) == |
203 | mask), timeout); | 218 | mask), timeout); |
204 | if (rc > 0) | 219 | if (rc > 0) |
205 | return 0; | 220 | return 0; |
221 | if (rc == -ERESTARTSYS && freezing(current)) { | ||
222 | clear_thread_flag(TIF_SIGPENDING); | ||
223 | goto again; | ||
224 | } | ||
206 | } else { | 225 | } else { |
207 | stop = jiffies + timeout; | ||
208 | do { | 226 | do { |
209 | msleep(TPM_TIMEOUT); | 227 | msleep(TPM_TIMEOUT); |
210 | status = tpm_tis_status(chip); | 228 | status = tpm_tis_status(chip); |