From 3540af8ffddcdbc7573451ac0b5cd57a2eaf8af5 Mon Sep 17 00:00:00 2001 From: Alex Dubov Date: Thu, 12 Apr 2007 16:59:15 +1000 Subject: tifm: replace per-adapter kthread with freezeable workqueue Freezeable workqueue makes sure that adapter work items (device insertions and removals) would be handled after the system is fully resumed. Previously this was achieved by explicit freezing of the kthread. Signed-off-by: Alex Dubov Signed-off-by: Pierre Ossman --- drivers/misc/tifm_core.c | 51 ++++++++++++++++++++++++++++++++---------------- 1 file changed, 34 insertions(+), 17 deletions(-) (limited to 'drivers/misc/tifm_core.c') diff --git a/drivers/misc/tifm_core.c b/drivers/misc/tifm_core.c index 6b2c447dc8ee..ef8a97b819dd 100644 --- a/drivers/misc/tifm_core.c +++ b/drivers/misc/tifm_core.c @@ -16,6 +16,7 @@ #define DRIVER_NAME "tifm_core" #define DRIVER_VERSION "0.8" +static struct workqueue_struct *workqueue; static DEFINE_IDR(tifm_adapter_idr); static DEFINE_SPINLOCK(tifm_adapter_lock); @@ -184,8 +185,7 @@ void tifm_free_adapter(struct tifm_adapter *fm) } EXPORT_SYMBOL(tifm_free_adapter); -int tifm_add_adapter(struct tifm_adapter *fm, - int (*mediathreadfn)(void *data)) +int tifm_add_adapter(struct tifm_adapter *fm) { int rc; @@ -197,16 +197,13 @@ int tifm_add_adapter(struct tifm_adapter *fm, spin_unlock(&tifm_adapter_lock); if (!rc) { snprintf(fm->cdev.class_id, BUS_ID_SIZE, "tifm%u", fm->id); - fm->media_switcher = kthread_create(mediathreadfn, - fm, "tifm/%u", fm->id); + rc = class_device_add(&fm->cdev); - if (!IS_ERR(fm->media_switcher)) - return class_device_add(&fm->cdev); - - spin_lock(&tifm_adapter_lock); - idr_remove(&tifm_adapter_idr, fm->id); - spin_unlock(&tifm_adapter_lock); - rc = -ENOMEM; + if (rc) { + spin_lock(&tifm_adapter_lock); + idr_remove(&tifm_adapter_idr, fm->id); + spin_unlock(&tifm_adapter_lock); + } } return rc; } @@ -214,6 +211,7 @@ EXPORT_SYMBOL(tifm_add_adapter); void tifm_remove_adapter(struct tifm_adapter *fm) { + flush_workqueue(workqueue); class_device_del(&fm->cdev); spin_lock(&tifm_adapter_lock); @@ -267,6 +265,12 @@ void tifm_unmap_sg(struct tifm_dev *sock, struct scatterlist *sg, int nents, } EXPORT_SYMBOL(tifm_unmap_sg); +void tifm_queue_work(struct work_struct *work) +{ + queue_work(workqueue, work); +} +EXPORT_SYMBOL(tifm_queue_work); + int tifm_register_driver(struct tifm_driver *drv) { drv->driver.bus = &tifm_bus_type; @@ -283,13 +287,25 @@ EXPORT_SYMBOL(tifm_unregister_driver); static int __init tifm_init(void) { - int rc = bus_register(&tifm_bus_type); + int rc; - if (!rc) { - rc = class_register(&tifm_adapter_class); - if (rc) - bus_unregister(&tifm_bus_type); - } + workqueue = create_freezeable_workqueue("tifm"); + if (!workqueue) + return -ENOMEM; + + rc = bus_register(&tifm_bus_type); + + if (rc) + goto err_out_wq; + + rc = class_register(&tifm_adapter_class); + if (!rc) + return 0; + + bus_unregister(&tifm_bus_type); + +err_out_wq: + destroy_workqueue(workqueue); return rc; } @@ -298,6 +314,7 @@ static void __exit tifm_exit(void) { class_unregister(&tifm_adapter_class); bus_unregister(&tifm_bus_type); + destroy_workqueue(workqueue); } subsys_initcall(tifm_init); -- cgit v1.2.3