aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/i2c/chips/ds1374.c
diff options
context:
space:
mode:
authorJean Delvare <khali@linux-fr.org>2006-03-31 16:05:01 -0500
committerGreg Kroah-Hartman <gregkh@suse.de>2006-04-14 14:18:33 -0400
commit524465df2accf54604cb89c04dbaab0c8aaa5bb4 (patch)
tree2fd935549b981ae0c60b7fe6a50aa71b9a377347 /drivers/i2c/chips/ds1374.c
parentf043ca43c1ae354346f72dc5826d820d5619f0b2 (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/chips/ds1374.c')
-rw-r--r--drivers/i2c/chips/ds1374.c16
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
142static void ds1374_set_tlet(ulong arg) 143static 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
169static ulong new_time; 170static ulong new_time;
170 171
171static DECLARE_TASKLET_DISABLED(ds1374_tasklet, ds1374_set_tlet, 172static struct workqueue_struct *ds1374_workqueue;
172 (ulong) & new_time); 173
174static DECLARE_WORK(ds1374_work, ds1374_set_work, &new_time);
173 175
174int ds1374_set_rtc_time(ulong nowtime) 176int 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}