diff options
| author | Jean Delvare <khali@linux-fr.org> | 2006-03-31 16:05:01 -0500 |
|---|---|---|
| committer | Greg Kroah-Hartman <gregkh@suse.de> | 2006-04-14 14:18:33 -0400 |
| commit | 524465df2accf54604cb89c04dbaab0c8aaa5bb4 (patch) | |
| tree | 2fd935549b981ae0c60b7fe6a50aa71b9a377347 /drivers/i2c | |
| parent | f043ca43c1ae354346f72dc5826d820d5619f0b2 (diff) | |
[PATCH] i2c: convert ds1374 to use a workqueue
A tasklet is not suitable for what the ds1374 driver does: neither sleeping
nor mutex operations are allowed in tasklets, and ds1374_set_tlet may do
both.
We can use a workqueue instead, where both sleeping and mutex operations
are allowed.
Signed-off-by: Jean Delvare <khali@linux-fr.org>
Acked-by: Randy Vinson <rvinson@mvista.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/i2c')
| -rw-r--r-- | drivers/i2c/chips/ds1374.c | 16 |
1 files changed, 10 insertions, 6 deletions
diff --git a/drivers/i2c/chips/ds1374.c b/drivers/i2c/chips/ds1374.c index 03d09ed5ec2c..4630f1969a09 100644 --- a/drivers/i2c/chips/ds1374.c +++ b/drivers/i2c/chips/ds1374.c | |||
| @@ -27,6 +27,7 @@ | |||
| 27 | #include <linux/rtc.h> | 27 | #include <linux/rtc.h> |
| 28 | #include <linux/bcd.h> | 28 | #include <linux/bcd.h> |
| 29 | #include <linux/mutex.h> | 29 | #include <linux/mutex.h> |
| 30 | #include <linux/workqueue.h> | ||
| 30 | 31 | ||
| 31 | #define DS1374_REG_TOD0 0x00 | 32 | #define DS1374_REG_TOD0 0x00 |
| 32 | #define DS1374_REG_TOD1 0x01 | 33 | #define DS1374_REG_TOD1 0x01 |
| @@ -139,7 +140,7 @@ ulong ds1374_get_rtc_time(void) | |||
| 139 | return t1; | 140 | return t1; |
| 140 | } | 141 | } |
| 141 | 142 | ||
| 142 | static void ds1374_set_tlet(ulong arg) | 143 | static void ds1374_set_work(void *arg) |
| 143 | { | 144 | { |
| 144 | ulong t1, t2; | 145 | ulong t1, t2; |
| 145 | int limit = 10; /* arbitrary retry limit */ | 146 | int limit = 10; /* arbitrary retry limit */ |
| @@ -168,17 +169,18 @@ static void ds1374_set_tlet(ulong arg) | |||
| 168 | 169 | ||
| 169 | static ulong new_time; | 170 | static ulong new_time; |
| 170 | 171 | ||
| 171 | static DECLARE_TASKLET_DISABLED(ds1374_tasklet, ds1374_set_tlet, | 172 | static struct workqueue_struct *ds1374_workqueue; |
| 172 | (ulong) & new_time); | 173 | |
| 174 | static DECLARE_WORK(ds1374_work, ds1374_set_work, &new_time); | ||
| 173 | 175 | ||
| 174 | int ds1374_set_rtc_time(ulong nowtime) | 176 | int ds1374_set_rtc_time(ulong nowtime) |
| 175 | { | 177 | { |
| 176 | new_time = nowtime; | 178 | new_time = nowtime; |
| 177 | 179 | ||
| 178 | if (in_interrupt()) | 180 | if (in_interrupt()) |
| 179 | tasklet_schedule(&ds1374_tasklet); | 181 | queue_work(ds1374_workqueue, &ds1374_work); |
| 180 | else | 182 | else |
| 181 | ds1374_set_tlet((ulong) & new_time); | 183 | ds1374_set_work(&new_time); |
| 182 | 184 | ||
| 183 | return 0; | 185 | return 0; |
| 184 | } | 186 | } |
| @@ -204,6 +206,8 @@ static int ds1374_probe(struct i2c_adapter *adap, int addr, int kind) | |||
| 204 | client->adapter = adap; | 206 | client->adapter = adap; |
| 205 | client->driver = &ds1374_driver; | 207 | client->driver = &ds1374_driver; |
| 206 | 208 | ||
| 209 | ds1374_workqueue = create_singlethread_workqueue("ds1374"); | ||
| 210 | |||
| 207 | if ((rc = i2c_attach_client(client)) != 0) { | 211 | if ((rc = i2c_attach_client(client)) != 0) { |
| 208 | kfree(client); | 212 | kfree(client); |
| 209 | return rc; | 213 | return rc; |
| @@ -227,7 +231,7 @@ static int ds1374_detach(struct i2c_client *client) | |||
| 227 | 231 | ||
| 228 | if ((rc = i2c_detach_client(client)) == 0) { | 232 | if ((rc = i2c_detach_client(client)) == 0) { |
| 229 | kfree(i2c_get_clientdata(client)); | 233 | kfree(i2c_get_clientdata(client)); |
| 230 | tasklet_kill(&ds1374_tasklet); | 234 | destroy_workqueue(ds1374_workqueue); |
| 231 | } | 235 | } |
| 232 | return rc; | 236 | return rc; |
| 233 | } | 237 | } |
