Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  *  TI FlashMedia driver
0004  *
0005  *  Copyright (C) 2007 Alex Dubov <oakad@yahoo.com>
0006  *
0007  * Special thanks to Carlos Corbacho for providing various MemoryStick cards
0008  * that made this driver possible.
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  * Some control bits of TIFM appear to conform to Sony's reference design,
0026  * so I'm just assuming they all are.
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 /* Hardware flags */
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 /* Called from interrupt handler */
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 /* Called from interrupt handler */
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         /* also affected by media detection mechanism */
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 /* CONFIG_PM */
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);