diff options
author | Jonathan Corbet <corbet@lwn.net> | 2008-05-16 15:53:00 -0400 |
---|---|---|
committer | Jonathan Corbet <corbet@lwn.net> | 2008-06-20 16:05:51 -0400 |
commit | b8c71d7ae2a7f723d171d9175212b6d0a727655d (patch) | |
tree | 26bc87aac3c7f683dfe7c7aadf8ce112a9e48778 /drivers/char/tlclk.c | |
parent | f4943db14f5071ecbf7ca76722e59a2fd22bda4d (diff) |
tlckl: BKL pushdown
Put explicit lock_kernel calls into tlclk_open()
Signed-off-by: Jonathan Corbet <corbet@lwn.net>
Diffstat (limited to 'drivers/char/tlclk.c')
-rw-r--r-- | drivers/char/tlclk.c | 19 |
1 files changed, 12 insertions, 7 deletions
diff --git a/drivers/char/tlclk.c b/drivers/char/tlclk.c index 35e58030d296..8f2284be68e1 100644 --- a/drivers/char/tlclk.c +++ b/drivers/char/tlclk.c | |||
@@ -36,6 +36,7 @@ | |||
36 | #include <linux/ioport.h> | 36 | #include <linux/ioport.h> |
37 | #include <linux/interrupt.h> | 37 | #include <linux/interrupt.h> |
38 | #include <linux/spinlock.h> | 38 | #include <linux/spinlock.h> |
39 | #include <linux/smp_lock.h> | ||
39 | #include <linux/timer.h> | 40 | #include <linux/timer.h> |
40 | #include <linux/sysfs.h> | 41 | #include <linux/sysfs.h> |
41 | #include <linux/device.h> | 42 | #include <linux/device.h> |
@@ -204,11 +205,14 @@ static int tlclk_open(struct inode *inode, struct file *filp) | |||
204 | { | 205 | { |
205 | int result; | 206 | int result; |
206 | 207 | ||
207 | if (test_and_set_bit(0, &useflags)) | 208 | lock_kernel(); |
208 | return -EBUSY; | 209 | if (test_and_set_bit(0, &useflags)) { |
210 | result = -EBUSY; | ||
209 | /* this legacy device is always one per system and it doesn't | 211 | /* this legacy device is always one per system and it doesn't |
210 | * know how to handle multiple concurrent clients. | 212 | * know how to handle multiple concurrent clients. |
211 | */ | 213 | */ |
214 | goto out; | ||
215 | } | ||
212 | 216 | ||
213 | /* Make sure there is no interrupt pending while | 217 | /* Make sure there is no interrupt pending while |
214 | * initialising interrupt handler */ | 218 | * initialising interrupt handler */ |
@@ -218,13 +222,14 @@ static int tlclk_open(struct inode *inode, struct file *filp) | |||
218 | * we can't share this IRQ */ | 222 | * we can't share this IRQ */ |
219 | result = request_irq(telclk_interrupt, &tlclk_interrupt, | 223 | result = request_irq(telclk_interrupt, &tlclk_interrupt, |
220 | IRQF_DISABLED, "telco_clock", tlclk_interrupt); | 224 | IRQF_DISABLED, "telco_clock", tlclk_interrupt); |
221 | if (result == -EBUSY) { | 225 | if (result == -EBUSY) |
222 | printk(KERN_ERR "tlclk: Interrupt can't be reserved.\n"); | 226 | printk(KERN_ERR "tlclk: Interrupt can't be reserved.\n"); |
223 | return -EBUSY; | 227 | else |
224 | } | 228 | inb(TLCLK_REG6); /* Clear interrupt events */ |
225 | inb(TLCLK_REG6); /* Clear interrupt events */ | ||
226 | 229 | ||
227 | return 0; | 230 | out: |
231 | unlock_kernel(); | ||
232 | return result; | ||
228 | } | 233 | } |
229 | 234 | ||
230 | static int tlclk_release(struct inode *inode, struct file *filp) | 235 | static int tlclk_release(struct inode *inode, struct file *filp) |