diff options
author | Alex Dubov <oakad@yahoo.com> | 2006-12-08 16:50:51 +1100 |
---|---|---|
committer | Pierre Ossman <drzeus@drzeus.cx> | 2007-02-04 20:54:07 +0100 |
commit | 8e02f8581cd2f9c12a03be7641d5c2c427170feb (patch) | |
tree | eef042716811ef6dcb15be51352a2405a6cc4a96 /drivers/misc | |
parent | 83d420ba92bdd52127e4548ae8050a48f655ce3b (diff) | |
download | linux-8e02f8581cd2f9c12a03be7641d5c2c427170feb.tar.gz linux-8e02f8581cd2f9c12a03be7641d5c2c427170feb.tar.bz2 linux-8e02f8581cd2f9c12a03be7641d5c2c427170feb.zip |
tifm_sd: restructure initialization, removal and command handling
In order to support correct suspend and resume several changes were needed:
1. Switch from work_struct to tasklet for command handling. When device
suspend is called workqueues are already frozen and can not be used.
2. Separate host initialization code from driver's probe and don't rely
on interrupts for host initialization. This, in turn, addresses two
problems:
a) Resume needs to re-initialize the host, but can not assume that
device interrupts were already re-armed.
b) Previously, probe will return successfully before really knowing
the state of the host, as host interrupts were not armed in time.
Now it uses polling to determine the real host state before returning.
3. Separate termination code from driver's remove. Termination may be caused
by resume, if media changed type or became unavailable during suspend.
Signed-off-by: Alex Dubov <oakad@yahoo.com>
Signed-off-by: Pierre Ossman <drzeus@drzeus.cx>
Diffstat (limited to 'drivers/misc')
-rw-r--r-- | drivers/misc/tifm_7xx1.c | 3 | ||||
-rw-r--r-- | drivers/misc/tifm_core.c | 11 |
2 files changed, 4 insertions, 10 deletions
diff --git a/drivers/misc/tifm_7xx1.c b/drivers/misc/tifm_7xx1.c index 2ab7add78f94..50c4cdabb654 100644 --- a/drivers/misc/tifm_7xx1.c +++ b/drivers/misc/tifm_7xx1.c @@ -201,11 +201,12 @@ static void tifm_7xx1_insert_media(struct work_struct *work) fm->max_sockets == 2); if (media_id) { ok_to_register = 0; - new_sock = tifm_alloc_device(fm, cnt); + new_sock = tifm_alloc_device(fm); if (new_sock) { new_sock->addr = tifm_7xx1_sock_addr(fm->addr, cnt); new_sock->media_id = media_id; + new_sock->socket_id = cnt; switch (media_id) { case 1: card_name = "xd"; diff --git a/drivers/misc/tifm_core.c b/drivers/misc/tifm_core.c index d61df5c3ac36..21eb0ab7c329 100644 --- a/drivers/misc/tifm_core.c +++ b/drivers/misc/tifm_core.c @@ -141,24 +141,17 @@ EXPORT_SYMBOL(tifm_remove_adapter); void tifm_free_device(struct device *dev) { struct tifm_dev *fm_dev = container_of(dev, struct tifm_dev, dev); - if (fm_dev->wq) - destroy_workqueue(fm_dev->wq); kfree(fm_dev); } EXPORT_SYMBOL(tifm_free_device); -struct tifm_dev *tifm_alloc_device(struct tifm_adapter *fm, unsigned int id) +struct tifm_dev *tifm_alloc_device(struct tifm_adapter *fm) { struct tifm_dev *dev = kzalloc(sizeof(struct tifm_dev), GFP_KERNEL); if (dev) { spin_lock_init(&dev->lock); - snprintf(dev->wq_name, KOBJ_NAME_LEN, "tifm%u:%u", fm->id, id); - dev->wq = create_singlethread_workqueue(dev->wq_name); - if (!dev->wq) { - kfree(dev); - return NULL; - } + dev->dev.parent = fm->dev; dev->dev.bus = &tifm_bus_type; dev->dev.release = tifm_free_device; |