0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #include <linux/tifm.h>
0012 #include <linux/memstick.h>
0013 #include <linux/highmem.h>
0014 #include <linux/scatterlist.h>
0015 #include <linux/log2.h>
0016 #include <linux/module.h>
0017 #include <asm/io.h>
0018
0019 #define DRIVER_NAME "tifm_ms"
0020
0021 static bool no_dma;
0022 module_param(no_dma, bool, 0644);
0023
0024
0025
0026
0027
0028
0029 #define TIFM_MS_STAT_DRQ 0x04000
0030 #define TIFM_MS_STAT_MSINT 0x02000
0031 #define TIFM_MS_STAT_RDY 0x01000
0032 #define TIFM_MS_STAT_CRC 0x00200
0033 #define TIFM_MS_STAT_TOE 0x00100
0034 #define TIFM_MS_STAT_EMP 0x00020
0035 #define TIFM_MS_STAT_FUL 0x00010
0036 #define TIFM_MS_STAT_CED 0x00008
0037 #define TIFM_MS_STAT_ERR 0x00004
0038 #define TIFM_MS_STAT_BRQ 0x00002
0039 #define TIFM_MS_STAT_CNK 0x00001
0040
0041 #define TIFM_MS_SYS_DMA 0x10000
0042 #define TIFM_MS_SYS_RESET 0x08000
0043 #define TIFM_MS_SYS_SRAC 0x04000
0044 #define TIFM_MS_SYS_INTEN 0x02000
0045 #define TIFM_MS_SYS_NOCRC 0x01000
0046 #define TIFM_MS_SYS_INTCLR 0x00800
0047 #define TIFM_MS_SYS_MSIEN 0x00400
0048 #define TIFM_MS_SYS_FCLR 0x00200
0049 #define TIFM_MS_SYS_FDIR 0x00100
0050 #define TIFM_MS_SYS_DAM 0x00080
0051 #define TIFM_MS_SYS_DRM 0x00040
0052 #define TIFM_MS_SYS_DRQSL 0x00020
0053 #define TIFM_MS_SYS_REI 0x00010
0054 #define TIFM_MS_SYS_REO 0x00008
0055 #define TIFM_MS_SYS_BSY_MASK 0x00007
0056
0057 #define TIFM_MS_SYS_FIFO (TIFM_MS_SYS_INTEN | TIFM_MS_SYS_MSIEN \
0058 | TIFM_MS_SYS_FCLR | TIFM_MS_SYS_BSY_MASK)
0059
0060
0061 enum {
0062 CMD_READY = 0x01,
0063 FIFO_READY = 0x02,
0064 CARD_INT = 0x04
0065 };
0066
0067 struct tifm_ms {
0068 struct tifm_dev *dev;
0069 struct timer_list timer;
0070 struct memstick_request *req;
0071 struct tasklet_struct notify;
0072 unsigned int mode_mask;
0073 unsigned int block_pos;
0074 unsigned long timeout_jiffies;
0075 unsigned char eject:1,
0076 use_dma:1;
0077 unsigned char cmd_flags;
0078 unsigned char io_pos;
0079 unsigned int io_word;
0080 };
0081
0082 static unsigned int tifm_ms_read_data(struct tifm_ms *host,
0083 unsigned char *buf, unsigned int length)
0084 {
0085 struct tifm_dev *sock = host->dev;
0086 unsigned int off = 0;
0087
0088 while (host->io_pos && length) {
0089 buf[off++] = host->io_word & 0xff;
0090 host->io_word >>= 8;
0091 length--;
0092 host->io_pos--;
0093 }
0094
0095 if (!length)
0096 return off;
0097
0098 while (!(TIFM_MS_STAT_EMP & readl(sock->addr + SOCK_MS_STATUS))) {
0099 if (length < 4)
0100 break;
0101 *(unsigned int *)(buf + off) = __raw_readl(sock->addr
0102 + SOCK_MS_DATA);
0103 length -= 4;
0104 off += 4;
0105 }
0106
0107 if (length
0108 && !(TIFM_MS_STAT_EMP & readl(sock->addr + SOCK_MS_STATUS))) {
0109 host->io_word = readl(sock->addr + SOCK_MS_DATA);
0110 for (host->io_pos = 4; host->io_pos; --host->io_pos) {
0111 buf[off++] = host->io_word & 0xff;
0112 host->io_word >>= 8;
0113 length--;
0114 if (!length)
0115 break;
0116 }
0117 }
0118
0119 return off;
0120 }
0121
0122 static unsigned int tifm_ms_write_data(struct tifm_ms *host,
0123 unsigned char *buf, unsigned int length)
0124 {
0125 struct tifm_dev *sock = host->dev;
0126 unsigned int off = 0;
0127
0128 if (host->io_pos) {
0129 while (host->io_pos < 4 && length) {
0130 host->io_word |= buf[off++] << (host->io_pos * 8);
0131 host->io_pos++;
0132 length--;
0133 }
0134 }
0135
0136 if (host->io_pos == 4
0137 && !(TIFM_MS_STAT_FUL & readl(sock->addr + SOCK_MS_STATUS))) {
0138 writel(TIFM_MS_SYS_FDIR | readl(sock->addr + SOCK_MS_SYSTEM),
0139 sock->addr + SOCK_MS_SYSTEM);
0140 writel(host->io_word, sock->addr + SOCK_MS_DATA);
0141 host->io_pos = 0;
0142 host->io_word = 0;
0143 } else if (host->io_pos) {
0144 return off;
0145 }
0146
0147 if (!length)
0148 return off;
0149
0150 while (!(TIFM_MS_STAT_FUL & readl(sock->addr + SOCK_MS_STATUS))) {
0151 if (length < 4)
0152 break;
0153 writel(TIFM_MS_SYS_FDIR | readl(sock->addr + SOCK_MS_SYSTEM),
0154 sock->addr + SOCK_MS_SYSTEM);
0155 __raw_writel(*(unsigned int *)(buf + off),
0156 sock->addr + SOCK_MS_DATA);
0157 length -= 4;
0158 off += 4;
0159 }
0160
0161 switch (length) {
0162 case 3:
0163 host->io_word |= buf[off + 2] << 16;
0164 host->io_pos++;
0165 fallthrough;
0166 case 2:
0167 host->io_word |= buf[off + 1] << 8;
0168 host->io_pos++;
0169 fallthrough;
0170 case 1:
0171 host->io_word |= buf[off];
0172 host->io_pos++;
0173 }
0174
0175 off += host->io_pos;
0176
0177 return off;
0178 }
0179
0180 static unsigned int tifm_ms_transfer_data(struct tifm_ms *host)
0181 {
0182 struct tifm_dev *sock = host->dev;
0183 unsigned int length;
0184 unsigned int off;
0185 unsigned int t_size, p_cnt;
0186 unsigned char *buf;
0187 struct page *pg;
0188 unsigned long flags = 0;
0189
0190 if (host->req->long_data) {
0191 length = host->req->sg.length - host->block_pos;
0192 off = host->req->sg.offset + host->block_pos;
0193 } else {
0194 length = host->req->data_len - host->block_pos;
0195 off = 0;
0196 }
0197 dev_dbg(&sock->dev, "fifo data transfer, %d, %d\n", length,
0198 host->block_pos);
0199
0200 while (length) {
0201 unsigned int p_off;
0202
0203 if (host->req->long_data) {
0204 pg = nth_page(sg_page(&host->req->sg),
0205 off >> PAGE_SHIFT);
0206 p_off = offset_in_page(off);
0207 p_cnt = PAGE_SIZE - p_off;
0208 p_cnt = min(p_cnt, length);
0209
0210 local_irq_save(flags);
0211 buf = kmap_atomic(pg) + p_off;
0212 } else {
0213 buf = host->req->data + host->block_pos;
0214 p_cnt = host->req->data_len - host->block_pos;
0215 }
0216
0217 t_size = host->req->data_dir == WRITE
0218 ? tifm_ms_write_data(host, buf, p_cnt)
0219 : tifm_ms_read_data(host, buf, p_cnt);
0220
0221 if (host->req->long_data) {
0222 kunmap_atomic(buf - p_off);
0223 local_irq_restore(flags);
0224 }
0225
0226 if (!t_size)
0227 break;
0228 host->block_pos += t_size;
0229 length -= t_size;
0230 off += t_size;
0231 }
0232
0233 dev_dbg(&sock->dev, "fifo data transfer, %d remaining\n", length);
0234 if (!length && (host->req->data_dir == WRITE)) {
0235 if (host->io_pos) {
0236 writel(TIFM_MS_SYS_FDIR
0237 | readl(sock->addr + SOCK_MS_SYSTEM),
0238 sock->addr + SOCK_MS_SYSTEM);
0239 writel(host->io_word, sock->addr + SOCK_MS_DATA);
0240 }
0241 writel(TIFM_MS_SYS_FDIR
0242 | readl(sock->addr + SOCK_MS_SYSTEM),
0243 sock->addr + SOCK_MS_SYSTEM);
0244 writel(0, sock->addr + SOCK_MS_DATA);
0245 } else {
0246 readl(sock->addr + SOCK_MS_DATA);
0247 }
0248
0249 return length;
0250 }
0251
0252 static int tifm_ms_issue_cmd(struct tifm_ms *host)
0253 {
0254 struct tifm_dev *sock = host->dev;
0255 unsigned int data_len, cmd, sys_param;
0256
0257 host->cmd_flags = 0;
0258 host->block_pos = 0;
0259 host->io_pos = 0;
0260 host->io_word = 0;
0261 host->cmd_flags = 0;
0262
0263 host->use_dma = !no_dma;
0264
0265 if (host->req->long_data) {
0266 data_len = host->req->sg.length;
0267 if (!is_power_of_2(data_len))
0268 host->use_dma = 0;
0269 } else {
0270 data_len = host->req->data_len;
0271 host->use_dma = 0;
0272 }
0273
0274 writel(TIFM_FIFO_INT_SETALL,
0275 sock->addr + SOCK_DMA_FIFO_INT_ENABLE_CLEAR);
0276 writel(TIFM_FIFO_ENABLE,
0277 sock->addr + SOCK_FIFO_CONTROL);
0278
0279 if (host->use_dma) {
0280 if (1 != tifm_map_sg(sock, &host->req->sg, 1,
0281 host->req->data_dir == READ
0282 ? DMA_FROM_DEVICE
0283 : DMA_TO_DEVICE)) {
0284 host->req->error = -ENOMEM;
0285 return host->req->error;
0286 }
0287 data_len = sg_dma_len(&host->req->sg);
0288
0289 writel(ilog2(data_len) - 2,
0290 sock->addr + SOCK_FIFO_PAGE_SIZE);
0291 writel(TIFM_FIFO_INTMASK,
0292 sock->addr + SOCK_DMA_FIFO_INT_ENABLE_SET);
0293 sys_param = TIFM_DMA_EN | (1 << 8);
0294 if (host->req->data_dir == WRITE)
0295 sys_param |= TIFM_DMA_TX;
0296
0297 writel(TIFM_FIFO_INTMASK,
0298 sock->addr + SOCK_DMA_FIFO_INT_ENABLE_SET);
0299
0300 writel(sg_dma_address(&host->req->sg),
0301 sock->addr + SOCK_DMA_ADDRESS);
0302 writel(sys_param, sock->addr + SOCK_DMA_CONTROL);
0303 } else {
0304 writel(host->mode_mask | TIFM_MS_SYS_FIFO,
0305 sock->addr + SOCK_MS_SYSTEM);
0306
0307 writel(TIFM_FIFO_MORE,
0308 sock->addr + SOCK_DMA_FIFO_INT_ENABLE_SET);
0309 }
0310
0311 mod_timer(&host->timer, jiffies + host->timeout_jiffies);
0312 writel(TIFM_CTRL_LED | readl(sock->addr + SOCK_CONTROL),
0313 sock->addr + SOCK_CONTROL);
0314 host->req->error = 0;
0315
0316 sys_param = readl(sock->addr + SOCK_MS_SYSTEM);
0317 sys_param |= TIFM_MS_SYS_INTCLR;
0318
0319 if (host->use_dma)
0320 sys_param |= TIFM_MS_SYS_DMA;
0321 else
0322 sys_param &= ~TIFM_MS_SYS_DMA;
0323
0324 writel(sys_param, sock->addr + SOCK_MS_SYSTEM);
0325
0326 cmd = (host->req->tpc & 0xf) << 12;
0327 cmd |= data_len;
0328 writel(cmd, sock->addr + SOCK_MS_COMMAND);
0329
0330 dev_dbg(&sock->dev, "executing TPC %x, %x\n", cmd, sys_param);
0331 return 0;
0332 }
0333
0334 static void tifm_ms_complete_cmd(struct tifm_ms *host)
0335 {
0336 struct tifm_dev *sock = host->dev;
0337 struct memstick_host *msh = tifm_get_drvdata(sock);
0338 int rc;
0339
0340 del_timer(&host->timer);
0341
0342 host->req->int_reg = readl(sock->addr + SOCK_MS_STATUS) & 0xff;
0343 host->req->int_reg = (host->req->int_reg & 1)
0344 | ((host->req->int_reg << 4) & 0xe0);
0345
0346 writel(TIFM_FIFO_INT_SETALL,
0347 sock->addr + SOCK_DMA_FIFO_INT_ENABLE_CLEAR);
0348 writel(TIFM_DMA_RESET, sock->addr + SOCK_DMA_CONTROL);
0349
0350 if (host->use_dma) {
0351 tifm_unmap_sg(sock, &host->req->sg, 1,
0352 host->req->data_dir == READ
0353 ? DMA_FROM_DEVICE
0354 : DMA_TO_DEVICE);
0355 }
0356
0357 writel((~TIFM_CTRL_LED) & readl(sock->addr + SOCK_CONTROL),
0358 sock->addr + SOCK_CONTROL);
0359
0360 dev_dbg(&sock->dev, "TPC complete\n");
0361 do {
0362 rc = memstick_next_req(msh, &host->req);
0363 } while (!rc && tifm_ms_issue_cmd(host));
0364 }
0365
0366 static int tifm_ms_check_status(struct tifm_ms *host)
0367 {
0368 if (!host->req->error) {
0369 if (!(host->cmd_flags & CMD_READY))
0370 return 1;
0371 if (!(host->cmd_flags & FIFO_READY))
0372 return 1;
0373 if (host->req->need_card_int
0374 && !(host->cmd_flags & CARD_INT))
0375 return 1;
0376 }
0377 return 0;
0378 }
0379
0380
0381 static void tifm_ms_data_event(struct tifm_dev *sock)
0382 {
0383 struct tifm_ms *host;
0384 unsigned int fifo_status = 0, host_status = 0;
0385 int rc = 1;
0386
0387 spin_lock(&sock->lock);
0388 host = memstick_priv((struct memstick_host *)tifm_get_drvdata(sock));
0389 fifo_status = readl(sock->addr + SOCK_DMA_FIFO_STATUS);
0390 host_status = readl(sock->addr + SOCK_MS_STATUS);
0391 dev_dbg(&sock->dev,
0392 "data event: fifo_status %x, host_status %x, flags %x\n",
0393 fifo_status, host_status, host->cmd_flags);
0394
0395 if (host->req) {
0396 if (host->use_dma && (fifo_status & 1)) {
0397 host->cmd_flags |= FIFO_READY;
0398 rc = tifm_ms_check_status(host);
0399 }
0400 if (!host->use_dma && (fifo_status & TIFM_FIFO_MORE)) {
0401 if (!tifm_ms_transfer_data(host)) {
0402 host->cmd_flags |= FIFO_READY;
0403 rc = tifm_ms_check_status(host);
0404 }
0405 }
0406 }
0407
0408 writel(fifo_status, sock->addr + SOCK_DMA_FIFO_STATUS);
0409 if (!rc)
0410 tifm_ms_complete_cmd(host);
0411
0412 spin_unlock(&sock->lock);
0413 }
0414
0415
0416
0417 static void tifm_ms_card_event(struct tifm_dev *sock)
0418 {
0419 struct tifm_ms *host;
0420 unsigned int host_status = 0;
0421 int rc = 1;
0422
0423 spin_lock(&sock->lock);
0424 host = memstick_priv((struct memstick_host *)tifm_get_drvdata(sock));
0425 host_status = readl(sock->addr + SOCK_MS_STATUS);
0426 dev_dbg(&sock->dev, "host event: host_status %x, flags %x\n",
0427 host_status, host->cmd_flags);
0428
0429 if (host->req) {
0430 if (host_status & TIFM_MS_STAT_TOE)
0431 host->req->error = -ETIME;
0432 else if (host_status & TIFM_MS_STAT_CRC)
0433 host->req->error = -EILSEQ;
0434
0435 if (host_status & TIFM_MS_STAT_RDY)
0436 host->cmd_flags |= CMD_READY;
0437
0438 if (host_status & TIFM_MS_STAT_MSINT)
0439 host->cmd_flags |= CARD_INT;
0440
0441 rc = tifm_ms_check_status(host);
0442
0443 }
0444
0445 writel(TIFM_MS_SYS_INTCLR | readl(sock->addr + SOCK_MS_SYSTEM),
0446 sock->addr + SOCK_MS_SYSTEM);
0447
0448 if (!rc)
0449 tifm_ms_complete_cmd(host);
0450
0451 spin_unlock(&sock->lock);
0452 return;
0453 }
0454
0455 static void tifm_ms_req_tasklet(unsigned long data)
0456 {
0457 struct memstick_host *msh = (struct memstick_host *)data;
0458 struct tifm_ms *host = memstick_priv(msh);
0459 struct tifm_dev *sock = host->dev;
0460 unsigned long flags;
0461 int rc;
0462
0463 spin_lock_irqsave(&sock->lock, flags);
0464 if (!host->req) {
0465 if (host->eject) {
0466 do {
0467 rc = memstick_next_req(msh, &host->req);
0468 if (!rc)
0469 host->req->error = -ETIME;
0470 } while (!rc);
0471 spin_unlock_irqrestore(&sock->lock, flags);
0472 return;
0473 }
0474
0475 do {
0476 rc = memstick_next_req(msh, &host->req);
0477 } while (!rc && tifm_ms_issue_cmd(host));
0478 }
0479 spin_unlock_irqrestore(&sock->lock, flags);
0480 }
0481
0482 static void tifm_ms_dummy_submit(struct memstick_host *msh)
0483 {
0484 return;
0485 }
0486
0487 static void tifm_ms_submit_req(struct memstick_host *msh)
0488 {
0489 struct tifm_ms *host = memstick_priv(msh);
0490
0491 tasklet_schedule(&host->notify);
0492 }
0493
0494 static int tifm_ms_set_param(struct memstick_host *msh,
0495 enum memstick_param param,
0496 int value)
0497 {
0498 struct tifm_ms *host = memstick_priv(msh);
0499 struct tifm_dev *sock = host->dev;
0500
0501 switch (param) {
0502 case MEMSTICK_POWER:
0503
0504 if (value == MEMSTICK_POWER_ON) {
0505 host->mode_mask = TIFM_MS_SYS_SRAC | TIFM_MS_SYS_REI;
0506 writel(TIFM_MS_SYS_RESET, sock->addr + SOCK_MS_SYSTEM);
0507 writel(TIFM_MS_SYS_FCLR | TIFM_MS_SYS_INTCLR,
0508 sock->addr + SOCK_MS_SYSTEM);
0509 writel(0xffffffff, sock->addr + SOCK_MS_STATUS);
0510 } else if (value == MEMSTICK_POWER_OFF) {
0511 writel(TIFM_MS_SYS_FCLR | TIFM_MS_SYS_INTCLR,
0512 sock->addr + SOCK_MS_SYSTEM);
0513 writel(0xffffffff, sock->addr + SOCK_MS_STATUS);
0514 } else
0515 return -EINVAL;
0516 break;
0517 case MEMSTICK_INTERFACE:
0518 if (value == MEMSTICK_SERIAL) {
0519 host->mode_mask = TIFM_MS_SYS_SRAC | TIFM_MS_SYS_REI;
0520 writel((~TIFM_CTRL_FAST_CLK)
0521 & readl(sock->addr + SOCK_CONTROL),
0522 sock->addr + SOCK_CONTROL);
0523 } else if (value == MEMSTICK_PAR4) {
0524 host->mode_mask = 0;
0525 writel(TIFM_CTRL_FAST_CLK
0526 | readl(sock->addr + SOCK_CONTROL),
0527 sock->addr + SOCK_CONTROL);
0528 } else
0529 return -EINVAL;
0530 break;
0531 }
0532
0533 return 0;
0534 }
0535
0536 static void tifm_ms_abort(struct timer_list *t)
0537 {
0538 struct tifm_ms *host = from_timer(host, t, timer);
0539
0540 dev_dbg(&host->dev->dev, "status %x\n",
0541 readl(host->dev->addr + SOCK_MS_STATUS));
0542 printk(KERN_ERR
0543 "%s : card failed to respond for a long period of time "
0544 "(%x, %x)\n",
0545 dev_name(&host->dev->dev), host->req ? host->req->tpc : 0,
0546 host->cmd_flags);
0547
0548 tifm_eject(host->dev);
0549 }
0550
0551 static int tifm_ms_probe(struct tifm_dev *sock)
0552 {
0553 struct memstick_host *msh;
0554 struct tifm_ms *host;
0555 int rc = -EIO;
0556
0557 if (!(TIFM_SOCK_STATE_OCCUPIED
0558 & readl(sock->addr + SOCK_PRESENT_STATE))) {
0559 printk(KERN_WARNING "%s : card gone, unexpectedly\n",
0560 dev_name(&sock->dev));
0561 return rc;
0562 }
0563
0564 msh = memstick_alloc_host(sizeof(struct tifm_ms), &sock->dev);
0565 if (!msh)
0566 return -ENOMEM;
0567
0568 host = memstick_priv(msh);
0569 tifm_set_drvdata(sock, msh);
0570 host->dev = sock;
0571 host->timeout_jiffies = msecs_to_jiffies(1000);
0572
0573 timer_setup(&host->timer, tifm_ms_abort, 0);
0574 tasklet_init(&host->notify, tifm_ms_req_tasklet, (unsigned long)msh);
0575
0576 msh->request = tifm_ms_submit_req;
0577 msh->set_param = tifm_ms_set_param;
0578 sock->card_event = tifm_ms_card_event;
0579 sock->data_event = tifm_ms_data_event;
0580 if (tifm_has_ms_pif(sock))
0581 msh->caps |= MEMSTICK_CAP_PAR4;
0582
0583 rc = memstick_add_host(msh);
0584 if (!rc)
0585 return 0;
0586
0587 memstick_free_host(msh);
0588 return rc;
0589 }
0590
0591 static void tifm_ms_remove(struct tifm_dev *sock)
0592 {
0593 struct memstick_host *msh = tifm_get_drvdata(sock);
0594 struct tifm_ms *host = memstick_priv(msh);
0595 int rc = 0;
0596 unsigned long flags;
0597
0598 msh->request = tifm_ms_dummy_submit;
0599 tasklet_kill(&host->notify);
0600 spin_lock_irqsave(&sock->lock, flags);
0601 host->eject = 1;
0602 if (host->req) {
0603 del_timer(&host->timer);
0604 writel(TIFM_FIFO_INT_SETALL,
0605 sock->addr + SOCK_DMA_FIFO_INT_ENABLE_CLEAR);
0606 writel(TIFM_DMA_RESET, sock->addr + SOCK_DMA_CONTROL);
0607 if (host->use_dma)
0608 tifm_unmap_sg(sock, &host->req->sg, 1,
0609 host->req->data_dir == READ
0610 ? DMA_TO_DEVICE
0611 : DMA_FROM_DEVICE);
0612 host->req->error = -ETIME;
0613
0614 do {
0615 rc = memstick_next_req(msh, &host->req);
0616 if (!rc)
0617 host->req->error = -ETIME;
0618 } while (!rc);
0619 }
0620 spin_unlock_irqrestore(&sock->lock, flags);
0621
0622 memstick_remove_host(msh);
0623 memstick_free_host(msh);
0624 }
0625
0626 #ifdef CONFIG_PM
0627
0628 static int tifm_ms_suspend(struct tifm_dev *sock, pm_message_t state)
0629 {
0630 struct memstick_host *msh = tifm_get_drvdata(sock);
0631
0632 memstick_suspend_host(msh);
0633 return 0;
0634 }
0635
0636 static int tifm_ms_resume(struct tifm_dev *sock)
0637 {
0638 struct memstick_host *msh = tifm_get_drvdata(sock);
0639
0640 memstick_resume_host(msh);
0641 return 0;
0642 }
0643
0644 #else
0645
0646 #define tifm_ms_suspend NULL
0647 #define tifm_ms_resume NULL
0648
0649 #endif
0650
0651 static struct tifm_device_id tifm_ms_id_tbl[] = {
0652 { TIFM_TYPE_MS }, { 0 }
0653 };
0654
0655 static struct tifm_driver tifm_ms_driver = {
0656 .driver = {
0657 .name = DRIVER_NAME,
0658 .owner = THIS_MODULE
0659 },
0660 .id_table = tifm_ms_id_tbl,
0661 .probe = tifm_ms_probe,
0662 .remove = tifm_ms_remove,
0663 .suspend = tifm_ms_suspend,
0664 .resume = tifm_ms_resume
0665 };
0666
0667 static int __init tifm_ms_init(void)
0668 {
0669 return tifm_register_driver(&tifm_ms_driver);
0670 }
0671
0672 static void __exit tifm_ms_exit(void)
0673 {
0674 tifm_unregister_driver(&tifm_ms_driver);
0675 }
0676
0677 MODULE_AUTHOR("Alex Dubov");
0678 MODULE_DESCRIPTION("TI FlashMedia MemoryStick driver");
0679 MODULE_LICENSE("GPL");
0680 MODULE_DEVICE_TABLE(tifm, tifm_ms_id_tbl);
0681
0682 module_init(tifm_ms_init);
0683 module_exit(tifm_ms_exit);