Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  *  jmb38x_ms.c - JMicron jmb38x MemoryStick card reader
0004  *
0005  *  Copyright (C) 2008 Alex Dubov <oakad@yahoo.com>
0006  */
0007 
0008 #include <linux/spinlock.h>
0009 #include <linux/interrupt.h>
0010 #include <linux/pci.h>
0011 #include <linux/dma-mapping.h>
0012 #include <linux/delay.h>
0013 #include <linux/highmem.h>
0014 #include <linux/memstick.h>
0015 #include <linux/slab.h>
0016 #include <linux/module.h>
0017 
0018 #define DRIVER_NAME "jmb38x_ms"
0019 
0020 static bool no_dma;
0021 module_param(no_dma, bool, 0644);
0022 
0023 enum {
0024     DMA_ADDRESS       = 0x00,
0025     BLOCK             = 0x04,
0026     DMA_CONTROL       = 0x08,
0027     TPC_P0            = 0x0c,
0028     TPC_P1            = 0x10,
0029     TPC               = 0x14,
0030     HOST_CONTROL      = 0x18,
0031     DATA              = 0x1c,
0032     STATUS            = 0x20,
0033     INT_STATUS        = 0x24,
0034     INT_STATUS_ENABLE = 0x28,
0035     INT_SIGNAL_ENABLE = 0x2c,
0036     TIMER             = 0x30,
0037     TIMER_CONTROL     = 0x34,
0038     PAD_OUTPUT_ENABLE = 0x38,
0039     PAD_PU_PD         = 0x3c,
0040     CLOCK_DELAY       = 0x40,
0041     ADMA_ADDRESS      = 0x44,
0042     CLOCK_CONTROL     = 0x48,
0043     LED_CONTROL       = 0x4c,
0044     VERSION           = 0x50
0045 };
0046 
0047 struct jmb38x_ms_host {
0048     struct jmb38x_ms        *chip;
0049     void __iomem            *addr;
0050     spinlock_t              lock;
0051     struct tasklet_struct   notify;
0052     int                     id;
0053     char                    host_id[32];
0054     int                     irq;
0055     unsigned int            block_pos;
0056     unsigned long           timeout_jiffies;
0057     struct timer_list       timer;
0058     struct memstick_host    *msh;
0059     struct memstick_request *req;
0060     unsigned char           cmd_flags;
0061     unsigned char           io_pos;
0062     unsigned char           ifmode;
0063     unsigned int            io_word[2];
0064 };
0065 
0066 struct jmb38x_ms {
0067     struct pci_dev        *pdev;
0068     int                   host_cnt;
0069     struct memstick_host  *hosts[];
0070 };
0071 
0072 #define BLOCK_COUNT_MASK       0xffff0000
0073 #define BLOCK_SIZE_MASK        0x00000fff
0074 
0075 #define DMA_CONTROL_ENABLE     0x00000001
0076 
0077 #define TPC_DATA_SEL           0x00008000
0078 #define TPC_DIR                0x00004000
0079 #define TPC_WAIT_INT           0x00002000
0080 #define TPC_GET_INT            0x00000800
0081 #define TPC_CODE_SZ_MASK       0x00000700
0082 #define TPC_DATA_SZ_MASK       0x00000007
0083 
0084 #define HOST_CONTROL_TDELAY_EN 0x00040000
0085 #define HOST_CONTROL_HW_OC_P   0x00010000
0086 #define HOST_CONTROL_RESET_REQ 0x00008000
0087 #define HOST_CONTROL_REI       0x00004000
0088 #define HOST_CONTROL_LED       0x00000400
0089 #define HOST_CONTROL_FAST_CLK  0x00000200
0090 #define HOST_CONTROL_RESET     0x00000100
0091 #define HOST_CONTROL_POWER_EN  0x00000080
0092 #define HOST_CONTROL_CLOCK_EN  0x00000040
0093 #define HOST_CONTROL_REO       0x00000008
0094 #define HOST_CONTROL_IF_SHIFT  4
0095 
0096 #define HOST_CONTROL_IF_SERIAL 0x0
0097 #define HOST_CONTROL_IF_PAR4   0x1
0098 #define HOST_CONTROL_IF_PAR8   0x3
0099 
0100 #define STATUS_BUSY             0x00080000
0101 #define STATUS_MS_DAT7          0x00040000
0102 #define STATUS_MS_DAT6          0x00020000
0103 #define STATUS_MS_DAT5          0x00010000
0104 #define STATUS_MS_DAT4          0x00008000
0105 #define STATUS_MS_DAT3          0x00004000
0106 #define STATUS_MS_DAT2          0x00002000
0107 #define STATUS_MS_DAT1          0x00001000
0108 #define STATUS_MS_DAT0          0x00000800
0109 #define STATUS_HAS_MEDIA        0x00000400
0110 #define STATUS_FIFO_EMPTY       0x00000200
0111 #define STATUS_FIFO_FULL        0x00000100
0112 #define STATUS_MS_CED           0x00000080
0113 #define STATUS_MS_ERR           0x00000040
0114 #define STATUS_MS_BRQ           0x00000020
0115 #define STATUS_MS_CNK           0x00000001
0116 
0117 #define INT_STATUS_TPC_ERR      0x00080000
0118 #define INT_STATUS_CRC_ERR      0x00040000
0119 #define INT_STATUS_TIMER_TO     0x00020000
0120 #define INT_STATUS_HSK_TO       0x00010000
0121 #define INT_STATUS_ANY_ERR      0x00008000
0122 #define INT_STATUS_FIFO_WRDY    0x00000080
0123 #define INT_STATUS_FIFO_RRDY    0x00000040
0124 #define INT_STATUS_MEDIA_OUT    0x00000010
0125 #define INT_STATUS_MEDIA_IN     0x00000008
0126 #define INT_STATUS_DMA_BOUNDARY 0x00000004
0127 #define INT_STATUS_EOTRAN       0x00000002
0128 #define INT_STATUS_EOTPC        0x00000001
0129 
0130 #define INT_STATUS_ALL          0x000f801f
0131 
0132 #define PAD_OUTPUT_ENABLE_MS  0x0F3F
0133 
0134 #define PAD_PU_PD_OFF         0x7FFF0000
0135 #define PAD_PU_PD_ON_MS_SOCK0 0x5f8f0000
0136 #define PAD_PU_PD_ON_MS_SOCK1 0x0f0f0000
0137 
0138 #define CLOCK_CONTROL_BY_MMIO 0x00000008
0139 #define CLOCK_CONTROL_40MHZ   0x00000001
0140 #define CLOCK_CONTROL_50MHZ   0x00000002
0141 #define CLOCK_CONTROL_60MHZ   0x00000010
0142 #define CLOCK_CONTROL_62_5MHZ 0x00000004
0143 #define CLOCK_CONTROL_OFF     0x00000000
0144 
0145 #define PCI_CTL_CLOCK_DLY_ADDR   0x000000b0
0146 
0147 enum {
0148     CMD_READY    = 0x01,
0149     FIFO_READY   = 0x02,
0150     REG_DATA     = 0x04,
0151     DMA_DATA     = 0x08
0152 };
0153 
0154 static unsigned int jmb38x_ms_read_data(struct jmb38x_ms_host *host,
0155                     unsigned char *buf, unsigned int length)
0156 {
0157     unsigned int off = 0;
0158 
0159     while (host->io_pos && length) {
0160         buf[off++] = host->io_word[0] & 0xff;
0161         host->io_word[0] >>= 8;
0162         length--;
0163         host->io_pos--;
0164     }
0165 
0166     if (!length)
0167         return off;
0168 
0169     while (!(STATUS_FIFO_EMPTY & readl(host->addr + STATUS))) {
0170         if (length < 4)
0171             break;
0172         *(unsigned int *)(buf + off) = __raw_readl(host->addr + DATA);
0173         length -= 4;
0174         off += 4;
0175     }
0176 
0177     if (length
0178         && !(STATUS_FIFO_EMPTY & readl(host->addr + STATUS))) {
0179         host->io_word[0] = readl(host->addr + DATA);
0180         for (host->io_pos = 4; host->io_pos; --host->io_pos) {
0181             buf[off++] = host->io_word[0] & 0xff;
0182             host->io_word[0] >>= 8;
0183             length--;
0184             if (!length)
0185                 break;
0186         }
0187     }
0188 
0189     return off;
0190 }
0191 
0192 static unsigned int jmb38x_ms_read_reg_data(struct jmb38x_ms_host *host,
0193                         unsigned char *buf,
0194                         unsigned int length)
0195 {
0196     unsigned int off = 0;
0197 
0198     while (host->io_pos > 4 && length) {
0199         buf[off++] = host->io_word[0] & 0xff;
0200         host->io_word[0] >>= 8;
0201         length--;
0202         host->io_pos--;
0203     }
0204 
0205     if (!length)
0206         return off;
0207 
0208     while (host->io_pos && length) {
0209         buf[off++] = host->io_word[1] & 0xff;
0210         host->io_word[1] >>= 8;
0211         length--;
0212         host->io_pos--;
0213     }
0214 
0215     return off;
0216 }
0217 
0218 static unsigned int jmb38x_ms_write_data(struct jmb38x_ms_host *host,
0219                      unsigned char *buf,
0220                      unsigned int length)
0221 {
0222     unsigned int off = 0;
0223 
0224     if (host->io_pos) {
0225         while (host->io_pos < 4 && length) {
0226             host->io_word[0] |=  buf[off++] << (host->io_pos * 8);
0227             host->io_pos++;
0228             length--;
0229         }
0230     }
0231 
0232     if (host->io_pos == 4
0233         && !(STATUS_FIFO_FULL & readl(host->addr + STATUS))) {
0234         writel(host->io_word[0], host->addr + DATA);
0235         host->io_pos = 0;
0236         host->io_word[0] = 0;
0237     } else if (host->io_pos) {
0238         return off;
0239     }
0240 
0241     if (!length)
0242         return off;
0243 
0244     while (!(STATUS_FIFO_FULL & readl(host->addr + STATUS))) {
0245         if (length < 4)
0246             break;
0247 
0248         __raw_writel(*(unsigned int *)(buf + off),
0249                  host->addr + DATA);
0250         length -= 4;
0251         off += 4;
0252     }
0253 
0254     switch (length) {
0255     case 3:
0256         host->io_word[0] |= buf[off + 2] << 16;
0257         host->io_pos++;
0258         fallthrough;
0259     case 2:
0260         host->io_word[0] |= buf[off + 1] << 8;
0261         host->io_pos++;
0262         fallthrough;
0263     case 1:
0264         host->io_word[0] |= buf[off];
0265         host->io_pos++;
0266     }
0267 
0268     off += host->io_pos;
0269 
0270     return off;
0271 }
0272 
0273 static unsigned int jmb38x_ms_write_reg_data(struct jmb38x_ms_host *host,
0274                          unsigned char *buf,
0275                          unsigned int length)
0276 {
0277     unsigned int off = 0;
0278 
0279     while (host->io_pos < 4 && length) {
0280         host->io_word[0] &= ~(0xff << (host->io_pos * 8));
0281         host->io_word[0] |=  buf[off++] << (host->io_pos * 8);
0282         host->io_pos++;
0283         length--;
0284     }
0285 
0286     if (!length)
0287         return off;
0288 
0289     while (host->io_pos < 8 && length) {
0290         host->io_word[1] &= ~(0xff << (host->io_pos * 8));
0291         host->io_word[1] |=  buf[off++] << (host->io_pos * 8);
0292         host->io_pos++;
0293         length--;
0294     }
0295 
0296     return off;
0297 }
0298 
0299 static int jmb38x_ms_transfer_data(struct jmb38x_ms_host *host)
0300 {
0301     unsigned int length;
0302     unsigned int off;
0303     unsigned int t_size, p_cnt;
0304     unsigned char *buf;
0305     struct page *pg;
0306     unsigned long flags = 0;
0307 
0308     if (host->req->long_data) {
0309         length = host->req->sg.length - host->block_pos;
0310         off = host->req->sg.offset + host->block_pos;
0311     } else {
0312         length = host->req->data_len - host->block_pos;
0313         off = 0;
0314     }
0315 
0316     while (length) {
0317         unsigned int p_off;
0318 
0319         if (host->req->long_data) {
0320             pg = nth_page(sg_page(&host->req->sg),
0321                       off >> PAGE_SHIFT);
0322             p_off = offset_in_page(off);
0323             p_cnt = PAGE_SIZE - p_off;
0324             p_cnt = min(p_cnt, length);
0325 
0326             local_irq_save(flags);
0327             buf = kmap_atomic(pg) + p_off;
0328         } else {
0329             buf = host->req->data + host->block_pos;
0330             p_cnt = host->req->data_len - host->block_pos;
0331         }
0332 
0333         if (host->req->data_dir == WRITE)
0334             t_size = !(host->cmd_flags & REG_DATA)
0335                  ? jmb38x_ms_write_data(host, buf, p_cnt)
0336                  : jmb38x_ms_write_reg_data(host, buf, p_cnt);
0337         else
0338             t_size = !(host->cmd_flags & REG_DATA)
0339                  ? jmb38x_ms_read_data(host, buf, p_cnt)
0340                  : jmb38x_ms_read_reg_data(host, buf, p_cnt);
0341 
0342         if (host->req->long_data) {
0343             kunmap_atomic(buf - p_off);
0344             local_irq_restore(flags);
0345         }
0346 
0347         if (!t_size)
0348             break;
0349         host->block_pos += t_size;
0350         length -= t_size;
0351         off += t_size;
0352     }
0353 
0354     if (!length && host->req->data_dir == WRITE) {
0355         if (host->cmd_flags & REG_DATA) {
0356             writel(host->io_word[0], host->addr + TPC_P0);
0357             writel(host->io_word[1], host->addr + TPC_P1);
0358         } else if (host->io_pos) {
0359             writel(host->io_word[0], host->addr + DATA);
0360         }
0361     }
0362 
0363     return length;
0364 }
0365 
0366 static int jmb38x_ms_issue_cmd(struct memstick_host *msh)
0367 {
0368     struct jmb38x_ms_host *host = memstick_priv(msh);
0369     unsigned int data_len, cmd, t_val;
0370 
0371     if (!(STATUS_HAS_MEDIA & readl(host->addr + STATUS))) {
0372         dev_dbg(&msh->dev, "no media status\n");
0373         host->req->error = -ETIME;
0374         return host->req->error;
0375     }
0376 
0377     dev_dbg(&msh->dev, "control %08x\n", readl(host->addr + HOST_CONTROL));
0378     dev_dbg(&msh->dev, "status %08x\n", readl(host->addr + INT_STATUS));
0379     dev_dbg(&msh->dev, "hstatus %08x\n", readl(host->addr + STATUS));
0380 
0381     host->cmd_flags = 0;
0382     host->block_pos = 0;
0383     host->io_pos = 0;
0384     host->io_word[0] = 0;
0385     host->io_word[1] = 0;
0386 
0387     cmd = host->req->tpc << 16;
0388     cmd |= TPC_DATA_SEL;
0389 
0390     if (host->req->data_dir == READ)
0391         cmd |= TPC_DIR;
0392 
0393     if (host->req->need_card_int) {
0394         if (host->ifmode == MEMSTICK_SERIAL)
0395             cmd |= TPC_GET_INT;
0396         else
0397             cmd |= TPC_WAIT_INT;
0398     }
0399 
0400     if (!no_dma)
0401         host->cmd_flags |= DMA_DATA;
0402 
0403     if (host->req->long_data) {
0404         data_len = host->req->sg.length;
0405     } else {
0406         data_len = host->req->data_len;
0407         host->cmd_flags &= ~DMA_DATA;
0408     }
0409 
0410     if (data_len <= 8) {
0411         cmd &= ~(TPC_DATA_SEL | 0xf);
0412         host->cmd_flags |= REG_DATA;
0413         cmd |= data_len & 0xf;
0414         host->cmd_flags &= ~DMA_DATA;
0415     }
0416 
0417     if (host->cmd_flags & DMA_DATA) {
0418         if (1 != dma_map_sg(&host->chip->pdev->dev, &host->req->sg, 1,
0419                     host->req->data_dir == READ
0420                     ? DMA_FROM_DEVICE
0421                     : DMA_TO_DEVICE)) {
0422             host->req->error = -ENOMEM;
0423             return host->req->error;
0424         }
0425         data_len = sg_dma_len(&host->req->sg);
0426         writel(sg_dma_address(&host->req->sg),
0427                host->addr + DMA_ADDRESS);
0428         writel(((1 << 16) & BLOCK_COUNT_MASK)
0429                | (data_len & BLOCK_SIZE_MASK),
0430                host->addr + BLOCK);
0431         writel(DMA_CONTROL_ENABLE, host->addr + DMA_CONTROL);
0432     } else if (!(host->cmd_flags & REG_DATA)) {
0433         writel(((1 << 16) & BLOCK_COUNT_MASK)
0434                | (data_len & BLOCK_SIZE_MASK),
0435                host->addr + BLOCK);
0436         t_val = readl(host->addr + INT_STATUS_ENABLE);
0437         t_val |= host->req->data_dir == READ
0438              ? INT_STATUS_FIFO_RRDY
0439              : INT_STATUS_FIFO_WRDY;
0440 
0441         writel(t_val, host->addr + INT_STATUS_ENABLE);
0442         writel(t_val, host->addr + INT_SIGNAL_ENABLE);
0443     } else {
0444         cmd &= ~(TPC_DATA_SEL | 0xf);
0445         host->cmd_flags |= REG_DATA;
0446         cmd |= data_len & 0xf;
0447 
0448         if (host->req->data_dir == WRITE) {
0449             jmb38x_ms_transfer_data(host);
0450             writel(host->io_word[0], host->addr + TPC_P0);
0451             writel(host->io_word[1], host->addr + TPC_P1);
0452         }
0453     }
0454 
0455     mod_timer(&host->timer, jiffies + host->timeout_jiffies);
0456     writel(HOST_CONTROL_LED | readl(host->addr + HOST_CONTROL),
0457            host->addr + HOST_CONTROL);
0458     host->req->error = 0;
0459 
0460     writel(cmd, host->addr + TPC);
0461     dev_dbg(&msh->dev, "executing TPC %08x, len %x\n", cmd, data_len);
0462 
0463     return 0;
0464 }
0465 
0466 static void jmb38x_ms_complete_cmd(struct memstick_host *msh, int last)
0467 {
0468     struct jmb38x_ms_host *host = memstick_priv(msh);
0469     unsigned int t_val = 0;
0470     int rc;
0471 
0472     del_timer(&host->timer);
0473 
0474     dev_dbg(&msh->dev, "c control %08x\n",
0475         readl(host->addr + HOST_CONTROL));
0476     dev_dbg(&msh->dev, "c status %08x\n",
0477         readl(host->addr + INT_STATUS));
0478     dev_dbg(&msh->dev, "c hstatus %08x\n", readl(host->addr + STATUS));
0479 
0480     host->req->int_reg = readl(host->addr + STATUS) & 0xff;
0481 
0482     writel(0, host->addr + BLOCK);
0483     writel(0, host->addr + DMA_CONTROL);
0484 
0485     if (host->cmd_flags & DMA_DATA) {
0486         dma_unmap_sg(&host->chip->pdev->dev, &host->req->sg, 1,
0487                  host->req->data_dir == READ
0488                  ? DMA_FROM_DEVICE : DMA_TO_DEVICE);
0489     } else {
0490         t_val = readl(host->addr + INT_STATUS_ENABLE);
0491         if (host->req->data_dir == READ)
0492             t_val &= ~INT_STATUS_FIFO_RRDY;
0493         else
0494             t_val &= ~INT_STATUS_FIFO_WRDY;
0495 
0496         writel(t_val, host->addr + INT_STATUS_ENABLE);
0497         writel(t_val, host->addr + INT_SIGNAL_ENABLE);
0498     }
0499 
0500     writel((~HOST_CONTROL_LED) & readl(host->addr + HOST_CONTROL),
0501            host->addr + HOST_CONTROL);
0502 
0503     if (!last) {
0504         do {
0505             rc = memstick_next_req(msh, &host->req);
0506         } while (!rc && jmb38x_ms_issue_cmd(msh));
0507     } else {
0508         do {
0509             rc = memstick_next_req(msh, &host->req);
0510             if (!rc)
0511                 host->req->error = -ETIME;
0512         } while (!rc);
0513     }
0514 }
0515 
0516 static irqreturn_t jmb38x_ms_isr(int irq, void *dev_id)
0517 {
0518     struct memstick_host *msh = dev_id;
0519     struct jmb38x_ms_host *host = memstick_priv(msh);
0520     unsigned int irq_status;
0521 
0522     spin_lock(&host->lock);
0523     irq_status = readl(host->addr + INT_STATUS);
0524     dev_dbg(&host->chip->pdev->dev, "irq_status = %08x\n", irq_status);
0525     if (irq_status == 0 || irq_status == (~0)) {
0526         spin_unlock(&host->lock);
0527         return IRQ_NONE;
0528     }
0529 
0530     if (host->req) {
0531         if (irq_status & INT_STATUS_ANY_ERR) {
0532             if (irq_status & INT_STATUS_CRC_ERR)
0533                 host->req->error = -EILSEQ;
0534             else if (irq_status & INT_STATUS_TPC_ERR) {
0535                 dev_dbg(&host->chip->pdev->dev, "TPC_ERR\n");
0536                 jmb38x_ms_complete_cmd(msh, 0);
0537             } else
0538                 host->req->error = -ETIME;
0539         } else {
0540             if (host->cmd_flags & DMA_DATA) {
0541                 if (irq_status & INT_STATUS_EOTRAN)
0542                     host->cmd_flags |= FIFO_READY;
0543             } else {
0544                 if (irq_status & (INT_STATUS_FIFO_RRDY
0545                           | INT_STATUS_FIFO_WRDY))
0546                     jmb38x_ms_transfer_data(host);
0547 
0548                 if (irq_status & INT_STATUS_EOTRAN) {
0549                     jmb38x_ms_transfer_data(host);
0550                     host->cmd_flags |= FIFO_READY;
0551                 }
0552             }
0553 
0554             if (irq_status & INT_STATUS_EOTPC) {
0555                 host->cmd_flags |= CMD_READY;
0556                 if (host->cmd_flags & REG_DATA) {
0557                     if (host->req->data_dir == READ) {
0558                         host->io_word[0]
0559                             = readl(host->addr
0560                                 + TPC_P0);
0561                         host->io_word[1]
0562                             = readl(host->addr
0563                                 + TPC_P1);
0564                         host->io_pos = 8;
0565 
0566                         jmb38x_ms_transfer_data(host);
0567                     }
0568                     host->cmd_flags |= FIFO_READY;
0569                 }
0570             }
0571         }
0572     }
0573 
0574     if (irq_status & (INT_STATUS_MEDIA_IN | INT_STATUS_MEDIA_OUT)) {
0575         dev_dbg(&host->chip->pdev->dev, "media changed\n");
0576         memstick_detect_change(msh);
0577     }
0578 
0579     writel(irq_status, host->addr + INT_STATUS);
0580 
0581     if (host->req
0582         && (((host->cmd_flags & CMD_READY)
0583          && (host->cmd_flags & FIFO_READY))
0584         || host->req->error))
0585         jmb38x_ms_complete_cmd(msh, 0);
0586 
0587     spin_unlock(&host->lock);
0588     return IRQ_HANDLED;
0589 }
0590 
0591 static void jmb38x_ms_abort(struct timer_list *t)
0592 {
0593     struct jmb38x_ms_host *host = from_timer(host, t, timer);
0594     struct memstick_host *msh = host->msh;
0595     unsigned long flags;
0596 
0597     dev_dbg(&host->chip->pdev->dev, "abort\n");
0598     spin_lock_irqsave(&host->lock, flags);
0599     if (host->req) {
0600         host->req->error = -ETIME;
0601         jmb38x_ms_complete_cmd(msh, 0);
0602     }
0603     spin_unlock_irqrestore(&host->lock, flags);
0604 }
0605 
0606 static void jmb38x_ms_req_tasklet(unsigned long data)
0607 {
0608     struct memstick_host *msh = (struct memstick_host *)data;
0609     struct jmb38x_ms_host *host = memstick_priv(msh);
0610     unsigned long flags;
0611     int rc;
0612 
0613     spin_lock_irqsave(&host->lock, flags);
0614     if (!host->req) {
0615         do {
0616             rc = memstick_next_req(msh, &host->req);
0617             dev_dbg(&host->chip->pdev->dev, "tasklet req %d\n", rc);
0618         } while (!rc && jmb38x_ms_issue_cmd(msh));
0619     }
0620     spin_unlock_irqrestore(&host->lock, flags);
0621 }
0622 
0623 static void jmb38x_ms_dummy_submit(struct memstick_host *msh)
0624 {
0625     return;
0626 }
0627 
0628 static void jmb38x_ms_submit_req(struct memstick_host *msh)
0629 {
0630     struct jmb38x_ms_host *host = memstick_priv(msh);
0631 
0632     tasklet_schedule(&host->notify);
0633 }
0634 
0635 static int jmb38x_ms_reset(struct jmb38x_ms_host *host)
0636 {
0637     int cnt;
0638 
0639     writel(HOST_CONTROL_RESET_REQ | HOST_CONTROL_CLOCK_EN
0640            | readl(host->addr + HOST_CONTROL),
0641            host->addr + HOST_CONTROL);
0642 
0643     for (cnt = 0; cnt < 20; ++cnt) {
0644         if (!(HOST_CONTROL_RESET_REQ
0645               & readl(host->addr + HOST_CONTROL)))
0646             goto reset_next;
0647 
0648         ndelay(20);
0649     }
0650     dev_dbg(&host->chip->pdev->dev, "reset_req timeout\n");
0651 
0652 reset_next:
0653     writel(HOST_CONTROL_RESET | HOST_CONTROL_CLOCK_EN
0654            | readl(host->addr + HOST_CONTROL),
0655            host->addr + HOST_CONTROL);
0656 
0657     for (cnt = 0; cnt < 20; ++cnt) {
0658         if (!(HOST_CONTROL_RESET
0659               & readl(host->addr + HOST_CONTROL)))
0660             goto reset_ok;
0661 
0662         ndelay(20);
0663     }
0664     dev_dbg(&host->chip->pdev->dev, "reset timeout\n");
0665     return -EIO;
0666 
0667 reset_ok:
0668     writel(INT_STATUS_ALL, host->addr + INT_SIGNAL_ENABLE);
0669     writel(INT_STATUS_ALL, host->addr + INT_STATUS_ENABLE);
0670     return 0;
0671 }
0672 
0673 static int jmb38x_ms_set_param(struct memstick_host *msh,
0674                    enum memstick_param param,
0675                    int value)
0676 {
0677     struct jmb38x_ms_host *host = memstick_priv(msh);
0678     unsigned int host_ctl = readl(host->addr + HOST_CONTROL);
0679     unsigned int clock_ctl = CLOCK_CONTROL_BY_MMIO, clock_delay = 0;
0680     int rc = 0;
0681 
0682     switch (param) {
0683     case MEMSTICK_POWER:
0684         if (value == MEMSTICK_POWER_ON) {
0685             rc = jmb38x_ms_reset(host);
0686             if (rc)
0687                 return rc;
0688 
0689             host_ctl = 7;
0690             host_ctl |= HOST_CONTROL_POWER_EN
0691                  | HOST_CONTROL_CLOCK_EN;
0692             writel(host_ctl, host->addr + HOST_CONTROL);
0693 
0694             writel(host->id ? PAD_PU_PD_ON_MS_SOCK1
0695                     : PAD_PU_PD_ON_MS_SOCK0,
0696                    host->addr + PAD_PU_PD);
0697 
0698             writel(PAD_OUTPUT_ENABLE_MS,
0699                    host->addr + PAD_OUTPUT_ENABLE);
0700 
0701             msleep(10);
0702             dev_dbg(&host->chip->pdev->dev, "power on\n");
0703         } else if (value == MEMSTICK_POWER_OFF) {
0704             host_ctl &= ~(HOST_CONTROL_POWER_EN
0705                       | HOST_CONTROL_CLOCK_EN);
0706             writel(host_ctl, host->addr +  HOST_CONTROL);
0707             writel(0, host->addr + PAD_OUTPUT_ENABLE);
0708             writel(PAD_PU_PD_OFF, host->addr + PAD_PU_PD);
0709             dev_dbg(&host->chip->pdev->dev, "power off\n");
0710         } else
0711             return -EINVAL;
0712         break;
0713     case MEMSTICK_INTERFACE:
0714         dev_dbg(&host->chip->pdev->dev,
0715             "Set Host Interface Mode to %d\n", value);
0716         host_ctl &= ~(HOST_CONTROL_FAST_CLK | HOST_CONTROL_REI |
0717                   HOST_CONTROL_REO);
0718         host_ctl |= HOST_CONTROL_TDELAY_EN | HOST_CONTROL_HW_OC_P;
0719         host_ctl &= ~(3 << HOST_CONTROL_IF_SHIFT);
0720 
0721         if (value == MEMSTICK_SERIAL) {
0722             host_ctl |= HOST_CONTROL_IF_SERIAL
0723                     << HOST_CONTROL_IF_SHIFT;
0724             host_ctl |= HOST_CONTROL_REI;
0725             clock_ctl |= CLOCK_CONTROL_40MHZ;
0726             clock_delay = 0;
0727         } else if (value == MEMSTICK_PAR4) {
0728             host_ctl |= HOST_CONTROL_FAST_CLK;
0729             host_ctl |= HOST_CONTROL_IF_PAR4
0730                     << HOST_CONTROL_IF_SHIFT;
0731             host_ctl |= HOST_CONTROL_REO;
0732             clock_ctl |= CLOCK_CONTROL_40MHZ;
0733             clock_delay = 4;
0734         } else if (value == MEMSTICK_PAR8) {
0735             host_ctl |= HOST_CONTROL_FAST_CLK;
0736             host_ctl |= HOST_CONTROL_IF_PAR8
0737                     << HOST_CONTROL_IF_SHIFT;
0738             clock_ctl |= CLOCK_CONTROL_50MHZ;
0739             clock_delay = 0;
0740         } else
0741             return -EINVAL;
0742 
0743         writel(host_ctl, host->addr + HOST_CONTROL);
0744         writel(CLOCK_CONTROL_OFF, host->addr + CLOCK_CONTROL);
0745         writel(clock_ctl, host->addr + CLOCK_CONTROL);
0746         pci_write_config_byte(host->chip->pdev,
0747                       PCI_CTL_CLOCK_DLY_ADDR + 1,
0748                       clock_delay);
0749         host->ifmode = value;
0750         break;
0751     }
0752     return 0;
0753 }
0754 
0755 #define PCI_PMOS0_CONTROL       0xae
0756 #define  PMOS0_ENABLE           0x01
0757 #define  PMOS0_OVERCURRENT_LEVEL_2_4V   0x06
0758 #define  PMOS0_EN_OVERCURRENT_DEBOUNCE  0x40
0759 #define  PMOS0_SW_LED_POLARITY_ENABLE   0x80
0760 #define  PMOS0_ACTIVE_BITS (PMOS0_ENABLE | PMOS0_EN_OVERCURRENT_DEBOUNCE | \
0761                 PMOS0_OVERCURRENT_LEVEL_2_4V)
0762 #define PCI_PMOS1_CONTROL       0xbd
0763 #define  PMOS1_ACTIVE_BITS      0x4a
0764 #define PCI_CLOCK_CTL           0xb9
0765 
0766 static int jmb38x_ms_pmos(struct pci_dev *pdev, int flag)
0767 {
0768     unsigned char val;
0769 
0770     pci_read_config_byte(pdev, PCI_PMOS0_CONTROL, &val);
0771     if (flag)
0772         val |= PMOS0_ACTIVE_BITS;
0773     else
0774         val &= ~PMOS0_ACTIVE_BITS;
0775     pci_write_config_byte(pdev, PCI_PMOS0_CONTROL, val);
0776     dev_dbg(&pdev->dev, "JMB38x: set PMOS0 val 0x%x\n", val);
0777 
0778     if (pci_resource_flags(pdev, 1)) {
0779         pci_read_config_byte(pdev, PCI_PMOS1_CONTROL, &val);
0780         if (flag)
0781             val |= PMOS1_ACTIVE_BITS;
0782         else
0783             val &= ~PMOS1_ACTIVE_BITS;
0784         pci_write_config_byte(pdev, PCI_PMOS1_CONTROL, val);
0785         dev_dbg(&pdev->dev, "JMB38x: set PMOS1 val 0x%x\n", val);
0786     }
0787 
0788     pci_read_config_byte(pdev, PCI_CLOCK_CTL, &val);
0789     pci_write_config_byte(pdev, PCI_CLOCK_CTL, val & ~0x0f);
0790     pci_write_config_byte(pdev, PCI_CLOCK_CTL, val | 0x01);
0791     dev_dbg(&pdev->dev, "Clock Control by PCI config is disabled!\n");
0792 
0793         return 0;
0794 }
0795 
0796 static int __maybe_unused jmb38x_ms_suspend(struct device *dev)
0797 {
0798     struct jmb38x_ms *jm = dev_get_drvdata(dev);
0799 
0800     int cnt;
0801 
0802     for (cnt = 0; cnt < jm->host_cnt; ++cnt) {
0803         if (!jm->hosts[cnt])
0804             break;
0805         memstick_suspend_host(jm->hosts[cnt]);
0806     }
0807 
0808     device_wakeup_disable(dev);
0809 
0810     return 0;
0811 }
0812 
0813 static int __maybe_unused jmb38x_ms_resume(struct device *dev)
0814 {
0815     struct jmb38x_ms *jm = dev_get_drvdata(dev);
0816     int rc;
0817 
0818     jmb38x_ms_pmos(to_pci_dev(dev), 1);
0819 
0820     for (rc = 0; rc < jm->host_cnt; ++rc) {
0821         if (!jm->hosts[rc])
0822             break;
0823         memstick_resume_host(jm->hosts[rc]);
0824         memstick_detect_change(jm->hosts[rc]);
0825     }
0826 
0827     return 0;
0828 }
0829 
0830 static int jmb38x_ms_count_slots(struct pci_dev *pdev)
0831 {
0832     int cnt, rc = 0;
0833 
0834     for (cnt = 0; cnt < PCI_STD_NUM_BARS; ++cnt) {
0835         if (!(IORESOURCE_MEM & pci_resource_flags(pdev, cnt)))
0836             break;
0837 
0838         if (256 != pci_resource_len(pdev, cnt))
0839             break;
0840 
0841         ++rc;
0842     }
0843     return rc;
0844 }
0845 
0846 static struct memstick_host *jmb38x_ms_alloc_host(struct jmb38x_ms *jm, int cnt)
0847 {
0848     struct memstick_host *msh;
0849     struct jmb38x_ms_host *host;
0850 
0851     msh = memstick_alloc_host(sizeof(struct jmb38x_ms_host),
0852                   &jm->pdev->dev);
0853     if (!msh)
0854         return NULL;
0855 
0856     host = memstick_priv(msh);
0857     host->msh = msh;
0858     host->chip = jm;
0859     host->addr = ioremap(pci_resource_start(jm->pdev, cnt),
0860                  pci_resource_len(jm->pdev, cnt));
0861     if (!host->addr)
0862         goto err_out_free;
0863 
0864     spin_lock_init(&host->lock);
0865     host->id = cnt;
0866     snprintf(host->host_id, sizeof(host->host_id), DRIVER_NAME ":slot%d",
0867          host->id);
0868     host->irq = jm->pdev->irq;
0869     host->timeout_jiffies = msecs_to_jiffies(1000);
0870 
0871     tasklet_init(&host->notify, jmb38x_ms_req_tasklet, (unsigned long)msh);
0872     msh->request = jmb38x_ms_submit_req;
0873     msh->set_param = jmb38x_ms_set_param;
0874 
0875     msh->caps = MEMSTICK_CAP_PAR4 | MEMSTICK_CAP_PAR8;
0876 
0877     timer_setup(&host->timer, jmb38x_ms_abort, 0);
0878 
0879     if (!request_irq(host->irq, jmb38x_ms_isr, IRQF_SHARED, host->host_id,
0880              msh))
0881         return msh;
0882 
0883     iounmap(host->addr);
0884 err_out_free:
0885     memstick_free_host(msh);
0886     return NULL;
0887 }
0888 
0889 static void jmb38x_ms_free_host(struct memstick_host *msh)
0890 {
0891     struct jmb38x_ms_host *host = memstick_priv(msh);
0892 
0893     free_irq(host->irq, msh);
0894     iounmap(host->addr);
0895     memstick_free_host(msh);
0896 }
0897 
0898 static int jmb38x_ms_probe(struct pci_dev *pdev,
0899                const struct pci_device_id *dev_id)
0900 {
0901     struct jmb38x_ms *jm;
0902     int pci_dev_busy = 0;
0903     int rc, cnt;
0904 
0905     rc = dma_set_mask(&pdev->dev, DMA_BIT_MASK(32));
0906     if (rc)
0907         return rc;
0908 
0909     rc = pci_enable_device(pdev);
0910     if (rc)
0911         return rc;
0912 
0913     pci_set_master(pdev);
0914 
0915     rc = pci_request_regions(pdev, DRIVER_NAME);
0916     if (rc) {
0917         pci_dev_busy = 1;
0918         goto err_out;
0919     }
0920 
0921     jmb38x_ms_pmos(pdev, 1);
0922 
0923     cnt = jmb38x_ms_count_slots(pdev);
0924     if (!cnt) {
0925         rc = -ENODEV;
0926         pci_dev_busy = 1;
0927         goto err_out_int;
0928     }
0929 
0930     jm = kzalloc(struct_size(jm, hosts, cnt), GFP_KERNEL);
0931     if (!jm) {
0932         rc = -ENOMEM;
0933         goto err_out_int;
0934     }
0935 
0936     jm->pdev = pdev;
0937     jm->host_cnt = cnt;
0938     pci_set_drvdata(pdev, jm);
0939 
0940     for (cnt = 0; cnt < jm->host_cnt; ++cnt) {
0941         jm->hosts[cnt] = jmb38x_ms_alloc_host(jm, cnt);
0942         if (!jm->hosts[cnt])
0943             break;
0944 
0945         rc = memstick_add_host(jm->hosts[cnt]);
0946 
0947         if (rc) {
0948             jmb38x_ms_free_host(jm->hosts[cnt]);
0949             jm->hosts[cnt] = NULL;
0950             break;
0951         }
0952     }
0953 
0954     if (cnt)
0955         return 0;
0956 
0957     rc = -ENODEV;
0958 
0959     pci_set_drvdata(pdev, NULL);
0960     kfree(jm);
0961 err_out_int:
0962     pci_release_regions(pdev);
0963 err_out:
0964     if (!pci_dev_busy)
0965         pci_disable_device(pdev);
0966     return rc;
0967 }
0968 
0969 static void jmb38x_ms_remove(struct pci_dev *dev)
0970 {
0971     struct jmb38x_ms *jm = pci_get_drvdata(dev);
0972     struct jmb38x_ms_host *host;
0973     int cnt;
0974     unsigned long flags;
0975 
0976     for (cnt = 0; cnt < jm->host_cnt; ++cnt) {
0977         if (!jm->hosts[cnt])
0978             break;
0979 
0980         host = memstick_priv(jm->hosts[cnt]);
0981 
0982         jm->hosts[cnt]->request = jmb38x_ms_dummy_submit;
0983         tasklet_kill(&host->notify);
0984         writel(0, host->addr + INT_SIGNAL_ENABLE);
0985         writel(0, host->addr + INT_STATUS_ENABLE);
0986         dev_dbg(&jm->pdev->dev, "interrupts off\n");
0987         spin_lock_irqsave(&host->lock, flags);
0988         if (host->req) {
0989             host->req->error = -ETIME;
0990             jmb38x_ms_complete_cmd(jm->hosts[cnt], 1);
0991         }
0992         spin_unlock_irqrestore(&host->lock, flags);
0993 
0994         memstick_remove_host(jm->hosts[cnt]);
0995         dev_dbg(&jm->pdev->dev, "host removed\n");
0996 
0997         jmb38x_ms_free_host(jm->hosts[cnt]);
0998     }
0999 
1000     jmb38x_ms_pmos(dev, 0);
1001 
1002     pci_set_drvdata(dev, NULL);
1003     pci_release_regions(dev);
1004     pci_disable_device(dev);
1005     kfree(jm);
1006 }
1007 
1008 static struct pci_device_id jmb38x_ms_id_tbl [] = {
1009     { PCI_VDEVICE(JMICRON, PCI_DEVICE_ID_JMICRON_JMB38X_MS) },
1010     { PCI_VDEVICE(JMICRON, PCI_DEVICE_ID_JMICRON_JMB385_MS) },
1011     { PCI_VDEVICE(JMICRON, PCI_DEVICE_ID_JMICRON_JMB390_MS) },
1012     { }
1013 };
1014 
1015 static SIMPLE_DEV_PM_OPS(jmb38x_ms_pm_ops, jmb38x_ms_suspend, jmb38x_ms_resume);
1016 
1017 static struct pci_driver jmb38x_ms_driver = {
1018     .name = DRIVER_NAME,
1019     .id_table = jmb38x_ms_id_tbl,
1020     .probe = jmb38x_ms_probe,
1021     .remove = jmb38x_ms_remove,
1022     .driver.pm = &jmb38x_ms_pm_ops,
1023 };
1024 
1025 module_pci_driver(jmb38x_ms_driver);
1026 
1027 MODULE_AUTHOR("Alex Dubov");
1028 MODULE_DESCRIPTION("JMicron jmb38x MemoryStick driver");
1029 MODULE_LICENSE("GPL");
1030 MODULE_DEVICE_TABLE(pci, jmb38x_ms_id_tbl);