blob: 8b1c102fc3173bc8bd81692e0b0434efc3084e1f [file] [log] [blame]
Alex Dubovbaf85322008-02-09 10:20:54 -08001/*
2 * TI FlashMedia driver
3 *
4 * Copyright (C) 2007 Alex Dubov <oakad@yahoo.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 * Special thanks to Carlos Corbacho for providing various MemoryStick cards
11 * that made this driver possible.
12 *
13 */
14
15#include <linux/tifm.h>
16#include <linux/memstick.h>
17#include <linux/highmem.h>
18#include <linux/scatterlist.h>
19#include <linux/log2.h>
20#include <asm/io.h>
21
22#define DRIVER_NAME "tifm_ms"
23#define DRIVER_VERSION "0.1"
24
25static int no_dma;
26module_param(no_dma, bool, 0644);
27
28#define TIFM_MS_TIMEOUT 0x00100
29#define TIFM_MS_BADCRC 0x00200
30#define TIFM_MS_EOTPC 0x01000
31#define TIFM_MS_INT 0x02000
32
33/* The meaning of the bit majority in this constant is unknown. */
34#define TIFM_MS_SERIAL 0x04010
35
36#define TIFM_MS_SYS_LATCH 0x00100
37#define TIFM_MS_SYS_NOT_RDY 0x00800
38#define TIFM_MS_SYS_DATA 0x10000
39
40/* Hardware flags */
41enum {
42 CMD_READY = 0x0001,
43 FIFO_READY = 0x0002,
44 CARD_READY = 0x0004,
45 DATA_CARRY = 0x0008
46};
47
48struct tifm_ms {
49 struct tifm_dev *dev;
50 unsigned short eject:1,
51 no_dma:1;
52 unsigned short cmd_flags;
53 unsigned int mode_mask;
54 unsigned int block_pos;
55 unsigned long timeout_jiffies;
56
57 struct timer_list timer;
58 struct memstick_request *req;
59 unsigned int io_word;
60};
61
62static void tifm_ms_read_fifo(struct tifm_ms *host, unsigned int fifo_offset,
63 struct page *pg, unsigned int page_off,
64 unsigned int length)
65{
66 struct tifm_dev *sock = host->dev;
67 unsigned int cnt = 0, off = 0;
68 unsigned char *buf = kmap_atomic(pg, KM_BIO_DST_IRQ) + page_off;
69
70 if (host->cmd_flags & DATA_CARRY) {
71 while ((fifo_offset & 3) && length) {
72 buf[off++] = host->io_word & 0xff;
73 host->io_word >>= 8;
74 length--;
75 fifo_offset++;
76 }
77 if (!(fifo_offset & 3))
78 host->cmd_flags &= ~DATA_CARRY;
79 if (!length)
80 return;
81 }
82
83 do {
84 host->io_word = readl(sock->addr + SOCK_FIFO_ACCESS
85 + fifo_offset);
86 cnt = 4;
87 while (length && cnt) {
88 buf[off++] = (host->io_word >> 8) & 0xff;
89 cnt--;
90 length--;
91 }
92 fifo_offset += 4 - cnt;
93 } while (length);
94
95 if (cnt)
96 host->cmd_flags |= DATA_CARRY;
97
98 kunmap_atomic(buf - page_off, KM_BIO_DST_IRQ);
99}
100
101static void tifm_ms_write_fifo(struct tifm_ms *host, unsigned int fifo_offset,
102 struct page *pg, unsigned int page_off,
103 unsigned int length)
104{
105 struct tifm_dev *sock = host->dev;
106 unsigned int cnt = 0, off = 0;
107 unsigned char *buf = kmap_atomic(pg, KM_BIO_SRC_IRQ) + page_off;
108
109 if (host->cmd_flags & DATA_CARRY) {
110 while (fifo_offset & 3) {
111 host->io_word |= buf[off++] << (8 * (fifo_offset & 3));
112 length--;
113 fifo_offset++;
114 }
115 if (!(fifo_offset & 3)) {
116 writel(host->io_word, sock->addr + SOCK_FIFO_ACCESS
117 + fifo_offset - 4);
118
119 host->cmd_flags &= ~DATA_CARRY;
120 }
121 if (!length)
122 return;
123 }
124
125 do {
126 cnt = 4;
127 host->io_word = 0;
128 while (length && cnt) {
129 host->io_word |= buf[off++] << (4 - cnt);
130 cnt--;
131 length--;
132 }
133 fifo_offset += 4 - cnt;
134 if (!cnt)
135 writel(host->io_word, sock->addr + SOCK_FIFO_ACCESS
136 + fifo_offset - 4);
137
138 } while (length);
139
140 if (cnt)
141 host->cmd_flags |= DATA_CARRY;
142
143 kunmap_atomic(buf - page_off, KM_BIO_SRC_IRQ);
144}
145
146static void tifm_ms_move_block(struct tifm_ms *host, unsigned int length)
147{
148 unsigned int t_size;
149 unsigned int off = host->req->sg.offset + host->block_pos;
150 unsigned int p_off, p_cnt;
151 struct page *pg;
152 unsigned long flags;
153
154 dev_dbg(&host->dev->dev, "moving block\n");
155 local_irq_save(flags);
156 t_size = length;
157 while (t_size) {
158 pg = nth_page(sg_page(&host->req->sg), off >> PAGE_SHIFT);
159 p_off = offset_in_page(off);
160 p_cnt = PAGE_SIZE - p_off;
161 p_cnt = min(p_cnt, t_size);
162
163 if (host->req->data_dir == WRITE)
164 tifm_ms_write_fifo(host, length - t_size,
165 pg, p_off, p_cnt);
166 else
167 tifm_ms_read_fifo(host, length - t_size,
168 pg, p_off, p_cnt);
169
170 t_size -= p_cnt;
171 }
172 local_irq_restore(flags);
173}
174
175static int tifm_ms_transfer_data(struct tifm_ms *host, int skip)
176{
177 struct tifm_dev *sock = host->dev;
178 unsigned int length = host->req->sg.length - host->block_pos;
179
180 if (!length)
181 return 1;
182
183 if (length > TIFM_FIFO_SIZE)
184 length = TIFM_FIFO_SIZE;
185
186 if (!skip) {
187 tifm_ms_move_block(host, length);
188 host->block_pos += length;
189 }
190
191 if ((host->req->data_dir == READ)
192 && (host->block_pos == host->req->sg.length))
193 return 1;
194
195 writel(ilog2(length) - 2, sock->addr + SOCK_FIFO_PAGE_SIZE);
196 if (host->req->data_dir == WRITE)
197 writel((1 << 8) | TIFM_DMA_TX, sock->addr + SOCK_DMA_CONTROL);
198 else
199 writel((1 << 8), sock->addr + SOCK_DMA_CONTROL);
200
201 return 0;
202}
203
204static int tifm_ms_issue_cmd(struct tifm_ms *host)
205{
206 struct tifm_dev *sock = host->dev;
207 unsigned char *data;
208 unsigned int data_len = 0, cmd = 0, cmd_mask = 0, cnt, tval = 0;
209
210 host->cmd_flags = 0;
211
Alex Dubove1f19992008-03-10 11:43:37 -0700212 if (host->req->long_data) {
Alex Dubovbaf85322008-02-09 10:20:54 -0800213 if (!host->no_dma) {
214 if (1 != tifm_map_sg(sock, &host->req->sg, 1,
215 host->req->data_dir == READ
216 ? PCI_DMA_FROMDEVICE
217 : PCI_DMA_TODEVICE)) {
218 host->req->error = -ENOMEM;
219 return host->req->error;
220 }
221 data_len = sg_dma_len(&host->req->sg);
222 } else
223 data_len = host->req->sg.length;
224
225 writel(TIFM_FIFO_INT_SETALL,
226 sock->addr + SOCK_DMA_FIFO_INT_ENABLE_CLEAR);
227 writel(TIFM_FIFO_ENABLE,
228 sock->addr + SOCK_FIFO_CONTROL);
229 writel(TIFM_FIFO_INTMASK,
230 sock->addr + SOCK_DMA_FIFO_INT_ENABLE_SET);
231
232 if (!host->no_dma) {
233 writel(ilog2(data_len) - 2,
234 sock->addr + SOCK_FIFO_PAGE_SIZE);
235 writel(sg_dma_address(&host->req->sg),
236 sock->addr + SOCK_DMA_ADDRESS);
237 if (host->req->data_dir == WRITE)
238 writel((1 << 8) | TIFM_DMA_TX | TIFM_DMA_EN,
239 sock->addr + SOCK_DMA_CONTROL);
240 else
241 writel((1 << 8) | TIFM_DMA_EN,
242 sock->addr + SOCK_DMA_CONTROL);
243 } else {
244 tifm_ms_transfer_data(host,
245 host->req->data_dir == READ);
246 }
247
248 cmd_mask = readl(sock->addr + SOCK_MS_SYSTEM);
249 cmd_mask |= TIFM_MS_SYS_DATA | TIFM_MS_SYS_NOT_RDY;
250 writel(cmd_mask, sock->addr + SOCK_MS_SYSTEM);
Alex Dubove1f19992008-03-10 11:43:37 -0700251 } else {
Alex Dubovbaf85322008-02-09 10:20:54 -0800252 data = host->req->data;
253 data_len = host->req->data_len;
254
255 cmd_mask = host->mode_mask | 0x2607; /* unknown constant */
256
257 if (host->req->data_dir == WRITE) {
258 cmd_mask |= TIFM_MS_SYS_LATCH;
259 writel(cmd_mask, sock->addr + SOCK_MS_SYSTEM);
260 for (cnt = 0; (data_len - cnt) >= 4; cnt += 4) {
261 writel(TIFM_MS_SYS_LATCH
262 | readl(sock->addr + SOCK_MS_SYSTEM),
263 sock->addr + SOCK_MS_SYSTEM);
264 __raw_writel(*(unsigned int *)(data + cnt),
265 sock->addr + SOCK_MS_DATA);
266 dev_dbg(&sock->dev, "writing %x\n",
267 *(int *)(data + cnt));
268 }
269 switch (data_len - cnt) {
270 case 3:
271 tval |= data[cnt + 2] << 16;
272 case 2:
273 tval |= data[cnt + 1] << 8;
274 case 1:
275 tval |= data[cnt];
276 writel(TIFM_MS_SYS_LATCH
277 | readl(sock->addr + SOCK_MS_SYSTEM),
278 sock->addr + SOCK_MS_SYSTEM);
279 writel(tval, sock->addr + SOCK_MS_DATA);
280 dev_dbg(&sock->dev, "writing %x\n", tval);
281 }
282
283 writel(TIFM_MS_SYS_LATCH
284 | readl(sock->addr + SOCK_MS_SYSTEM),
Al Viro282ea442008-02-13 03:56:59 +0000285 sock->addr + SOCK_MS_SYSTEM);
Alex Dubovbaf85322008-02-09 10:20:54 -0800286 writel(0, sock->addr + SOCK_MS_DATA);
287 dev_dbg(&sock->dev, "writing %x\n", 0);
288
289 } else
290 writel(cmd_mask, sock->addr + SOCK_MS_SYSTEM);
291
292 cmd_mask = readl(sock->addr + SOCK_MS_SYSTEM);
293 cmd_mask &= ~TIFM_MS_SYS_DATA;
294 cmd_mask |= TIFM_MS_SYS_NOT_RDY;
295 dev_dbg(&sock->dev, "mask %x\n", cmd_mask);
296 writel(cmd_mask, sock->addr + SOCK_MS_SYSTEM);
Alex Dubove1f19992008-03-10 11:43:37 -0700297 }
Alex Dubovbaf85322008-02-09 10:20:54 -0800298
299 mod_timer(&host->timer, jiffies + host->timeout_jiffies);
300 writel(TIFM_CTRL_LED | readl(sock->addr + SOCK_CONTROL),
301 sock->addr + SOCK_CONTROL);
302 host->req->error = 0;
303
304 cmd = (host->req->tpc & 0xf) << 12;
305 cmd |= data_len;
306 writel(cmd, sock->addr + SOCK_MS_COMMAND);
307
308 dev_dbg(&sock->dev, "executing TPC %x, %x\n", cmd, cmd_mask);
309 return 0;
310}
311
312static void tifm_ms_complete_cmd(struct tifm_ms *host)
313{
314 struct tifm_dev *sock = host->dev;
315 struct memstick_host *msh = tifm_get_drvdata(sock);
316 unsigned int tval = 0, data_len;
317 unsigned char *data;
318 int rc;
319
320 del_timer(&host->timer);
Alex Dubove1f19992008-03-10 11:43:37 -0700321 if (host->req->long_data) {
Alex Dubovbaf85322008-02-09 10:20:54 -0800322 if (!host->no_dma)
323 tifm_unmap_sg(sock, &host->req->sg, 1,
324 host->req->data_dir == READ
325 ? PCI_DMA_FROMDEVICE
326 : PCI_DMA_TODEVICE);
Alex Dubove1f19992008-03-10 11:43:37 -0700327 } else {
Alex Dubovbaf85322008-02-09 10:20:54 -0800328 writel(~TIFM_MS_SYS_DATA & readl(sock->addr + SOCK_MS_SYSTEM),
329 sock->addr + SOCK_MS_SYSTEM);
330
331 data = host->req->data;
332 data_len = host->req->data_len;
333
334 if (host->req->data_dir == READ) {
335 for (rc = 0; (data_len - rc) >= 4; rc += 4)
336 *(int *)(data + rc)
337 = __raw_readl(sock->addr
338 + SOCK_MS_DATA);
339
340 if (data_len - rc)
341 tval = readl(sock->addr + SOCK_MS_DATA);
342 switch (data_len - rc) {
343 case 3:
344 data[rc + 2] = (tval >> 16) & 0xff;
345 case 2:
346 data[rc + 1] = (tval >> 8) & 0xff;
347 case 1:
348 data[rc] = tval & 0xff;
349 }
350 readl(sock->addr + SOCK_MS_DATA);
351 }
352 }
353
354 writel((~TIFM_CTRL_LED) & readl(sock->addr + SOCK_CONTROL),
355 sock->addr + SOCK_CONTROL);
356
357 do {
358 rc = memstick_next_req(msh, &host->req);
359 } while (!rc && tifm_ms_issue_cmd(host));
360}
361
362static int tifm_ms_check_status(struct tifm_ms *host)
363{
364 if (!host->req->error) {
365 if (!(host->cmd_flags & CMD_READY))
366 return 1;
Alex Dubove1f19992008-03-10 11:43:37 -0700367 if (host->req->long_data
Alex Dubovbaf85322008-02-09 10:20:54 -0800368 && !(host->cmd_flags & FIFO_READY))
369 return 1;
370 if (host->req->need_card_int
371 && !(host->cmd_flags & CARD_READY))
372 return 1;
373 }
374 return 0;
375}
376
377/* Called from interrupt handler */
378static void tifm_ms_data_event(struct tifm_dev *sock)
379{
380 struct tifm_ms *host;
381 unsigned int fifo_status = 0;
382 int rc = 1;
383
384 spin_lock(&sock->lock);
385 host = memstick_priv((struct memstick_host *)tifm_get_drvdata(sock));
386 fifo_status = readl(sock->addr + SOCK_DMA_FIFO_STATUS);
387 dev_dbg(&sock->dev, "data event: fifo_status %x, flags %x\n",
388 fifo_status, host->cmd_flags);
389
390 if (host->req) {
391 if (fifo_status & TIFM_FIFO_READY) {
392 if (!host->no_dma || tifm_ms_transfer_data(host, 0)) {
393 host->cmd_flags |= FIFO_READY;
394 rc = tifm_ms_check_status(host);
395 }
396 }
397 }
398
399 writel(fifo_status, sock->addr + SOCK_DMA_FIFO_STATUS);
400 if (!rc)
401 tifm_ms_complete_cmd(host);
402
403 spin_unlock(&sock->lock);
404}
405
406
407/* Called from interrupt handler */
408static void tifm_ms_card_event(struct tifm_dev *sock)
409{
410 struct tifm_ms *host;
411 unsigned int host_status = 0;
412 int rc = 1;
413
414 spin_lock(&sock->lock);
415 host = memstick_priv((struct memstick_host *)tifm_get_drvdata(sock));
416 host_status = readl(sock->addr + SOCK_MS_STATUS);
417 dev_dbg(&sock->dev, "host event: host_status %x, flags %x\n",
418 host_status, host->cmd_flags);
419
420 if (host->req) {
421 if (host_status & TIFM_MS_TIMEOUT)
422 host->req->error = -ETIME;
423 else if (host_status & TIFM_MS_BADCRC)
424 host->req->error = -EILSEQ;
425
426 if (host->req->error) {
427 writel(TIFM_FIFO_INT_SETALL,
428 sock->addr + SOCK_DMA_FIFO_INT_ENABLE_CLEAR);
429 writel(TIFM_DMA_RESET, sock->addr + SOCK_DMA_CONTROL);
430 }
431
432 if (host_status & TIFM_MS_EOTPC)
433 host->cmd_flags |= CMD_READY;
434 if (host_status & TIFM_MS_INT)
435 host->cmd_flags |= CARD_READY;
436
437 rc = tifm_ms_check_status(host);
438
439 }
440
441 writel(TIFM_MS_SYS_NOT_RDY | readl(sock->addr + SOCK_MS_SYSTEM),
442 sock->addr + SOCK_MS_SYSTEM);
443 writel((~TIFM_MS_SYS_DATA) & readl(sock->addr + SOCK_MS_SYSTEM),
444 sock->addr + SOCK_MS_SYSTEM);
445
446 if (!rc)
447 tifm_ms_complete_cmd(host);
448
449 spin_unlock(&sock->lock);
450 return;
451}
452
453static void tifm_ms_request(struct memstick_host *msh)
454{
455 struct tifm_ms *host = memstick_priv(msh);
456 struct tifm_dev *sock = host->dev;
457 unsigned long flags;
458 int rc;
459
460 spin_lock_irqsave(&sock->lock, flags);
461 if (host->req) {
462 printk(KERN_ERR "%s : unfinished request detected\n",
463 sock->dev.bus_id);
464 spin_unlock_irqrestore(&sock->lock, flags);
465 tifm_eject(host->dev);
466 return;
467 }
468
469 if (host->eject) {
470 do {
471 rc = memstick_next_req(msh, &host->req);
472 if (!rc)
473 host->req->error = -ETIME;
474 } while (!rc);
475 spin_unlock_irqrestore(&sock->lock, flags);
476 return;
477 }
478
479 do {
480 rc = memstick_next_req(msh, &host->req);
481 } while (!rc && tifm_ms_issue_cmd(host));
482
483 spin_unlock_irqrestore(&sock->lock, flags);
484 return;
485}
486
487static void tifm_ms_set_param(struct memstick_host *msh,
488 enum memstick_param param,
489 int value)
490{
491 struct tifm_ms *host = memstick_priv(msh);
492 struct tifm_dev *sock = host->dev;
493 unsigned long flags;
494
495 spin_lock_irqsave(&sock->lock, flags);
496
497 switch (param) {
498 case MEMSTICK_POWER:
499 /* this is set by card detection mechanism */
500 break;
501 case MEMSTICK_INTERFACE:
502 if (value == MEMSTICK_SERIAL) {
503 host->mode_mask = TIFM_MS_SERIAL;
504 writel((~TIFM_CTRL_FAST_CLK)
505 & readl(sock->addr + SOCK_CONTROL),
506 sock->addr + SOCK_CONTROL);
Alex Dubove1f19992008-03-10 11:43:37 -0700507 } else if (value == MEMSTICK_PAR4) {
Alex Dubovbaf85322008-02-09 10:20:54 -0800508 host->mode_mask = 0;
509 writel(TIFM_CTRL_FAST_CLK
510 | readl(sock->addr + SOCK_CONTROL),
511 sock->addr + SOCK_CONTROL);
512 }
513 break;
514 };
515
516 spin_unlock_irqrestore(&sock->lock, flags);
517}
518
519static void tifm_ms_abort(unsigned long data)
520{
521 struct tifm_ms *host = (struct tifm_ms *)data;
522
523 dev_dbg(&host->dev->dev, "status %x\n",
524 readl(host->dev->addr + SOCK_MS_STATUS));
525 printk(KERN_ERR
526 "%s : card failed to respond for a long period of time "
527 "(%x, %x)\n",
528 host->dev->dev.bus_id, host->req ? host->req->tpc : 0,
529 host->cmd_flags);
530
531 tifm_eject(host->dev);
532}
533
534static int tifm_ms_initialize_host(struct tifm_ms *host)
535{
536 struct tifm_dev *sock = host->dev;
537 struct memstick_host *msh = tifm_get_drvdata(sock);
538
539 host->mode_mask = TIFM_MS_SERIAL;
540 writel(0x8000, sock->addr + SOCK_MS_SYSTEM);
541 writel(0x0200 | TIFM_MS_SYS_NOT_RDY, sock->addr + SOCK_MS_SYSTEM);
542 writel(0xffffffff, sock->addr + SOCK_MS_STATUS);
543 if (tifm_has_ms_pif(sock))
Alex Dubove1f19992008-03-10 11:43:37 -0700544 msh->caps |= MEMSTICK_CAP_PAR4;
Alex Dubovbaf85322008-02-09 10:20:54 -0800545
546 return 0;
547}
548
549static int tifm_ms_probe(struct tifm_dev *sock)
550{
551 struct memstick_host *msh;
552 struct tifm_ms *host;
553 int rc = -EIO;
554
555 if (!(TIFM_SOCK_STATE_OCCUPIED
556 & readl(sock->addr + SOCK_PRESENT_STATE))) {
557 printk(KERN_WARNING "%s : card gone, unexpectedly\n",
558 sock->dev.bus_id);
559 return rc;
560 }
561
562 msh = memstick_alloc_host(sizeof(struct tifm_ms), &sock->dev);
563 if (!msh)
564 return -ENOMEM;
565
566 host = memstick_priv(msh);
567 tifm_set_drvdata(sock, msh);
568 host->dev = sock;
569 host->timeout_jiffies = msecs_to_jiffies(1000);
570 host->no_dma = no_dma;
571
572 setup_timer(&host->timer, tifm_ms_abort, (unsigned long)host);
573
574 msh->request = tifm_ms_request;
575 msh->set_param = tifm_ms_set_param;
576 sock->card_event = tifm_ms_card_event;
577 sock->data_event = tifm_ms_data_event;
578 rc = tifm_ms_initialize_host(host);
579
580 if (!rc)
581 rc = memstick_add_host(msh);
582 if (!rc)
583 return 0;
584
585 memstick_free_host(msh);
586 return rc;
587}
588
589static void tifm_ms_remove(struct tifm_dev *sock)
590{
591 struct memstick_host *msh = tifm_get_drvdata(sock);
592 struct tifm_ms *host = memstick_priv(msh);
593 int rc = 0;
594 unsigned long flags;
595
596 spin_lock_irqsave(&sock->lock, flags);
597 host->eject = 1;
598 if (host->req) {
599 del_timer(&host->timer);
600 writel(TIFM_FIFO_INT_SETALL,
601 sock->addr + SOCK_DMA_FIFO_INT_ENABLE_CLEAR);
602 writel(TIFM_DMA_RESET, sock->addr + SOCK_DMA_CONTROL);
Alex Dubove1f19992008-03-10 11:43:37 -0700603 if (host->req->long_data && !host->no_dma)
Alex Dubovbaf85322008-02-09 10:20:54 -0800604 tifm_unmap_sg(sock, &host->req->sg, 1,
605 host->req->data_dir == READ
606 ? PCI_DMA_TODEVICE
607 : PCI_DMA_FROMDEVICE);
608 host->req->error = -ETIME;
609
610 do {
611 rc = memstick_next_req(msh, &host->req);
612 if (!rc)
613 host->req->error = -ETIME;
614 } while (!rc);
615 }
616 spin_unlock_irqrestore(&sock->lock, flags);
617
618 memstick_remove_host(msh);
619
620 writel(0x0200 | TIFM_MS_SYS_NOT_RDY, sock->addr + SOCK_MS_SYSTEM);
621 writel(0xffffffff, sock->addr + SOCK_MS_STATUS);
622
623 memstick_free_host(msh);
624}
625
626#ifdef CONFIG_PM
627
628static int tifm_ms_suspend(struct tifm_dev *sock, pm_message_t state)
629{
Alex Dubovd114ad52008-03-10 11:43:38 -0700630 struct memstick_host *msh = tifm_get_drvdata(sock);
631
632 memstick_suspend_host(msh);
Alex Dubovbaf85322008-02-09 10:20:54 -0800633 return 0;
634}
635
636static int tifm_ms_resume(struct tifm_dev *sock)
637{
638 struct memstick_host *msh = tifm_get_drvdata(sock);
Alex Dubovbaf85322008-02-09 10:20:54 -0800639
Alex Dubovd114ad52008-03-10 11:43:38 -0700640 memstick_resume_host(msh);
Alex Dubovbaf85322008-02-09 10:20:54 -0800641 return 0;
642}
643
644#else
645
646#define tifm_ms_suspend NULL
647#define tifm_ms_resume NULL
648
649#endif /* CONFIG_PM */
650
651static struct tifm_device_id tifm_ms_id_tbl[] = {
652 { TIFM_TYPE_MS }, { 0 }
653};
654
655static struct tifm_driver tifm_ms_driver = {
656 .driver = {
657 .name = DRIVER_NAME,
658 .owner = THIS_MODULE
659 },
660 .id_table = tifm_ms_id_tbl,
661 .probe = tifm_ms_probe,
662 .remove = tifm_ms_remove,
663 .suspend = tifm_ms_suspend,
664 .resume = tifm_ms_resume
665};
666
667static int __init tifm_ms_init(void)
668{
669 return tifm_register_driver(&tifm_ms_driver);
670}
671
672static void __exit tifm_ms_exit(void)
673{
674 tifm_unregister_driver(&tifm_ms_driver);
675}
676
677MODULE_AUTHOR("Alex Dubov");
678MODULE_DESCRIPTION("TI FlashMedia MemoryStick driver");
679MODULE_LICENSE("GPL");
680MODULE_DEVICE_TABLE(tifm, tifm_ms_id_tbl);
681MODULE_VERSION(DRIVER_VERSION);
682
683module_init(tifm_ms_init);
684module_exit(tifm_ms_exit);