aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/misc
diff options
context:
space:
mode:
authorAlex Dubov <oakad@yahoo.com>2006-12-08 00:50:51 -0500
committerPierre Ossman <drzeus@drzeus.cx>2007-02-04 14:54:07 -0500
commit8e02f8581cd2f9c12a03be7641d5c2c427170feb (patch)
treeeef042716811ef6dcb15be51352a2405a6cc4a96 /drivers/misc
parent83d420ba92bdd52127e4548ae8050a48f655ce3b (diff)
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.c3
-rw-r--r--drivers/misc/tifm_core.c11
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)
201 fm->max_sockets == 2); 201 fm->max_sockets == 2);
202 if (media_id) { 202 if (media_id) {
203 ok_to_register = 0; 203 ok_to_register = 0;
204 new_sock = tifm_alloc_device(fm, cnt); 204 new_sock = tifm_alloc_device(fm);
205 if (new_sock) { 205 if (new_sock) {
206 new_sock->addr = tifm_7xx1_sock_addr(fm->addr, 206 new_sock->addr = tifm_7xx1_sock_addr(fm->addr,
207 cnt); 207 cnt);
208 new_sock->media_id = media_id; 208 new_sock->media_id = media_id;
209 new_sock->socket_id = cnt;
209 switch (media_id) { 210 switch (media_id) {
210 case 1: 211 case 1:
211 card_name = "xd"; 212 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);
141void tifm_free_device(struct device *dev) 141void tifm_free_device(struct device *dev)
142{ 142{
143 struct tifm_dev *fm_dev = container_of(dev, struct tifm_dev, dev); 143 struct tifm_dev *fm_dev = container_of(dev, struct tifm_dev, dev);
144 if (fm_dev->wq)
145 destroy_workqueue(fm_dev->wq);
146 kfree(fm_dev); 144 kfree(fm_dev);
147} 145}
148EXPORT_SYMBOL(tifm_free_device); 146EXPORT_SYMBOL(tifm_free_device);
149 147
150struct tifm_dev *tifm_alloc_device(struct tifm_adapter *fm, unsigned int id) 148struct tifm_dev *tifm_alloc_device(struct tifm_adapter *fm)
151{ 149{
152 struct tifm_dev *dev = kzalloc(sizeof(struct tifm_dev), GFP_KERNEL); 150 struct tifm_dev *dev = kzalloc(sizeof(struct tifm_dev), GFP_KERNEL);
153 151
154 if (dev) { 152 if (dev) {
155 spin_lock_init(&dev->lock); 153 spin_lock_init(&dev->lock);
156 snprintf(dev->wq_name, KOBJ_NAME_LEN, "tifm%u:%u", fm->id, id); 154
157 dev->wq = create_singlethread_workqueue(dev->wq_name);
158 if (!dev->wq) {
159 kfree(dev);
160 return NULL;
161 }
162 dev->dev.parent = fm->dev; 155 dev->dev.parent = fm->dev;
163 dev->dev.bus = &tifm_bus_type; 156 dev->dev.bus = &tifm_bus_type;
164 dev->dev.release = tifm_free_device; 157 dev->dev.release = tifm_free_device;