Merge branch 'i2c-for-linus' of git://jdelvare.pck.nerim.net/jdelvare-2.6
[wrt350n-kernel.git] / drivers / memstick / host / jmb38x_ms.c
blob03fe8783b1ee0f41dace3f7f4a37a2c597a51050
1 /*
2 * jmb38x_ms.c - JMicron jmb38x MemoryStick card reader
4 * Copyright (C) 2008 Alex Dubov <oakad@yahoo.com>
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.
12 #include <linux/spinlock.h>
13 #include <linux/interrupt.h>
14 #include <linux/pci.h>
15 #include <linux/delay.h>
16 #include <linux/highmem.h>
17 #include <linux/memstick.h>
19 #define DRIVER_NAME "jmb38x_ms"
21 static int no_dma;
22 module_param(no_dma, bool, 0644);
24 enum {
25 DMA_ADDRESS = 0x00,
26 BLOCK = 0x04,
27 DMA_CONTROL = 0x08,
28 TPC_P0 = 0x0c,
29 TPC_P1 = 0x10,
30 TPC = 0x14,
31 HOST_CONTROL = 0x18,
32 DATA = 0x1c,
33 STATUS = 0x20,
34 INT_STATUS = 0x24,
35 INT_STATUS_ENABLE = 0x28,
36 INT_SIGNAL_ENABLE = 0x2c,
37 TIMER = 0x30,
38 TIMER_CONTROL = 0x34,
39 PAD_OUTPUT_ENABLE = 0x38,
40 PAD_PU_PD = 0x3c,
41 CLOCK_DELAY = 0x40,
42 ADMA_ADDRESS = 0x44,
43 CLOCK_CONTROL = 0x48,
44 LED_CONTROL = 0x4c,
45 VERSION = 0x50
48 struct jmb38x_ms_host {
49 struct jmb38x_ms *chip;
50 void __iomem *addr;
51 spinlock_t lock;
52 int id;
53 char host_id[DEVICE_ID_SIZE];
54 int irq;
55 unsigned int block_pos;
56 unsigned long timeout_jiffies;
57 struct timer_list timer;
58 struct memstick_request *req;
59 unsigned char eject:1,
60 use_dma:1;
61 unsigned char cmd_flags;
62 unsigned char io_pos;
63 unsigned int io_word[2];
66 struct jmb38x_ms {
67 struct pci_dev *pdev;
68 int host_cnt;
69 struct memstick_host *hosts[];
72 #define BLOCK_COUNT_MASK 0xffff0000
73 #define BLOCK_SIZE_MASK 0x00000fff
75 #define DMA_CONTROL_ENABLE 0x00000001
77 #define TPC_DATA_SEL 0x00008000
78 #define TPC_DIR 0x00004000
79 #define TPC_WAIT_INT 0x00002000
80 #define TPC_GET_INT 0x00000800
81 #define TPC_CODE_SZ_MASK 0x00000700
82 #define TPC_DATA_SZ_MASK 0x00000007
84 #define HOST_CONTROL_RESET_REQ 0x00008000
85 #define HOST_CONTROL_REI 0x00004000
86 #define HOST_CONTROL_LED 0x00000400
87 #define HOST_CONTROL_FAST_CLK 0x00000200
88 #define HOST_CONTROL_RESET 0x00000100
89 #define HOST_CONTROL_POWER_EN 0x00000080
90 #define HOST_CONTROL_CLOCK_EN 0x00000040
91 #define HOST_CONTROL_IF_SHIFT 4
93 #define HOST_CONTROL_IF_SERIAL 0x0
94 #define HOST_CONTROL_IF_PAR4 0x1
95 #define HOST_CONTROL_IF_PAR8 0x3
97 #define STATUS_HAS_MEDIA 0x00000400
98 #define STATUS_FIFO_EMPTY 0x00000200
99 #define STATUS_FIFO_FULL 0x00000100
101 #define INT_STATUS_TPC_ERR 0x00080000
102 #define INT_STATUS_CRC_ERR 0x00040000
103 #define INT_STATUS_TIMER_TO 0x00020000
104 #define INT_STATUS_HSK_TO 0x00010000
105 #define INT_STATUS_ANY_ERR 0x00008000
106 #define INT_STATUS_FIFO_WRDY 0x00000080
107 #define INT_STATUS_FIFO_RRDY 0x00000040
108 #define INT_STATUS_MEDIA_OUT 0x00000010
109 #define INT_STATUS_MEDIA_IN 0x00000008
110 #define INT_STATUS_DMA_BOUNDARY 0x00000004
111 #define INT_STATUS_EOTRAN 0x00000002
112 #define INT_STATUS_EOTPC 0x00000001
114 #define INT_STATUS_ALL 0x000f801f
116 #define PAD_OUTPUT_ENABLE_MS 0x0F3F
118 #define PAD_PU_PD_OFF 0x7FFF0000
119 #define PAD_PU_PD_ON_MS_SOCK0 0x5f8f0000
120 #define PAD_PU_PD_ON_MS_SOCK1 0x0f0f0000
122 enum {
123 CMD_READY = 0x01,
124 FIFO_READY = 0x02,
125 REG_DATA = 0x04,
126 AUTO_GET_INT = 0x08
129 static unsigned int jmb38x_ms_read_data(struct jmb38x_ms_host *host,
130 unsigned char *buf, unsigned int length)
132 unsigned int off = 0;
134 while (host->io_pos && length) {
135 buf[off++] = host->io_word[0] & 0xff;
136 host->io_word[0] >>= 8;
137 length--;
138 host->io_pos--;
141 if (!length)
142 return off;
144 while (!(STATUS_FIFO_EMPTY & readl(host->addr + STATUS))) {
145 if (length < 4)
146 break;
147 *(unsigned int *)(buf + off) = __raw_readl(host->addr + DATA);
148 length -= 4;
149 off += 4;
152 if (length
153 && !(STATUS_FIFO_EMPTY & readl(host->addr + STATUS))) {
154 host->io_word[0] = readl(host->addr + DATA);
155 for (host->io_pos = 4; host->io_pos; --host->io_pos) {
156 buf[off++] = host->io_word[0] & 0xff;
157 host->io_word[0] >>= 8;
158 length--;
159 if (!length)
160 break;
164 return off;
167 static unsigned int jmb38x_ms_read_reg_data(struct jmb38x_ms_host *host,
168 unsigned char *buf,
169 unsigned int length)
171 unsigned int off = 0;
173 while (host->io_pos > 4 && length) {
174 buf[off++] = host->io_word[0] & 0xff;
175 host->io_word[0] >>= 8;
176 length--;
177 host->io_pos--;
180 if (!length)
181 return off;
183 while (host->io_pos && length) {
184 buf[off++] = host->io_word[1] & 0xff;
185 host->io_word[1] >>= 8;
186 length--;
187 host->io_pos--;
190 return off;
193 static unsigned int jmb38x_ms_write_data(struct jmb38x_ms_host *host,
194 unsigned char *buf,
195 unsigned int length)
197 unsigned int off = 0;
199 if (host->io_pos) {
200 while (host->io_pos < 4 && length) {
201 host->io_word[0] |= buf[off++] << (host->io_pos * 8);
202 host->io_pos++;
203 length--;
207 if (host->io_pos == 4
208 && !(STATUS_FIFO_FULL & readl(host->addr + STATUS))) {
209 writel(host->io_word[0], host->addr + DATA);
210 host->io_pos = 0;
211 host->io_word[0] = 0;
212 } else if (host->io_pos) {
213 return off;
216 if (!length)
217 return off;
219 while (!(STATUS_FIFO_FULL & readl(host->addr + STATUS))) {
220 if (length < 4)
221 break;
223 __raw_writel(*(unsigned int *)(buf + off),
224 host->addr + DATA);
225 length -= 4;
226 off += 4;
229 switch (length) {
230 case 3:
231 host->io_word[0] |= buf[off + 2] << 16;
232 host->io_pos++;
233 case 2:
234 host->io_word[0] |= buf[off + 1] << 8;
235 host->io_pos++;
236 case 1:
237 host->io_word[0] |= buf[off];
238 host->io_pos++;
241 off += host->io_pos;
243 return off;
246 static unsigned int jmb38x_ms_write_reg_data(struct jmb38x_ms_host *host,
247 unsigned char *buf,
248 unsigned int length)
250 unsigned int off = 0;
252 while (host->io_pos < 4 && length) {
253 host->io_word[0] &= ~(0xff << (host->io_pos * 8));
254 host->io_word[0] |= buf[off++] << (host->io_pos * 8);
255 host->io_pos++;
256 length--;
259 if (!length)
260 return off;
262 while (host->io_pos < 8 && length) {
263 host->io_word[1] &= ~(0xff << (host->io_pos * 8));
264 host->io_word[1] |= buf[off++] << (host->io_pos * 8);
265 host->io_pos++;
266 length--;
269 return off;
272 static int jmb38x_ms_transfer_data(struct jmb38x_ms_host *host)
274 unsigned int length;
275 unsigned int off;
276 unsigned int t_size, p_off, p_cnt;
277 unsigned char *buf;
278 struct page *pg;
279 unsigned long flags = 0;
281 if (host->req->long_data) {
282 length = host->req->sg.length - host->block_pos;
283 off = host->req->sg.offset + host->block_pos;
284 } else {
285 length = host->req->data_len - host->block_pos;
286 off = 0;
289 while (length) {
290 if (host->req->long_data) {
291 pg = nth_page(sg_page(&host->req->sg),
292 off >> PAGE_SHIFT);
293 p_off = offset_in_page(off);
294 p_cnt = PAGE_SIZE - p_off;
295 p_cnt = min(p_cnt, length);
297 local_irq_save(flags);
298 buf = kmap_atomic(pg, KM_BIO_SRC_IRQ) + p_off;
299 } else {
300 buf = host->req->data + host->block_pos;
301 p_cnt = host->req->data_len - host->block_pos;
304 if (host->req->data_dir == WRITE)
305 t_size = !(host->cmd_flags & REG_DATA)
306 ? jmb38x_ms_write_data(host, buf, p_cnt)
307 : jmb38x_ms_write_reg_data(host, buf, p_cnt);
308 else
309 t_size = !(host->cmd_flags & REG_DATA)
310 ? jmb38x_ms_read_data(host, buf, p_cnt)
311 : jmb38x_ms_read_reg_data(host, buf, p_cnt);
313 if (host->req->long_data) {
314 kunmap_atomic(buf - p_off, KM_BIO_SRC_IRQ);
315 local_irq_restore(flags);
318 if (!t_size)
319 break;
320 host->block_pos += t_size;
321 length -= t_size;
322 off += t_size;
325 if (!length && host->req->data_dir == WRITE) {
326 if (host->cmd_flags & REG_DATA) {
327 writel(host->io_word[0], host->addr + TPC_P0);
328 writel(host->io_word[1], host->addr + TPC_P1);
329 } else if (host->io_pos) {
330 writel(host->io_word[0], host->addr + DATA);
334 return length;
337 static int jmb38x_ms_issue_cmd(struct memstick_host *msh)
339 struct jmb38x_ms_host *host = memstick_priv(msh);
340 unsigned char *data;
341 unsigned int data_len, cmd, t_val;
343 if (!(STATUS_HAS_MEDIA & readl(host->addr + STATUS))) {
344 dev_dbg(msh->cdev.dev, "no media status\n");
345 host->req->error = -ETIME;
346 return host->req->error;
349 dev_dbg(msh->cdev.dev, "control %08x\n",
350 readl(host->addr + HOST_CONTROL));
351 dev_dbg(msh->cdev.dev, "status %08x\n", readl(host->addr + INT_STATUS));
352 dev_dbg(msh->cdev.dev, "hstatus %08x\n", readl(host->addr + STATUS));
354 host->cmd_flags = 0;
355 host->block_pos = 0;
356 host->io_pos = 0;
357 host->io_word[0] = 0;
358 host->io_word[1] = 0;
360 cmd = host->req->tpc << 16;
361 cmd |= TPC_DATA_SEL;
363 if (host->req->data_dir == READ)
364 cmd |= TPC_DIR;
365 if (host->req->need_card_int)
366 cmd |= TPC_WAIT_INT;
367 if (host->req->get_int_reg)
368 cmd |= TPC_GET_INT;
370 data = host->req->data;
372 host->use_dma = !no_dma;
374 if (host->req->long_data) {
375 data_len = host->req->sg.length;
376 } else {
377 data_len = host->req->data_len;
378 host->use_dma = 0;
381 if (data_len <= 8) {
382 cmd &= ~(TPC_DATA_SEL | 0xf);
383 host->cmd_flags |= REG_DATA;
384 cmd |= data_len & 0xf;
385 host->use_dma = 0;
388 if (host->use_dma) {
389 if (1 != pci_map_sg(host->chip->pdev, &host->req->sg, 1,
390 host->req->data_dir == READ
391 ? PCI_DMA_FROMDEVICE
392 : PCI_DMA_TODEVICE)) {
393 host->req->error = -ENOMEM;
394 return host->req->error;
396 data_len = sg_dma_len(&host->req->sg);
397 writel(sg_dma_address(&host->req->sg),
398 host->addr + DMA_ADDRESS);
399 writel(((1 << 16) & BLOCK_COUNT_MASK)
400 | (data_len & BLOCK_SIZE_MASK),
401 host->addr + BLOCK);
402 writel(DMA_CONTROL_ENABLE, host->addr + DMA_CONTROL);
403 } else if (!(host->cmd_flags & REG_DATA)) {
404 writel(((1 << 16) & BLOCK_COUNT_MASK)
405 | (data_len & BLOCK_SIZE_MASK),
406 host->addr + BLOCK);
407 t_val = readl(host->addr + INT_STATUS_ENABLE);
408 t_val |= host->req->data_dir == READ
409 ? INT_STATUS_FIFO_RRDY
410 : INT_STATUS_FIFO_WRDY;
412 writel(t_val, host->addr + INT_STATUS_ENABLE);
413 writel(t_val, host->addr + INT_SIGNAL_ENABLE);
414 } else {
415 cmd &= ~(TPC_DATA_SEL | 0xf);
416 host->cmd_flags |= REG_DATA;
417 cmd |= data_len & 0xf;
419 if (host->req->data_dir == WRITE) {
420 jmb38x_ms_transfer_data(host);
421 writel(host->io_word[0], host->addr + TPC_P0);
422 writel(host->io_word[1], host->addr + TPC_P1);
426 mod_timer(&host->timer, jiffies + host->timeout_jiffies);
427 writel(HOST_CONTROL_LED | readl(host->addr + HOST_CONTROL),
428 host->addr + HOST_CONTROL);
429 host->req->error = 0;
431 writel(cmd, host->addr + TPC);
432 dev_dbg(msh->cdev.dev, "executing TPC %08x, len %x\n", cmd, data_len);
434 return 0;
437 static void jmb38x_ms_complete_cmd(struct memstick_host *msh, int last)
439 struct jmb38x_ms_host *host = memstick_priv(msh);
440 unsigned int t_val = 0;
441 int rc;
443 del_timer(&host->timer);
445 dev_dbg(msh->cdev.dev, "c control %08x\n",
446 readl(host->addr + HOST_CONTROL));
447 dev_dbg(msh->cdev.dev, "c status %08x\n",
448 readl(host->addr + INT_STATUS));
449 dev_dbg(msh->cdev.dev, "c hstatus %08x\n", readl(host->addr + STATUS));
451 if (host->req->get_int_reg) {
452 t_val = readl(host->addr + TPC_P0);
453 host->req->int_reg = (t_val & 0xff);
456 if (host->use_dma) {
457 writel(0, host->addr + DMA_CONTROL);
458 pci_unmap_sg(host->chip->pdev, &host->req->sg, 1,
459 host->req->data_dir == READ
460 ? PCI_DMA_FROMDEVICE : PCI_DMA_TODEVICE);
461 } else {
462 t_val = readl(host->addr + INT_STATUS_ENABLE);
463 if (host->req->data_dir == READ)
464 t_val &= ~INT_STATUS_FIFO_RRDY;
465 else
466 t_val &= ~INT_STATUS_FIFO_WRDY;
468 writel(t_val, host->addr + INT_STATUS_ENABLE);
469 writel(t_val, host->addr + INT_SIGNAL_ENABLE);
472 writel((~HOST_CONTROL_LED) & readl(host->addr + HOST_CONTROL),
473 host->addr + HOST_CONTROL);
475 if (!last) {
476 do {
477 rc = memstick_next_req(msh, &host->req);
478 } while (!rc && jmb38x_ms_issue_cmd(msh));
479 } else {
480 do {
481 rc = memstick_next_req(msh, &host->req);
482 if (!rc)
483 host->req->error = -ETIME;
484 } while (!rc);
488 static irqreturn_t jmb38x_ms_isr(int irq, void *dev_id)
490 struct memstick_host *msh = dev_id;
491 struct jmb38x_ms_host *host = memstick_priv(msh);
492 unsigned int irq_status;
494 spin_lock(&host->lock);
495 irq_status = readl(host->addr + INT_STATUS);
496 dev_dbg(&host->chip->pdev->dev, "irq_status = %08x\n", irq_status);
497 if (irq_status == 0 || irq_status == (~0)) {
498 spin_unlock(&host->lock);
499 return IRQ_NONE;
502 if (host->req) {
503 if (irq_status & INT_STATUS_ANY_ERR) {
504 if (irq_status & INT_STATUS_CRC_ERR)
505 host->req->error = -EILSEQ;
506 else
507 host->req->error = -ETIME;
508 } else {
509 if (host->use_dma) {
510 if (irq_status & INT_STATUS_EOTRAN)
511 host->cmd_flags |= FIFO_READY;
512 } else {
513 if (irq_status & (INT_STATUS_FIFO_RRDY
514 | INT_STATUS_FIFO_WRDY))
515 jmb38x_ms_transfer_data(host);
517 if (irq_status & INT_STATUS_EOTRAN) {
518 jmb38x_ms_transfer_data(host);
519 host->cmd_flags |= FIFO_READY;
523 if (irq_status & INT_STATUS_EOTPC) {
524 host->cmd_flags |= CMD_READY;
525 if (host->cmd_flags & REG_DATA) {
526 if (host->req->data_dir == READ) {
527 host->io_word[0]
528 = readl(host->addr
529 + TPC_P0);
530 host->io_word[1]
531 = readl(host->addr
532 + TPC_P1);
533 host->io_pos = 8;
535 jmb38x_ms_transfer_data(host);
537 host->cmd_flags |= FIFO_READY;
543 if (irq_status & (INT_STATUS_MEDIA_IN | INT_STATUS_MEDIA_OUT)) {
544 dev_dbg(&host->chip->pdev->dev, "media changed\n");
545 memstick_detect_change(msh);
548 writel(irq_status, host->addr + INT_STATUS);
550 if (host->req
551 && (((host->cmd_flags & CMD_READY)
552 && (host->cmd_flags & FIFO_READY))
553 || host->req->error))
554 jmb38x_ms_complete_cmd(msh, 0);
556 spin_unlock(&host->lock);
557 return IRQ_HANDLED;
560 static void jmb38x_ms_abort(unsigned long data)
562 struct memstick_host *msh = (struct memstick_host *)data;
563 struct jmb38x_ms_host *host = memstick_priv(msh);
564 unsigned long flags;
566 dev_dbg(&host->chip->pdev->dev, "abort\n");
567 spin_lock_irqsave(&host->lock, flags);
568 if (host->req) {
569 host->req->error = -ETIME;
570 jmb38x_ms_complete_cmd(msh, 0);
572 spin_unlock_irqrestore(&host->lock, flags);
575 static void jmb38x_ms_request(struct memstick_host *msh)
577 struct jmb38x_ms_host *host = memstick_priv(msh);
578 unsigned long flags;
579 int rc;
581 spin_lock_irqsave(&host->lock, flags);
582 if (host->req) {
583 spin_unlock_irqrestore(&host->lock, flags);
584 BUG();
585 return;
588 do {
589 rc = memstick_next_req(msh, &host->req);
590 } while (!rc && jmb38x_ms_issue_cmd(msh));
591 spin_unlock_irqrestore(&host->lock, flags);
594 static void jmb38x_ms_reset(struct jmb38x_ms_host *host)
596 unsigned int host_ctl = readl(host->addr + HOST_CONTROL);
598 writel(host_ctl | HOST_CONTROL_RESET_REQ | HOST_CONTROL_RESET,
599 host->addr + HOST_CONTROL);
601 while (HOST_CONTROL_RESET_REQ
602 & (host_ctl = readl(host->addr + HOST_CONTROL))) {
603 ndelay(100);
604 dev_dbg(&host->chip->pdev->dev, "reset\n");
607 writel(INT_STATUS_ALL, host->addr + INT_STATUS_ENABLE);
608 writel(INT_STATUS_ALL, host->addr + INT_SIGNAL_ENABLE);
610 dev_dbg(&host->chip->pdev->dev, "reset\n");
613 static void jmb38x_ms_set_param(struct memstick_host *msh,
614 enum memstick_param param,
615 int value)
617 struct jmb38x_ms_host *host = memstick_priv(msh);
618 unsigned int host_ctl;
619 unsigned long flags;
621 spin_lock_irqsave(&host->lock, flags);
623 switch (param) {
624 case MEMSTICK_POWER:
625 if (value == MEMSTICK_POWER_ON) {
626 jmb38x_ms_reset(host);
628 writel(host->id ? PAD_PU_PD_ON_MS_SOCK1
629 : PAD_PU_PD_ON_MS_SOCK0,
630 host->addr + PAD_PU_PD);
632 writel(PAD_OUTPUT_ENABLE_MS,
633 host->addr + PAD_OUTPUT_ENABLE);
635 host_ctl = readl(host->addr + HOST_CONTROL);
636 host_ctl |= 7;
637 writel(host_ctl | (HOST_CONTROL_POWER_EN
638 | HOST_CONTROL_CLOCK_EN),
639 host->addr + HOST_CONTROL);
641 dev_dbg(&host->chip->pdev->dev, "power on\n");
642 } else if (value == MEMSTICK_POWER_OFF) {
643 writel(readl(host->addr + HOST_CONTROL)
644 & ~(HOST_CONTROL_POWER_EN
645 | HOST_CONTROL_CLOCK_EN),
646 host->addr + HOST_CONTROL);
647 writel(0, host->addr + PAD_OUTPUT_ENABLE);
648 writel(PAD_PU_PD_OFF, host->addr + PAD_PU_PD);
649 dev_dbg(&host->chip->pdev->dev, "power off\n");
651 break;
652 case MEMSTICK_INTERFACE:
653 /* jmb38x_ms_reset(host); */
655 host_ctl = readl(host->addr + HOST_CONTROL);
656 host_ctl &= ~(3 << HOST_CONTROL_IF_SHIFT);
657 /* host_ctl |= 7; */
659 if (value == MEMSTICK_SERIAL) {
660 host_ctl &= ~HOST_CONTROL_FAST_CLK;
661 host_ctl |= HOST_CONTROL_IF_SERIAL
662 << HOST_CONTROL_IF_SHIFT;
663 host_ctl |= HOST_CONTROL_REI;
664 writel(0, host->addr + CLOCK_DELAY);
665 } else if (value == MEMSTICK_PAR4) {
666 host_ctl |= HOST_CONTROL_FAST_CLK;
667 host_ctl |= HOST_CONTROL_IF_PAR4
668 << HOST_CONTROL_IF_SHIFT;
669 host_ctl &= ~HOST_CONTROL_REI;
670 writel(4, host->addr + CLOCK_DELAY);
671 } else if (value == MEMSTICK_PAR8) {
672 host_ctl |= HOST_CONTROL_FAST_CLK;
673 host_ctl |= HOST_CONTROL_IF_PAR8
674 << HOST_CONTROL_IF_SHIFT;
675 host_ctl &= ~HOST_CONTROL_REI;
676 writel(4, host->addr + CLOCK_DELAY);
678 writel(host_ctl, host->addr + HOST_CONTROL);
679 break;
682 spin_unlock_irqrestore(&host->lock, flags);
685 #ifdef CONFIG_PM
687 static int jmb38x_ms_suspend(struct pci_dev *dev, pm_message_t state)
689 struct jmb38x_ms *jm = pci_get_drvdata(dev);
690 int cnt;
692 for (cnt = 0; cnt < jm->host_cnt; ++cnt) {
693 if (!jm->hosts[cnt])
694 break;
695 memstick_suspend_host(jm->hosts[cnt]);
698 pci_save_state(dev);
699 pci_enable_wake(dev, pci_choose_state(dev, state), 0);
700 pci_disable_device(dev);
701 pci_set_power_state(dev, pci_choose_state(dev, state));
702 return 0;
705 static int jmb38x_ms_resume(struct pci_dev *dev)
707 struct jmb38x_ms *jm = pci_get_drvdata(dev);
708 int rc;
710 pci_set_power_state(dev, PCI_D0);
711 pci_restore_state(dev);
712 rc = pci_enable_device(dev);
713 if (rc)
714 return rc;
715 pci_set_master(dev);
717 pci_read_config_dword(dev, 0xac, &rc);
718 pci_write_config_dword(dev, 0xac, rc | 0x00470000);
720 for (rc = 0; rc < jm->host_cnt; ++rc) {
721 if (!jm->hosts[rc])
722 break;
723 memstick_resume_host(jm->hosts[rc]);
724 memstick_detect_change(jm->hosts[rc]);
727 return 0;
730 #else
732 #define jmb38x_ms_suspend NULL
733 #define jmb38x_ms_resume NULL
735 #endif /* CONFIG_PM */
737 static int jmb38x_ms_count_slots(struct pci_dev *pdev)
739 int cnt, rc = 0;
741 for (cnt = 0; cnt < PCI_ROM_RESOURCE; ++cnt) {
742 if (!(IORESOURCE_MEM & pci_resource_flags(pdev, cnt)))
743 break;
745 if (256 != pci_resource_len(pdev, cnt))
746 break;
748 ++rc;
750 return rc;
753 static struct memstick_host *jmb38x_ms_alloc_host(struct jmb38x_ms *jm, int cnt)
755 struct memstick_host *msh;
756 struct jmb38x_ms_host *host;
758 msh = memstick_alloc_host(sizeof(struct jmb38x_ms_host),
759 &jm->pdev->dev);
760 if (!msh)
761 return NULL;
763 host = memstick_priv(msh);
764 host->chip = jm;
765 host->addr = ioremap(pci_resource_start(jm->pdev, cnt),
766 pci_resource_len(jm->pdev, cnt));
767 if (!host->addr)
768 goto err_out_free;
770 spin_lock_init(&host->lock);
771 host->id = cnt;
772 snprintf(host->host_id, DEVICE_ID_SIZE, DRIVER_NAME ":slot%d",
773 host->id);
774 host->irq = jm->pdev->irq;
775 host->timeout_jiffies = msecs_to_jiffies(4000);
776 msh->request = jmb38x_ms_request;
777 msh->set_param = jmb38x_ms_set_param;
779 msh->caps = MEMSTICK_CAP_AUTO_GET_INT | MEMSTICK_CAP_PAR4
780 | MEMSTICK_CAP_PAR8;
782 msh->caps = MEMSTICK_CAP_PAR4 | MEMSTICK_CAP_PAR8;
784 setup_timer(&host->timer, jmb38x_ms_abort, (unsigned long)msh);
786 if (!request_irq(host->irq, jmb38x_ms_isr, IRQF_SHARED, host->host_id,
787 msh))
788 return msh;
790 iounmap(host->addr);
791 err_out_free:
792 kfree(msh);
793 return NULL;
796 static void jmb38x_ms_free_host(struct memstick_host *msh)
798 struct jmb38x_ms_host *host = memstick_priv(msh);
800 free_irq(host->irq, msh);
801 iounmap(host->addr);
802 memstick_free_host(msh);
805 static int jmb38x_ms_probe(struct pci_dev *pdev,
806 const struct pci_device_id *dev_id)
808 struct jmb38x_ms *jm;
809 int pci_dev_busy = 0;
810 int rc, cnt;
812 rc = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
813 if (rc)
814 return rc;
816 rc = pci_enable_device(pdev);
817 if (rc)
818 return rc;
820 pci_set_master(pdev);
822 rc = pci_request_regions(pdev, DRIVER_NAME);
823 if (rc) {
824 pci_dev_busy = 1;
825 goto err_out;
828 pci_read_config_dword(pdev, 0xac, &rc);
829 pci_write_config_dword(pdev, 0xac, rc | 0x00470000);
831 cnt = jmb38x_ms_count_slots(pdev);
832 if (!cnt) {
833 rc = -ENODEV;
834 pci_dev_busy = 1;
835 goto err_out;
838 jm = kzalloc(sizeof(struct jmb38x_ms)
839 + cnt * sizeof(struct memstick_host *), GFP_KERNEL);
840 if (!jm) {
841 rc = -ENOMEM;
842 goto err_out_int;
845 jm->pdev = pdev;
846 jm->host_cnt = cnt;
847 pci_set_drvdata(pdev, jm);
849 for (cnt = 0; cnt < jm->host_cnt; ++cnt) {
850 jm->hosts[cnt] = jmb38x_ms_alloc_host(jm, cnt);
851 if (!jm->hosts[cnt])
852 break;
854 rc = memstick_add_host(jm->hosts[cnt]);
856 if (rc) {
857 jmb38x_ms_free_host(jm->hosts[cnt]);
858 jm->hosts[cnt] = NULL;
859 break;
863 if (cnt)
864 return 0;
866 rc = -ENODEV;
868 pci_set_drvdata(pdev, NULL);
869 kfree(jm);
870 err_out_int:
871 pci_release_regions(pdev);
872 err_out:
873 if (!pci_dev_busy)
874 pci_disable_device(pdev);
875 return rc;
878 static void jmb38x_ms_remove(struct pci_dev *dev)
880 struct jmb38x_ms *jm = pci_get_drvdata(dev);
881 struct jmb38x_ms_host *host;
882 int cnt;
883 unsigned long flags;
885 for (cnt = 0; cnt < jm->host_cnt; ++cnt) {
886 if (!jm->hosts[cnt])
887 break;
889 host = memstick_priv(jm->hosts[cnt]);
891 writel(0, host->addr + INT_SIGNAL_ENABLE);
892 writel(0, host->addr + INT_STATUS_ENABLE);
893 mmiowb();
894 dev_dbg(&jm->pdev->dev, "interrupts off\n");
895 spin_lock_irqsave(&host->lock, flags);
896 if (host->req) {
897 host->req->error = -ETIME;
898 jmb38x_ms_complete_cmd(jm->hosts[cnt], 1);
900 spin_unlock_irqrestore(&host->lock, flags);
902 memstick_remove_host(jm->hosts[cnt]);
903 dev_dbg(&jm->pdev->dev, "host removed\n");
905 jmb38x_ms_free_host(jm->hosts[cnt]);
908 pci_set_drvdata(dev, NULL);
909 pci_release_regions(dev);
910 pci_disable_device(dev);
911 kfree(jm);
914 static struct pci_device_id jmb38x_ms_id_tbl [] = {
915 { PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB38X_MS, PCI_ANY_ID,
916 PCI_ANY_ID, 0, 0, 0 },
920 static struct pci_driver jmb38x_ms_driver = {
921 .name = DRIVER_NAME,
922 .id_table = jmb38x_ms_id_tbl,
923 .probe = jmb38x_ms_probe,
924 .remove = jmb38x_ms_remove,
925 .suspend = jmb38x_ms_suspend,
926 .resume = jmb38x_ms_resume
929 static int __init jmb38x_ms_init(void)
931 return pci_register_driver(&jmb38x_ms_driver);
934 static void __exit jmb38x_ms_exit(void)
936 pci_unregister_driver(&jmb38x_ms_driver);
939 MODULE_AUTHOR("Alex Dubov");
940 MODULE_DESCRIPTION("JMicron jmb38x MemoryStick driver");
941 MODULE_LICENSE("GPL");
942 MODULE_DEVICE_TABLE(pci, jmb38x_ms_id_tbl);
944 module_init(jmb38x_ms_init);
945 module_exit(jmb38x_ms_exit);