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