Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[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>

authored by

Jean Delvare and committed by
Greg Kroah-Hartman
524465df f043ca43

+10 -6
+10 -6
drivers/i2c/chips/ds1374.c
··· 27 27 #include <linux/rtc.h> 28 28 #include <linux/bcd.h> 29 29 #include <linux/mutex.h> 30 + #include <linux/workqueue.h> 30 31 31 32 #define DS1374_REG_TOD0 0x00 32 33 #define DS1374_REG_TOD1 0x01 ··· 140 139 return t1; 141 140 } 142 141 143 - static void ds1374_set_tlet(ulong arg) 142 + static void ds1374_set_work(void *arg) 144 143 { 145 144 ulong t1, t2; 146 145 int limit = 10; /* arbitrary retry limit */ ··· 169 168 170 169 static ulong new_time; 171 170 172 - static DECLARE_TASKLET_DISABLED(ds1374_tasklet, ds1374_set_tlet, 173 - (ulong) & new_time); 171 + static struct workqueue_struct *ds1374_workqueue; 172 + 173 + static DECLARE_WORK(ds1374_work, ds1374_set_work, &new_time); 174 174 175 175 int ds1374_set_rtc_time(ulong nowtime) 176 176 { 177 177 new_time = nowtime; 178 178 179 179 if (in_interrupt()) 180 - tasklet_schedule(&ds1374_tasklet); 180 + queue_work(ds1374_workqueue, &ds1374_work); 181 181 else 182 - ds1374_set_tlet((ulong) & new_time); 182 + ds1374_set_work(&new_time); 183 183 184 184 return 0; 185 185 } ··· 206 204 client->adapter = adap; 207 205 client->driver = &ds1374_driver; 208 206 207 + ds1374_workqueue = create_singlethread_workqueue("ds1374"); 208 + 209 209 if ((rc = i2c_attach_client(client)) != 0) { 210 210 kfree(client); 211 211 return rc; ··· 231 227 232 228 if ((rc = i2c_detach_client(client)) == 0) { 233 229 kfree(i2c_get_clientdata(client)); 234 - tasklet_kill(&ds1374_tasklet); 230 + destroy_workqueue(ds1374_workqueue); 235 231 } 236 232 return rc; 237 233 }