aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/misc/tifm_7xx1.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@woody.linux-foundation.org>2007-05-05 00:44:34 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-05-05 00:44:34 -0400
commit62ea6d80211ecc88ef516927ecebf64cb505be3f (patch)
tree1920de8cd3671aedcc912afb8e5ddb2a7c674b05 /drivers/misc/tifm_7xx1.c
parentfa24aa561a3cf91cf25b5d4066470b08a2d24206 (diff)
parentd3af5abe9a809becbe4b413144b607844560d445 (diff)
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/drzeus/mmc
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/drzeus/mmc: (46 commits) mmc-omap: Clean up omap set_ios and make MMC_POWER_ON work mmc-omap: Fix omap to use MMC_POWER_ON mmc-omap: add missing '\n' mmc: make tifm_sd_set_dma_data() static mmc: remove old card states mmc: support unsafe resume of cards mmc: separate out reading EXT_CSD mmc: break apart switch function MMC: Fix handling of low-voltage cards MMC: Consolidate voltage definitions mmc: add bus handler wbsd: check for data opcode earlier mmc: Separate out protocol ops mmc: Move core functions to subdir mmc: deprecate mmc bus topology mmc: remove card upon suspend mmc: allow suspended block driver to be removed mmc: Flush pending detects on host removal mmc: Move host and card drivers to subdirs mmc: Move queue functions to mmc_block ...
Diffstat (limited to 'drivers/misc/tifm_7xx1.c')
-rw-r--r--drivers/misc/tifm_7xx1.c332
1 files changed, 141 insertions, 191 deletions
diff --git a/drivers/misc/tifm_7xx1.c b/drivers/misc/tifm_7xx1.c
index bc60e2fc3c2c..1ba6c085419a 100644
--- a/drivers/misc/tifm_7xx1.c
+++ b/drivers/misc/tifm_7xx1.c
@@ -11,10 +11,20 @@
11 11
12#include <linux/tifm.h> 12#include <linux/tifm.h>
13#include <linux/dma-mapping.h> 13#include <linux/dma-mapping.h>
14#include <linux/freezer.h>
15 14
16#define DRIVER_NAME "tifm_7xx1" 15#define DRIVER_NAME "tifm_7xx1"
17#define DRIVER_VERSION "0.7" 16#define DRIVER_VERSION "0.8"
17
18#define TIFM_IRQ_ENABLE 0x80000000
19#define TIFM_IRQ_SOCKMASK(x) (x)
20#define TIFM_IRQ_CARDMASK(x) ((x) << 8)
21#define TIFM_IRQ_FIFOMASK(x) ((x) << 16)
22#define TIFM_IRQ_SETALL 0xffffffff
23
24static void tifm_7xx1_dummy_eject(struct tifm_adapter *fm,
25 struct tifm_dev *sock)
26{
27}
18 28
19static void tifm_7xx1_eject(struct tifm_adapter *fm, struct tifm_dev *sock) 29static void tifm_7xx1_eject(struct tifm_adapter *fm, struct tifm_dev *sock)
20{ 30{
@@ -22,7 +32,7 @@ static void tifm_7xx1_eject(struct tifm_adapter *fm, struct tifm_dev *sock)
22 32
23 spin_lock_irqsave(&fm->lock, flags); 33 spin_lock_irqsave(&fm->lock, flags);
24 fm->socket_change_set |= 1 << sock->socket_id; 34 fm->socket_change_set |= 1 << sock->socket_id;
25 wake_up_all(&fm->change_set_notify); 35 tifm_queue_work(&fm->media_switcher);
26 spin_unlock_irqrestore(&fm->lock, flags); 36 spin_unlock_irqrestore(&fm->lock, flags);
27} 37}
28 38
@@ -30,8 +40,7 @@ static irqreturn_t tifm_7xx1_isr(int irq, void *dev_id)
30{ 40{
31 struct tifm_adapter *fm = dev_id; 41 struct tifm_adapter *fm = dev_id;
32 struct tifm_dev *sock; 42 struct tifm_dev *sock;
33 unsigned int irq_status; 43 unsigned int irq_status, cnt;
34 unsigned int sock_irq_status, cnt;
35 44
36 spin_lock(&fm->lock); 45 spin_lock(&fm->lock);
37 irq_status = readl(fm->addr + FM_INTERRUPT_STATUS); 46 irq_status = readl(fm->addr + FM_INTERRUPT_STATUS);
@@ -45,12 +54,12 @@ static irqreturn_t tifm_7xx1_isr(int irq, void *dev_id)
45 54
46 for (cnt = 0; cnt < fm->num_sockets; cnt++) { 55 for (cnt = 0; cnt < fm->num_sockets; cnt++) {
47 sock = fm->sockets[cnt]; 56 sock = fm->sockets[cnt];
48 sock_irq_status = (irq_status >> cnt) 57 if (sock) {
49 & (TIFM_IRQ_FIFOMASK(1) 58 if ((irq_status >> cnt) & TIFM_IRQ_FIFOMASK(1))
50 | TIFM_IRQ_CARDMASK(1)); 59 sock->data_event(sock);
51 60 if ((irq_status >> cnt) & TIFM_IRQ_CARDMASK(1))
52 if (sock && sock_irq_status) 61 sock->card_event(sock);
53 sock->signal_irq(sock, sock_irq_status); 62 }
54 } 63 }
55 64
56 fm->socket_change_set |= irq_status 65 fm->socket_change_set |= irq_status
@@ -58,57 +67,57 @@ static irqreturn_t tifm_7xx1_isr(int irq, void *dev_id)
58 } 67 }
59 writel(irq_status, fm->addr + FM_INTERRUPT_STATUS); 68 writel(irq_status, fm->addr + FM_INTERRUPT_STATUS);
60 69
61 if (!fm->socket_change_set) 70 if (fm->finish_me)
71 complete_all(fm->finish_me);
72 else if (!fm->socket_change_set)
62 writel(TIFM_IRQ_ENABLE, fm->addr + FM_SET_INTERRUPT_ENABLE); 73 writel(TIFM_IRQ_ENABLE, fm->addr + FM_SET_INTERRUPT_ENABLE);
63 else 74 else
64 wake_up_all(&fm->change_set_notify); 75 tifm_queue_work(&fm->media_switcher);
65 76
66 spin_unlock(&fm->lock); 77 spin_unlock(&fm->lock);
67 return IRQ_HANDLED; 78 return IRQ_HANDLED;
68} 79}
69 80
70static tifm_media_id tifm_7xx1_toggle_sock_power(char __iomem *sock_addr, 81static unsigned char tifm_7xx1_toggle_sock_power(char __iomem *sock_addr)
71 int is_x2)
72{ 82{
73 unsigned int s_state; 83 unsigned int s_state;
74 int cnt; 84 int cnt;
75 85
76 writel(0x0e00, sock_addr + SOCK_CONTROL); 86 writel(0x0e00, sock_addr + SOCK_CONTROL);
77 87
78 for (cnt = 0; cnt < 100; cnt++) { 88 for (cnt = 16; cnt <= 256; cnt <<= 1) {
79 if (!(TIFM_SOCK_STATE_POWERED 89 if (!(TIFM_SOCK_STATE_POWERED
80 & readl(sock_addr + SOCK_PRESENT_STATE))) 90 & readl(sock_addr + SOCK_PRESENT_STATE)))
81 break; 91 break;
82 msleep(10); 92
93 msleep(cnt);
83 } 94 }
84 95
85 s_state = readl(sock_addr + SOCK_PRESENT_STATE); 96 s_state = readl(sock_addr + SOCK_PRESENT_STATE);
86 if (!(TIFM_SOCK_STATE_OCCUPIED & s_state)) 97 if (!(TIFM_SOCK_STATE_OCCUPIED & s_state))
87 return FM_NULL; 98 return 0;
88
89 if (is_x2) {
90 writel((s_state & 7) | 0x0c00, sock_addr + SOCK_CONTROL);
91 } else {
92 // SmartMedia cards need extra 40 msec
93 if (((readl(sock_addr + SOCK_PRESENT_STATE) >> 4) & 7) == 1)
94 msleep(40);
95 writel(readl(sock_addr + SOCK_CONTROL) | TIFM_CTRL_LED,
96 sock_addr + SOCK_CONTROL);
97 msleep(10);
98 writel((s_state & 0x7) | 0x0c00 | TIFM_CTRL_LED,
99 sock_addr + SOCK_CONTROL);
100 }
101 99
102 for (cnt = 0; cnt < 100; cnt++) { 100 writel(readl(sock_addr + SOCK_CONTROL) | TIFM_CTRL_LED,
101 sock_addr + SOCK_CONTROL);
102
103 /* xd needs some extra time before power on */
104 if (((readl(sock_addr + SOCK_PRESENT_STATE) >> 4) & 7)
105 == TIFM_TYPE_XD)
106 msleep(40);
107
108 writel((s_state & 7) | 0x0c00, sock_addr + SOCK_CONTROL);
109 /* wait for power to stabilize */
110 msleep(20);
111 for (cnt = 16; cnt <= 256; cnt <<= 1) {
103 if ((TIFM_SOCK_STATE_POWERED 112 if ((TIFM_SOCK_STATE_POWERED
104 & readl(sock_addr + SOCK_PRESENT_STATE))) 113 & readl(sock_addr + SOCK_PRESENT_STATE)))
105 break; 114 break;
106 msleep(10); 115
116 msleep(cnt);
107 } 117 }
108 118
109 if (!is_x2) 119 writel(readl(sock_addr + SOCK_CONTROL) & (~TIFM_CTRL_LED),
110 writel(readl(sock_addr + SOCK_CONTROL) & (~TIFM_CTRL_LED), 120 sock_addr + SOCK_CONTROL);
111 sock_addr + SOCK_CONTROL);
112 121
113 return (readl(sock_addr + SOCK_PRESENT_STATE) >> 4) & 7; 122 return (readl(sock_addr + SOCK_PRESENT_STATE) >> 4) & 7;
114} 123}
@@ -119,127 +128,77 @@ tifm_7xx1_sock_addr(char __iomem *base_addr, unsigned int sock_num)
119 return base_addr + ((sock_num + 1) << 10); 128 return base_addr + ((sock_num + 1) << 10);
120} 129}
121 130
122static int tifm_7xx1_switch_media(void *data) 131static void tifm_7xx1_switch_media(struct work_struct *work)
123{ 132{
124 struct tifm_adapter *fm = data; 133 struct tifm_adapter *fm = container_of(work, struct tifm_adapter,
125 unsigned long flags; 134 media_switcher);
126 tifm_media_id media_id;
127 char *card_name = "xx";
128 int cnt, rc;
129 struct tifm_dev *sock; 135 struct tifm_dev *sock;
130 unsigned int socket_change_set; 136 unsigned long flags;
131 137 unsigned char media_id;
132 while (1) { 138 unsigned int socket_change_set, cnt;
133 rc = wait_event_interruptible(fm->change_set_notify,
134 fm->socket_change_set);
135 if (rc == -ERESTARTSYS)
136 try_to_freeze();
137 139
138 spin_lock_irqsave(&fm->lock, flags); 140 spin_lock_irqsave(&fm->lock, flags);
139 socket_change_set = fm->socket_change_set; 141 socket_change_set = fm->socket_change_set;
140 fm->socket_change_set = 0; 142 fm->socket_change_set = 0;
141 143
142 dev_dbg(fm->dev, "checking media set %x\n", 144 dev_dbg(fm->cdev.dev, "checking media set %x\n",
143 socket_change_set); 145 socket_change_set);
144 146
145 if (kthread_should_stop()) 147 if (!socket_change_set) {
146 socket_change_set = (1 << fm->num_sockets) - 1;
147 spin_unlock_irqrestore(&fm->lock, flags); 148 spin_unlock_irqrestore(&fm->lock, flags);
149 return;
150 }
148 151
149 if (!socket_change_set) 152 for (cnt = 0; cnt < fm->num_sockets; cnt++) {
153 if (!(socket_change_set & (1 << cnt)))
150 continue; 154 continue;
151 155 sock = fm->sockets[cnt];
152 spin_lock_irqsave(&fm->lock, flags); 156 if (sock) {
153 for (cnt = 0; cnt < fm->num_sockets; cnt++) { 157 printk(KERN_INFO
154 if (!(socket_change_set & (1 << cnt))) 158 "%s : demand removing card from socket %u:%u\n",
155 continue; 159 fm->cdev.class_id, fm->id, cnt);
156 sock = fm->sockets[cnt]; 160 fm->sockets[cnt] = NULL;
157 if (sock) {
158 printk(KERN_INFO DRIVER_NAME
159 ": demand removing card from socket %d\n",
160 cnt);
161 fm->sockets[cnt] = NULL;
162 spin_unlock_irqrestore(&fm->lock, flags);
163 device_unregister(&sock->dev);
164 spin_lock_irqsave(&fm->lock, flags);
165 writel(0x0e00,
166 tifm_7xx1_sock_addr(fm->addr, cnt)
167 + SOCK_CONTROL);
168 }
169 if (kthread_should_stop())
170 continue;
171
172 spin_unlock_irqrestore(&fm->lock, flags); 161 spin_unlock_irqrestore(&fm->lock, flags);
173 media_id = tifm_7xx1_toggle_sock_power( 162 device_unregister(&sock->dev);
174 tifm_7xx1_sock_addr(fm->addr, cnt), 163 spin_lock_irqsave(&fm->lock, flags);
175 fm->num_sockets == 2); 164 writel(0x0e00, tifm_7xx1_sock_addr(fm->addr, cnt)
176 if (media_id) { 165 + SOCK_CONTROL);
177 sock = tifm_alloc_device(fm);
178 if (sock) {
179 sock->addr = tifm_7xx1_sock_addr(fm->addr,
180 cnt);
181 sock->media_id = media_id;
182 sock->socket_id = cnt;
183 switch (media_id) {
184 case 1:
185 card_name = "xd";
186 break;
187 case 2:
188 card_name = "ms";
189 break;
190 case 3:
191 card_name = "sd";
192 break;
193 default:
194 tifm_free_device(&sock->dev);
195 spin_lock_irqsave(&fm->lock, flags);
196 continue;
197 }
198 snprintf(sock->dev.bus_id, BUS_ID_SIZE,
199 "tifm_%s%u:%u", card_name,
200 fm->id, cnt);
201 printk(KERN_INFO DRIVER_NAME
202 ": %s card detected in socket %d\n",
203 card_name, cnt);
204 if (!device_register(&sock->dev)) {
205 spin_lock_irqsave(&fm->lock, flags);
206 if (!fm->sockets[cnt]) {
207 fm->sockets[cnt] = sock;
208 sock = NULL;
209 }
210 spin_unlock_irqrestore(&fm->lock, flags);
211 }
212 if (sock)
213 tifm_free_device(&sock->dev);
214 }
215 spin_lock_irqsave(&fm->lock, flags);
216 }
217 } 166 }
218 167
219 if (!kthread_should_stop()) { 168 spin_unlock_irqrestore(&fm->lock, flags);
220 writel(TIFM_IRQ_FIFOMASK(socket_change_set) 169
221 | TIFM_IRQ_CARDMASK(socket_change_set), 170 media_id = tifm_7xx1_toggle_sock_power(
222 fm->addr + FM_CLEAR_INTERRUPT_ENABLE); 171 tifm_7xx1_sock_addr(fm->addr, cnt));
223 writel(TIFM_IRQ_FIFOMASK(socket_change_set) 172
224 | TIFM_IRQ_CARDMASK(socket_change_set), 173 // tifm_alloc_device will check if media_id is valid
225 fm->addr + FM_SET_INTERRUPT_ENABLE); 174 sock = tifm_alloc_device(fm, cnt, media_id);
226 writel(TIFM_IRQ_ENABLE, 175 if (sock) {
227 fm->addr + FM_SET_INTERRUPT_ENABLE); 176 sock->addr = tifm_7xx1_sock_addr(fm->addr, cnt);
228 spin_unlock_irqrestore(&fm->lock, flags); 177
229 } else { 178 if (!device_register(&sock->dev)) {
230 for (cnt = 0; cnt < fm->num_sockets; cnt++) { 179 spin_lock_irqsave(&fm->lock, flags);
231 if (fm->sockets[cnt]) 180 if (!fm->sockets[cnt]) {
232 fm->socket_change_set |= 1 << cnt; 181 fm->sockets[cnt] = sock;
233 } 182 sock = NULL;
234 if (!fm->socket_change_set) { 183 }
235 spin_unlock_irqrestore(&fm->lock, flags);
236 return 0;
237 } else {
238 spin_unlock_irqrestore(&fm->lock, flags); 184 spin_unlock_irqrestore(&fm->lock, flags);
239 } 185 }
186 if (sock)
187 tifm_free_device(&sock->dev);
240 } 188 }
189 spin_lock_irqsave(&fm->lock, flags);
241 } 190 }
242 return 0; 191
192 writel(TIFM_IRQ_FIFOMASK(socket_change_set)
193 | TIFM_IRQ_CARDMASK(socket_change_set),
194 fm->addr + FM_CLEAR_INTERRUPT_ENABLE);
195
196 writel(TIFM_IRQ_FIFOMASK(socket_change_set)
197 | TIFM_IRQ_CARDMASK(socket_change_set),
198 fm->addr + FM_SET_INTERRUPT_ENABLE);
199
200 writel(TIFM_IRQ_ENABLE, fm->addr + FM_SET_INTERRUPT_ENABLE);
201 spin_unlock_irqrestore(&fm->lock, flags);
243} 202}
244 203
245#ifdef CONFIG_PM 204#ifdef CONFIG_PM
@@ -258,9 +217,11 @@ static int tifm_7xx1_suspend(struct pci_dev *dev, pm_message_t state)
258static int tifm_7xx1_resume(struct pci_dev *dev) 217static int tifm_7xx1_resume(struct pci_dev *dev)
259{ 218{
260 struct tifm_adapter *fm = pci_get_drvdata(dev); 219 struct tifm_adapter *fm = pci_get_drvdata(dev);
261 int cnt, rc; 220 int rc;
221 unsigned int good_sockets = 0, bad_sockets = 0;
262 unsigned long flags; 222 unsigned long flags;
263 tifm_media_id new_ids[fm->num_sockets]; 223 unsigned char new_ids[fm->num_sockets];
224 DECLARE_COMPLETION_ONSTACK(finish_resume);
264 225
265 pci_set_power_state(dev, PCI_D0); 226 pci_set_power_state(dev, PCI_D0);
266 pci_restore_state(dev); 227 pci_restore_state(dev);
@@ -271,45 +232,49 @@ static int tifm_7xx1_resume(struct pci_dev *dev)
271 232
272 dev_dbg(&dev->dev, "resuming host\n"); 233 dev_dbg(&dev->dev, "resuming host\n");
273 234
274 for (cnt = 0; cnt < fm->num_sockets; cnt++) 235 for (rc = 0; rc < fm->num_sockets; rc++)
275 new_ids[cnt] = tifm_7xx1_toggle_sock_power( 236 new_ids[rc] = tifm_7xx1_toggle_sock_power(
276 tifm_7xx1_sock_addr(fm->addr, cnt), 237 tifm_7xx1_sock_addr(fm->addr, rc));
277 fm->num_sockets == 2);
278 spin_lock_irqsave(&fm->lock, flags); 238 spin_lock_irqsave(&fm->lock, flags);
279 fm->socket_change_set = 0; 239 for (rc = 0; rc < fm->num_sockets; rc++) {
280 for (cnt = 0; cnt < fm->num_sockets; cnt++) { 240 if (fm->sockets[rc]) {
281 if (fm->sockets[cnt]) { 241 if (fm->sockets[rc]->type == new_ids[rc])
282 if (fm->sockets[cnt]->media_id == new_ids[cnt]) 242 good_sockets |= 1 << rc;
283 fm->socket_change_set |= 1 << cnt; 243 else
284 244 bad_sockets |= 1 << rc;
285 fm->sockets[cnt]->media_id = new_ids[cnt];
286 } 245 }
287 } 246 }
288 247
289 writel(TIFM_IRQ_ENABLE | TIFM_IRQ_SOCKMASK((1 << fm->num_sockets) - 1), 248 writel(TIFM_IRQ_ENABLE | TIFM_IRQ_SOCKMASK((1 << fm->num_sockets) - 1),
290 fm->addr + FM_SET_INTERRUPT_ENABLE); 249 fm->addr + FM_SET_INTERRUPT_ENABLE);
291 if (!fm->socket_change_set) { 250 dev_dbg(&dev->dev, "change sets on resume: good %x, bad %x\n",
292 spin_unlock_irqrestore(&fm->lock, flags); 251 good_sockets, bad_sockets);
293 return 0; 252
294 } else { 253 fm->socket_change_set = 0;
295 fm->socket_change_set = 0; 254 if (good_sockets) {
255 fm->finish_me = &finish_resume;
296 spin_unlock_irqrestore(&fm->lock, flags); 256 spin_unlock_irqrestore(&fm->lock, flags);
257 rc = wait_for_completion_timeout(&finish_resume, HZ);
258 dev_dbg(&dev->dev, "wait returned %d\n", rc);
259 writel(TIFM_IRQ_FIFOMASK(good_sockets)
260 | TIFM_IRQ_CARDMASK(good_sockets),
261 fm->addr + FM_CLEAR_INTERRUPT_ENABLE);
262 writel(TIFM_IRQ_FIFOMASK(good_sockets)
263 | TIFM_IRQ_CARDMASK(good_sockets),
264 fm->addr + FM_SET_INTERRUPT_ENABLE);
265 spin_lock_irqsave(&fm->lock, flags);
266 fm->finish_me = NULL;
267 fm->socket_change_set ^= good_sockets & fm->socket_change_set;
297 } 268 }
298 269
299 wait_event_timeout(fm->change_set_notify, fm->socket_change_set, HZ); 270 fm->socket_change_set |= bad_sockets;
271 if (fm->socket_change_set)
272 tifm_queue_work(&fm->media_switcher);
300 273
301 spin_lock_irqsave(&fm->lock, flags); 274 spin_unlock_irqrestore(&fm->lock, flags);
302 writel(TIFM_IRQ_FIFOMASK(fm->socket_change_set)
303 | TIFM_IRQ_CARDMASK(fm->socket_change_set),
304 fm->addr + FM_CLEAR_INTERRUPT_ENABLE);
305 writel(TIFM_IRQ_FIFOMASK(fm->socket_change_set)
306 | TIFM_IRQ_CARDMASK(fm->socket_change_set),
307 fm->addr + FM_SET_INTERRUPT_ENABLE);
308 writel(TIFM_IRQ_ENABLE, 275 writel(TIFM_IRQ_ENABLE,
309 fm->addr + FM_SET_INTERRUPT_ENABLE); 276 fm->addr + FM_SET_INTERRUPT_ENABLE);
310 fm->socket_change_set = 0;
311 277
312 spin_unlock_irqrestore(&fm->lock, flags);
313 return 0; 278 return 0;
314} 279}
315 280
@@ -345,20 +310,14 @@ static int tifm_7xx1_probe(struct pci_dev *dev,
345 310
346 pci_intx(dev, 1); 311 pci_intx(dev, 1);
347 312
348 fm = tifm_alloc_adapter(); 313 fm = tifm_alloc_adapter(dev->device == PCI_DEVICE_ID_TI_XX21_XX11_FM
314 ? 4 : 2, &dev->dev);
349 if (!fm) { 315 if (!fm) {
350 rc = -ENOMEM; 316 rc = -ENOMEM;
351 goto err_out_int; 317 goto err_out_int;
352 } 318 }
353 319
354 fm->dev = &dev->dev; 320 INIT_WORK(&fm->media_switcher, tifm_7xx1_switch_media);
355 fm->num_sockets = (dev->device == PCI_DEVICE_ID_TI_XX21_XX11_FM)
356 ? 4 : 2;
357 fm->sockets = kzalloc(sizeof(struct tifm_dev*) * fm->num_sockets,
358 GFP_KERNEL);
359 if (!fm->sockets)
360 goto err_out_free;
361
362 fm->eject = tifm_7xx1_eject; 321 fm->eject = tifm_7xx1_eject;
363 pci_set_drvdata(dev, fm); 322 pci_set_drvdata(dev, fm);
364 323
@@ -367,19 +326,16 @@ static int tifm_7xx1_probe(struct pci_dev *dev,
367 if (!fm->addr) 326 if (!fm->addr)
368 goto err_out_free; 327 goto err_out_free;
369 328
370 rc = request_irq(dev->irq, tifm_7xx1_isr, IRQF_SHARED, DRIVER_NAME, fm); 329 rc = request_irq(dev->irq, tifm_7xx1_isr, SA_SHIRQ, DRIVER_NAME, fm);
371 if (rc) 330 if (rc)
372 goto err_out_unmap; 331 goto err_out_unmap;
373 332
374 init_waitqueue_head(&fm->change_set_notify); 333 rc = tifm_add_adapter(fm);
375 rc = tifm_add_adapter(fm, tifm_7xx1_switch_media);
376 if (rc) 334 if (rc)
377 goto err_out_irq; 335 goto err_out_irq;
378 336
379 writel(TIFM_IRQ_SETALL, fm->addr + FM_CLEAR_INTERRUPT_ENABLE);
380 writel(TIFM_IRQ_ENABLE | TIFM_IRQ_SOCKMASK((1 << fm->num_sockets) - 1), 337 writel(TIFM_IRQ_ENABLE | TIFM_IRQ_SOCKMASK((1 << fm->num_sockets) - 1),
381 fm->addr + FM_SET_INTERRUPT_ENABLE); 338 fm->addr + FM_SET_INTERRUPT_ENABLE);
382 wake_up_process(fm->media_switcher);
383 return 0; 339 return 0;
384 340
385err_out_irq: 341err_out_irq:
@@ -401,18 +357,12 @@ err_out:
401static void tifm_7xx1_remove(struct pci_dev *dev) 357static void tifm_7xx1_remove(struct pci_dev *dev)
402{ 358{
403 struct tifm_adapter *fm = pci_get_drvdata(dev); 359 struct tifm_adapter *fm = pci_get_drvdata(dev);
404 unsigned long flags;
405 360
361 fm->eject = tifm_7xx1_dummy_eject;
406 writel(TIFM_IRQ_SETALL, fm->addr + FM_CLEAR_INTERRUPT_ENABLE); 362 writel(TIFM_IRQ_SETALL, fm->addr + FM_CLEAR_INTERRUPT_ENABLE);
407 mmiowb(); 363 mmiowb();
408 free_irq(dev->irq, fm); 364 free_irq(dev->irq, fm);
409 365
410 spin_lock_irqsave(&fm->lock, flags);
411 fm->socket_change_set = (1 << fm->num_sockets) - 1;
412 spin_unlock_irqrestore(&fm->lock, flags);
413
414 kthread_stop(fm->media_switcher);
415
416 tifm_remove_adapter(fm); 366 tifm_remove_adapter(fm);
417 367
418 pci_set_drvdata(dev, NULL); 368 pci_set_drvdata(dev, NULL);