Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/drivers/memstick/host/jmb38x_ms.c
15111 views
1
/*
2
* jmb38x_ms.c - JMicron jmb38x MemoryStick card reader
3
*
4
* Copyright (C) 2008 Alex Dubov <[email protected]>
5
*
6
* This program is free software; you can redistribute it and/or modify
7
* it under the terms of the GNU General Public License version 2 as
8
* published by the Free Software Foundation.
9
*
10
*/
11
12
#include <linux/spinlock.h>
13
#include <linux/interrupt.h>
14
#include <linux/pci.h>
15
#include <linux/dma-mapping.h>
16
#include <linux/delay.h>
17
#include <linux/highmem.h>
18
#include <linux/memstick.h>
19
#include <linux/slab.h>
20
21
#define DRIVER_NAME "jmb38x_ms"
22
23
static int no_dma;
24
module_param(no_dma, bool, 0644);
25
26
enum {
27
DMA_ADDRESS = 0x00,
28
BLOCK = 0x04,
29
DMA_CONTROL = 0x08,
30
TPC_P0 = 0x0c,
31
TPC_P1 = 0x10,
32
TPC = 0x14,
33
HOST_CONTROL = 0x18,
34
DATA = 0x1c,
35
STATUS = 0x20,
36
INT_STATUS = 0x24,
37
INT_STATUS_ENABLE = 0x28,
38
INT_SIGNAL_ENABLE = 0x2c,
39
TIMER = 0x30,
40
TIMER_CONTROL = 0x34,
41
PAD_OUTPUT_ENABLE = 0x38,
42
PAD_PU_PD = 0x3c,
43
CLOCK_DELAY = 0x40,
44
ADMA_ADDRESS = 0x44,
45
CLOCK_CONTROL = 0x48,
46
LED_CONTROL = 0x4c,
47
VERSION = 0x50
48
};
49
50
struct jmb38x_ms_host {
51
struct jmb38x_ms *chip;
52
void __iomem *addr;
53
spinlock_t lock;
54
struct tasklet_struct notify;
55
int id;
56
char host_id[32];
57
int irq;
58
unsigned int block_pos;
59
unsigned long timeout_jiffies;
60
struct timer_list timer;
61
struct memstick_request *req;
62
unsigned char cmd_flags;
63
unsigned char io_pos;
64
unsigned char ifmode;
65
unsigned int io_word[2];
66
};
67
68
struct jmb38x_ms {
69
struct pci_dev *pdev;
70
int host_cnt;
71
struct memstick_host *hosts[];
72
};
73
74
#define BLOCK_COUNT_MASK 0xffff0000
75
#define BLOCK_SIZE_MASK 0x00000fff
76
77
#define DMA_CONTROL_ENABLE 0x00000001
78
79
#define TPC_DATA_SEL 0x00008000
80
#define TPC_DIR 0x00004000
81
#define TPC_WAIT_INT 0x00002000
82
#define TPC_GET_INT 0x00000800
83
#define TPC_CODE_SZ_MASK 0x00000700
84
#define TPC_DATA_SZ_MASK 0x00000007
85
86
#define HOST_CONTROL_TDELAY_EN 0x00040000
87
#define HOST_CONTROL_HW_OC_P 0x00010000
88
#define HOST_CONTROL_RESET_REQ 0x00008000
89
#define HOST_CONTROL_REI 0x00004000
90
#define HOST_CONTROL_LED 0x00000400
91
#define HOST_CONTROL_FAST_CLK 0x00000200
92
#define HOST_CONTROL_RESET 0x00000100
93
#define HOST_CONTROL_POWER_EN 0x00000080
94
#define HOST_CONTROL_CLOCK_EN 0x00000040
95
#define HOST_CONTROL_REO 0x00000008
96
#define HOST_CONTROL_IF_SHIFT 4
97
98
#define HOST_CONTROL_IF_SERIAL 0x0
99
#define HOST_CONTROL_IF_PAR4 0x1
100
#define HOST_CONTROL_IF_PAR8 0x3
101
102
#define STATUS_BUSY 0x00080000
103
#define STATUS_MS_DAT7 0x00040000
104
#define STATUS_MS_DAT6 0x00020000
105
#define STATUS_MS_DAT5 0x00010000
106
#define STATUS_MS_DAT4 0x00008000
107
#define STATUS_MS_DAT3 0x00004000
108
#define STATUS_MS_DAT2 0x00002000
109
#define STATUS_MS_DAT1 0x00001000
110
#define STATUS_MS_DAT0 0x00000800
111
#define STATUS_HAS_MEDIA 0x00000400
112
#define STATUS_FIFO_EMPTY 0x00000200
113
#define STATUS_FIFO_FULL 0x00000100
114
#define STATUS_MS_CED 0x00000080
115
#define STATUS_MS_ERR 0x00000040
116
#define STATUS_MS_BRQ 0x00000020
117
#define STATUS_MS_CNK 0x00000001
118
119
#define INT_STATUS_TPC_ERR 0x00080000
120
#define INT_STATUS_CRC_ERR 0x00040000
121
#define INT_STATUS_TIMER_TO 0x00020000
122
#define INT_STATUS_HSK_TO 0x00010000
123
#define INT_STATUS_ANY_ERR 0x00008000
124
#define INT_STATUS_FIFO_WRDY 0x00000080
125
#define INT_STATUS_FIFO_RRDY 0x00000040
126
#define INT_STATUS_MEDIA_OUT 0x00000010
127
#define INT_STATUS_MEDIA_IN 0x00000008
128
#define INT_STATUS_DMA_BOUNDARY 0x00000004
129
#define INT_STATUS_EOTRAN 0x00000002
130
#define INT_STATUS_EOTPC 0x00000001
131
132
#define INT_STATUS_ALL 0x000f801f
133
134
#define PAD_OUTPUT_ENABLE_MS 0x0F3F
135
136
#define PAD_PU_PD_OFF 0x7FFF0000
137
#define PAD_PU_PD_ON_MS_SOCK0 0x5f8f0000
138
#define PAD_PU_PD_ON_MS_SOCK1 0x0f0f0000
139
140
#define CLOCK_CONTROL_BY_MMIO 0x00000008
141
#define CLOCK_CONTROL_40MHZ 0x00000001
142
#define CLOCK_CONTROL_50MHZ 0x00000002
143
#define CLOCK_CONTROL_60MHZ 0x00000010
144
#define CLOCK_CONTROL_62_5MHZ 0x00000004
145
#define CLOCK_CONTROL_OFF 0x00000000
146
147
#define PCI_CTL_CLOCK_DLY_ADDR 0x000000b0
148
149
enum {
150
CMD_READY = 0x01,
151
FIFO_READY = 0x02,
152
REG_DATA = 0x04,
153
DMA_DATA = 0x08
154
};
155
156
static unsigned int jmb38x_ms_read_data(struct jmb38x_ms_host *host,
157
unsigned char *buf, unsigned int length)
158
{
159
unsigned int off = 0;
160
161
while (host->io_pos && length) {
162
buf[off++] = host->io_word[0] & 0xff;
163
host->io_word[0] >>= 8;
164
length--;
165
host->io_pos--;
166
}
167
168
if (!length)
169
return off;
170
171
while (!(STATUS_FIFO_EMPTY & readl(host->addr + STATUS))) {
172
if (length < 4)
173
break;
174
*(unsigned int *)(buf + off) = __raw_readl(host->addr + DATA);
175
length -= 4;
176
off += 4;
177
}
178
179
if (length
180
&& !(STATUS_FIFO_EMPTY & readl(host->addr + STATUS))) {
181
host->io_word[0] = readl(host->addr + DATA);
182
for (host->io_pos = 4; host->io_pos; --host->io_pos) {
183
buf[off++] = host->io_word[0] & 0xff;
184
host->io_word[0] >>= 8;
185
length--;
186
if (!length)
187
break;
188
}
189
}
190
191
return off;
192
}
193
194
static unsigned int jmb38x_ms_read_reg_data(struct jmb38x_ms_host *host,
195
unsigned char *buf,
196
unsigned int length)
197
{
198
unsigned int off = 0;
199
200
while (host->io_pos > 4 && length) {
201
buf[off++] = host->io_word[0] & 0xff;
202
host->io_word[0] >>= 8;
203
length--;
204
host->io_pos--;
205
}
206
207
if (!length)
208
return off;
209
210
while (host->io_pos && length) {
211
buf[off++] = host->io_word[1] & 0xff;
212
host->io_word[1] >>= 8;
213
length--;
214
host->io_pos--;
215
}
216
217
return off;
218
}
219
220
static unsigned int jmb38x_ms_write_data(struct jmb38x_ms_host *host,
221
unsigned char *buf,
222
unsigned int length)
223
{
224
unsigned int off = 0;
225
226
if (host->io_pos) {
227
while (host->io_pos < 4 && length) {
228
host->io_word[0] |= buf[off++] << (host->io_pos * 8);
229
host->io_pos++;
230
length--;
231
}
232
}
233
234
if (host->io_pos == 4
235
&& !(STATUS_FIFO_FULL & readl(host->addr + STATUS))) {
236
writel(host->io_word[0], host->addr + DATA);
237
host->io_pos = 0;
238
host->io_word[0] = 0;
239
} else if (host->io_pos) {
240
return off;
241
}
242
243
if (!length)
244
return off;
245
246
while (!(STATUS_FIFO_FULL & readl(host->addr + STATUS))) {
247
if (length < 4)
248
break;
249
250
__raw_writel(*(unsigned int *)(buf + off),
251
host->addr + DATA);
252
length -= 4;
253
off += 4;
254
}
255
256
switch (length) {
257
case 3:
258
host->io_word[0] |= buf[off + 2] << 16;
259
host->io_pos++;
260
case 2:
261
host->io_word[0] |= buf[off + 1] << 8;
262
host->io_pos++;
263
case 1:
264
host->io_word[0] |= buf[off];
265
host->io_pos++;
266
}
267
268
off += host->io_pos;
269
270
return off;
271
}
272
273
static unsigned int jmb38x_ms_write_reg_data(struct jmb38x_ms_host *host,
274
unsigned char *buf,
275
unsigned int length)
276
{
277
unsigned int off = 0;
278
279
while (host->io_pos < 4 && length) {
280
host->io_word[0] &= ~(0xff << (host->io_pos * 8));
281
host->io_word[0] |= buf[off++] << (host->io_pos * 8);
282
host->io_pos++;
283
length--;
284
}
285
286
if (!length)
287
return off;
288
289
while (host->io_pos < 8 && length) {
290
host->io_word[1] &= ~(0xff << (host->io_pos * 8));
291
host->io_word[1] |= buf[off++] << (host->io_pos * 8);
292
host->io_pos++;
293
length--;
294
}
295
296
return off;
297
}
298
299
static int jmb38x_ms_transfer_data(struct jmb38x_ms_host *host)
300
{
301
unsigned int length;
302
unsigned int off;
303
unsigned int t_size, p_cnt;
304
unsigned char *buf;
305
struct page *pg;
306
unsigned long flags = 0;
307
308
if (host->req->long_data) {
309
length = host->req->sg.length - host->block_pos;
310
off = host->req->sg.offset + host->block_pos;
311
} else {
312
length = host->req->data_len - host->block_pos;
313
off = 0;
314
}
315
316
while (length) {
317
unsigned int uninitialized_var(p_off);
318
319
if (host->req->long_data) {
320
pg = nth_page(sg_page(&host->req->sg),
321
off >> PAGE_SHIFT);
322
p_off = offset_in_page(off);
323
p_cnt = PAGE_SIZE - p_off;
324
p_cnt = min(p_cnt, length);
325
326
local_irq_save(flags);
327
buf = kmap_atomic(pg, KM_BIO_SRC_IRQ) + p_off;
328
} else {
329
buf = host->req->data + host->block_pos;
330
p_cnt = host->req->data_len - host->block_pos;
331
}
332
333
if (host->req->data_dir == WRITE)
334
t_size = !(host->cmd_flags & REG_DATA)
335
? jmb38x_ms_write_data(host, buf, p_cnt)
336
: jmb38x_ms_write_reg_data(host, buf, p_cnt);
337
else
338
t_size = !(host->cmd_flags & REG_DATA)
339
? jmb38x_ms_read_data(host, buf, p_cnt)
340
: jmb38x_ms_read_reg_data(host, buf, p_cnt);
341
342
if (host->req->long_data) {
343
kunmap_atomic(buf - p_off, KM_BIO_SRC_IRQ);
344
local_irq_restore(flags);
345
}
346
347
if (!t_size)
348
break;
349
host->block_pos += t_size;
350
length -= t_size;
351
off += t_size;
352
}
353
354
if (!length && host->req->data_dir == WRITE) {
355
if (host->cmd_flags & REG_DATA) {
356
writel(host->io_word[0], host->addr + TPC_P0);
357
writel(host->io_word[1], host->addr + TPC_P1);
358
} else if (host->io_pos) {
359
writel(host->io_word[0], host->addr + DATA);
360
}
361
}
362
363
return length;
364
}
365
366
static int jmb38x_ms_issue_cmd(struct memstick_host *msh)
367
{
368
struct jmb38x_ms_host *host = memstick_priv(msh);
369
unsigned char *data;
370
unsigned int data_len, cmd, t_val;
371
372
if (!(STATUS_HAS_MEDIA & readl(host->addr + STATUS))) {
373
dev_dbg(&msh->dev, "no media status\n");
374
host->req->error = -ETIME;
375
return host->req->error;
376
}
377
378
dev_dbg(&msh->dev, "control %08x\n", readl(host->addr + HOST_CONTROL));
379
dev_dbg(&msh->dev, "status %08x\n", readl(host->addr + INT_STATUS));
380
dev_dbg(&msh->dev, "hstatus %08x\n", readl(host->addr + STATUS));
381
382
host->cmd_flags = 0;
383
host->block_pos = 0;
384
host->io_pos = 0;
385
host->io_word[0] = 0;
386
host->io_word[1] = 0;
387
388
cmd = host->req->tpc << 16;
389
cmd |= TPC_DATA_SEL;
390
391
if (host->req->data_dir == READ)
392
cmd |= TPC_DIR;
393
394
if (host->req->need_card_int) {
395
if (host->ifmode == MEMSTICK_SERIAL)
396
cmd |= TPC_GET_INT;
397
else
398
cmd |= TPC_WAIT_INT;
399
}
400
401
data = host->req->data;
402
403
if (!no_dma)
404
host->cmd_flags |= DMA_DATA;
405
406
if (host->req->long_data) {
407
data_len = host->req->sg.length;
408
} else {
409
data_len = host->req->data_len;
410
host->cmd_flags &= ~DMA_DATA;
411
}
412
413
if (data_len <= 8) {
414
cmd &= ~(TPC_DATA_SEL | 0xf);
415
host->cmd_flags |= REG_DATA;
416
cmd |= data_len & 0xf;
417
host->cmd_flags &= ~DMA_DATA;
418
}
419
420
if (host->cmd_flags & DMA_DATA) {
421
if (1 != pci_map_sg(host->chip->pdev, &host->req->sg, 1,
422
host->req->data_dir == READ
423
? PCI_DMA_FROMDEVICE
424
: PCI_DMA_TODEVICE)) {
425
host->req->error = -ENOMEM;
426
return host->req->error;
427
}
428
data_len = sg_dma_len(&host->req->sg);
429
writel(sg_dma_address(&host->req->sg),
430
host->addr + DMA_ADDRESS);
431
writel(((1 << 16) & BLOCK_COUNT_MASK)
432
| (data_len & BLOCK_SIZE_MASK),
433
host->addr + BLOCK);
434
writel(DMA_CONTROL_ENABLE, host->addr + DMA_CONTROL);
435
} else if (!(host->cmd_flags & REG_DATA)) {
436
writel(((1 << 16) & BLOCK_COUNT_MASK)
437
| (data_len & BLOCK_SIZE_MASK),
438
host->addr + BLOCK);
439
t_val = readl(host->addr + INT_STATUS_ENABLE);
440
t_val |= host->req->data_dir == READ
441
? INT_STATUS_FIFO_RRDY
442
: INT_STATUS_FIFO_WRDY;
443
444
writel(t_val, host->addr + INT_STATUS_ENABLE);
445
writel(t_val, host->addr + INT_SIGNAL_ENABLE);
446
} else {
447
cmd &= ~(TPC_DATA_SEL | 0xf);
448
host->cmd_flags |= REG_DATA;
449
cmd |= data_len & 0xf;
450
451
if (host->req->data_dir == WRITE) {
452
jmb38x_ms_transfer_data(host);
453
writel(host->io_word[0], host->addr + TPC_P0);
454
writel(host->io_word[1], host->addr + TPC_P1);
455
}
456
}
457
458
mod_timer(&host->timer, jiffies + host->timeout_jiffies);
459
writel(HOST_CONTROL_LED | readl(host->addr + HOST_CONTROL),
460
host->addr + HOST_CONTROL);
461
host->req->error = 0;
462
463
writel(cmd, host->addr + TPC);
464
dev_dbg(&msh->dev, "executing TPC %08x, len %x\n", cmd, data_len);
465
466
return 0;
467
}
468
469
static void jmb38x_ms_complete_cmd(struct memstick_host *msh, int last)
470
{
471
struct jmb38x_ms_host *host = memstick_priv(msh);
472
unsigned int t_val = 0;
473
int rc;
474
475
del_timer(&host->timer);
476
477
dev_dbg(&msh->dev, "c control %08x\n",
478
readl(host->addr + HOST_CONTROL));
479
dev_dbg(&msh->dev, "c status %08x\n",
480
readl(host->addr + INT_STATUS));
481
dev_dbg(&msh->dev, "c hstatus %08x\n", readl(host->addr + STATUS));
482
483
host->req->int_reg = readl(host->addr + STATUS) & 0xff;
484
485
writel(0, host->addr + BLOCK);
486
writel(0, host->addr + DMA_CONTROL);
487
488
if (host->cmd_flags & DMA_DATA) {
489
pci_unmap_sg(host->chip->pdev, &host->req->sg, 1,
490
host->req->data_dir == READ
491
? PCI_DMA_FROMDEVICE : PCI_DMA_TODEVICE);
492
} else {
493
t_val = readl(host->addr + INT_STATUS_ENABLE);
494
if (host->req->data_dir == READ)
495
t_val &= ~INT_STATUS_FIFO_RRDY;
496
else
497
t_val &= ~INT_STATUS_FIFO_WRDY;
498
499
writel(t_val, host->addr + INT_STATUS_ENABLE);
500
writel(t_val, host->addr + INT_SIGNAL_ENABLE);
501
}
502
503
writel((~HOST_CONTROL_LED) & readl(host->addr + HOST_CONTROL),
504
host->addr + HOST_CONTROL);
505
506
if (!last) {
507
do {
508
rc = memstick_next_req(msh, &host->req);
509
} while (!rc && jmb38x_ms_issue_cmd(msh));
510
} else {
511
do {
512
rc = memstick_next_req(msh, &host->req);
513
if (!rc)
514
host->req->error = -ETIME;
515
} while (!rc);
516
}
517
}
518
519
static irqreturn_t jmb38x_ms_isr(int irq, void *dev_id)
520
{
521
struct memstick_host *msh = dev_id;
522
struct jmb38x_ms_host *host = memstick_priv(msh);
523
unsigned int irq_status;
524
525
spin_lock(&host->lock);
526
irq_status = readl(host->addr + INT_STATUS);
527
dev_dbg(&host->chip->pdev->dev, "irq_status = %08x\n", irq_status);
528
if (irq_status == 0 || irq_status == (~0)) {
529
spin_unlock(&host->lock);
530
return IRQ_NONE;
531
}
532
533
if (host->req) {
534
if (irq_status & INT_STATUS_ANY_ERR) {
535
if (irq_status & INT_STATUS_CRC_ERR)
536
host->req->error = -EILSEQ;
537
else if (irq_status & INT_STATUS_TPC_ERR) {
538
dev_dbg(&host->chip->pdev->dev, "TPC_ERR\n");
539
jmb38x_ms_complete_cmd(msh, 0);
540
} else
541
host->req->error = -ETIME;
542
} else {
543
if (host->cmd_flags & DMA_DATA) {
544
if (irq_status & INT_STATUS_EOTRAN)
545
host->cmd_flags |= FIFO_READY;
546
} else {
547
if (irq_status & (INT_STATUS_FIFO_RRDY
548
| INT_STATUS_FIFO_WRDY))
549
jmb38x_ms_transfer_data(host);
550
551
if (irq_status & INT_STATUS_EOTRAN) {
552
jmb38x_ms_transfer_data(host);
553
host->cmd_flags |= FIFO_READY;
554
}
555
}
556
557
if (irq_status & INT_STATUS_EOTPC) {
558
host->cmd_flags |= CMD_READY;
559
if (host->cmd_flags & REG_DATA) {
560
if (host->req->data_dir == READ) {
561
host->io_word[0]
562
= readl(host->addr
563
+ TPC_P0);
564
host->io_word[1]
565
= readl(host->addr
566
+ TPC_P1);
567
host->io_pos = 8;
568
569
jmb38x_ms_transfer_data(host);
570
}
571
host->cmd_flags |= FIFO_READY;
572
}
573
}
574
}
575
}
576
577
if (irq_status & (INT_STATUS_MEDIA_IN | INT_STATUS_MEDIA_OUT)) {
578
dev_dbg(&host->chip->pdev->dev, "media changed\n");
579
memstick_detect_change(msh);
580
}
581
582
writel(irq_status, host->addr + INT_STATUS);
583
584
if (host->req
585
&& (((host->cmd_flags & CMD_READY)
586
&& (host->cmd_flags & FIFO_READY))
587
|| host->req->error))
588
jmb38x_ms_complete_cmd(msh, 0);
589
590
spin_unlock(&host->lock);
591
return IRQ_HANDLED;
592
}
593
594
static void jmb38x_ms_abort(unsigned long data)
595
{
596
struct memstick_host *msh = (struct memstick_host *)data;
597
struct jmb38x_ms_host *host = memstick_priv(msh);
598
unsigned long flags;
599
600
dev_dbg(&host->chip->pdev->dev, "abort\n");
601
spin_lock_irqsave(&host->lock, flags);
602
if (host->req) {
603
host->req->error = -ETIME;
604
jmb38x_ms_complete_cmd(msh, 0);
605
}
606
spin_unlock_irqrestore(&host->lock, flags);
607
}
608
609
static void jmb38x_ms_req_tasklet(unsigned long data)
610
{
611
struct memstick_host *msh = (struct memstick_host *)data;
612
struct jmb38x_ms_host *host = memstick_priv(msh);
613
unsigned long flags;
614
int rc;
615
616
spin_lock_irqsave(&host->lock, flags);
617
if (!host->req) {
618
do {
619
rc = memstick_next_req(msh, &host->req);
620
dev_dbg(&host->chip->pdev->dev, "tasklet req %d\n", rc);
621
} while (!rc && jmb38x_ms_issue_cmd(msh));
622
}
623
spin_unlock_irqrestore(&host->lock, flags);
624
}
625
626
static void jmb38x_ms_dummy_submit(struct memstick_host *msh)
627
{
628
return;
629
}
630
631
static void jmb38x_ms_submit_req(struct memstick_host *msh)
632
{
633
struct jmb38x_ms_host *host = memstick_priv(msh);
634
635
tasklet_schedule(&host->notify);
636
}
637
638
static int jmb38x_ms_reset(struct jmb38x_ms_host *host)
639
{
640
int cnt;
641
642
writel(HOST_CONTROL_RESET_REQ | HOST_CONTROL_CLOCK_EN
643
| readl(host->addr + HOST_CONTROL),
644
host->addr + HOST_CONTROL);
645
mmiowb();
646
647
for (cnt = 0; cnt < 20; ++cnt) {
648
if (!(HOST_CONTROL_RESET_REQ
649
& readl(host->addr + HOST_CONTROL)))
650
goto reset_next;
651
652
ndelay(20);
653
}
654
dev_dbg(&host->chip->pdev->dev, "reset_req timeout\n");
655
656
reset_next:
657
writel(HOST_CONTROL_RESET | HOST_CONTROL_CLOCK_EN
658
| readl(host->addr + HOST_CONTROL),
659
host->addr + HOST_CONTROL);
660
mmiowb();
661
662
for (cnt = 0; cnt < 20; ++cnt) {
663
if (!(HOST_CONTROL_RESET
664
& readl(host->addr + HOST_CONTROL)))
665
goto reset_ok;
666
667
ndelay(20);
668
}
669
dev_dbg(&host->chip->pdev->dev, "reset timeout\n");
670
return -EIO;
671
672
reset_ok:
673
mmiowb();
674
writel(INT_STATUS_ALL, host->addr + INT_SIGNAL_ENABLE);
675
writel(INT_STATUS_ALL, host->addr + INT_STATUS_ENABLE);
676
return 0;
677
}
678
679
static int jmb38x_ms_set_param(struct memstick_host *msh,
680
enum memstick_param param,
681
int value)
682
{
683
struct jmb38x_ms_host *host = memstick_priv(msh);
684
unsigned int host_ctl = readl(host->addr + HOST_CONTROL);
685
unsigned int clock_ctl = CLOCK_CONTROL_BY_MMIO, clock_delay = 0;
686
int rc = 0;
687
688
switch (param) {
689
case MEMSTICK_POWER:
690
if (value == MEMSTICK_POWER_ON) {
691
rc = jmb38x_ms_reset(host);
692
if (rc)
693
return rc;
694
695
host_ctl = 7;
696
host_ctl |= HOST_CONTROL_POWER_EN
697
| HOST_CONTROL_CLOCK_EN;
698
writel(host_ctl, host->addr + HOST_CONTROL);
699
700
writel(host->id ? PAD_PU_PD_ON_MS_SOCK1
701
: PAD_PU_PD_ON_MS_SOCK0,
702
host->addr + PAD_PU_PD);
703
704
writel(PAD_OUTPUT_ENABLE_MS,
705
host->addr + PAD_OUTPUT_ENABLE);
706
707
msleep(10);
708
dev_dbg(&host->chip->pdev->dev, "power on\n");
709
} else if (value == MEMSTICK_POWER_OFF) {
710
host_ctl &= ~(HOST_CONTROL_POWER_EN
711
| HOST_CONTROL_CLOCK_EN);
712
writel(host_ctl, host->addr + HOST_CONTROL);
713
writel(0, host->addr + PAD_OUTPUT_ENABLE);
714
writel(PAD_PU_PD_OFF, host->addr + PAD_PU_PD);
715
dev_dbg(&host->chip->pdev->dev, "power off\n");
716
} else
717
return -EINVAL;
718
break;
719
case MEMSTICK_INTERFACE:
720
dev_dbg(&host->chip->pdev->dev,
721
"Set Host Interface Mode to %d\n", value);
722
host_ctl &= ~(HOST_CONTROL_FAST_CLK | HOST_CONTROL_REI |
723
HOST_CONTROL_REO);
724
host_ctl |= HOST_CONTROL_TDELAY_EN | HOST_CONTROL_HW_OC_P;
725
host_ctl &= ~(3 << HOST_CONTROL_IF_SHIFT);
726
727
if (value == MEMSTICK_SERIAL) {
728
host_ctl |= HOST_CONTROL_IF_SERIAL
729
<< HOST_CONTROL_IF_SHIFT;
730
host_ctl |= HOST_CONTROL_REI;
731
clock_ctl |= CLOCK_CONTROL_40MHZ;
732
clock_delay = 0;
733
} else if (value == MEMSTICK_PAR4) {
734
host_ctl |= HOST_CONTROL_FAST_CLK;
735
host_ctl |= HOST_CONTROL_IF_PAR4
736
<< HOST_CONTROL_IF_SHIFT;
737
host_ctl |= HOST_CONTROL_REO;
738
clock_ctl |= CLOCK_CONTROL_40MHZ;
739
clock_delay = 4;
740
} else if (value == MEMSTICK_PAR8) {
741
host_ctl |= HOST_CONTROL_FAST_CLK;
742
host_ctl |= HOST_CONTROL_IF_PAR8
743
<< HOST_CONTROL_IF_SHIFT;
744
clock_ctl |= CLOCK_CONTROL_50MHZ;
745
clock_delay = 0;
746
} else
747
return -EINVAL;
748
749
writel(host_ctl, host->addr + HOST_CONTROL);
750
writel(CLOCK_CONTROL_OFF, host->addr + CLOCK_CONTROL);
751
writel(clock_ctl, host->addr + CLOCK_CONTROL);
752
pci_write_config_byte(host->chip->pdev,
753
PCI_CTL_CLOCK_DLY_ADDR + 1,
754
clock_delay);
755
host->ifmode = value;
756
break;
757
};
758
return 0;
759
}
760
761
#define PCI_PMOS0_CONTROL 0xae
762
#define PMOS0_ENABLE 0x01
763
#define PMOS0_OVERCURRENT_LEVEL_2_4V 0x06
764
#define PMOS0_EN_OVERCURRENT_DEBOUNCE 0x40
765
#define PMOS0_SW_LED_POLARITY_ENABLE 0x80
766
#define PMOS0_ACTIVE_BITS (PMOS0_ENABLE | PMOS0_EN_OVERCURRENT_DEBOUNCE | \
767
PMOS0_OVERCURRENT_LEVEL_2_4V)
768
#define PCI_PMOS1_CONTROL 0xbd
769
#define PMOS1_ACTIVE_BITS 0x4a
770
#define PCI_CLOCK_CTL 0xb9
771
772
static int jmb38x_ms_pmos(struct pci_dev *pdev, int flag)
773
{
774
unsigned char val;
775
776
pci_read_config_byte(pdev, PCI_PMOS0_CONTROL, &val);
777
if (flag)
778
val |= PMOS0_ACTIVE_BITS;
779
else
780
val &= ~PMOS0_ACTIVE_BITS;
781
pci_write_config_byte(pdev, PCI_PMOS0_CONTROL, val);
782
dev_dbg(&pdev->dev, "JMB38x: set PMOS0 val 0x%x\n", val);
783
784
if (pci_resource_flags(pdev, 1)) {
785
pci_read_config_byte(pdev, PCI_PMOS1_CONTROL, &val);
786
if (flag)
787
val |= PMOS1_ACTIVE_BITS;
788
else
789
val &= ~PMOS1_ACTIVE_BITS;
790
pci_write_config_byte(pdev, PCI_PMOS1_CONTROL, val);
791
dev_dbg(&pdev->dev, "JMB38x: set PMOS1 val 0x%x\n", val);
792
}
793
794
pci_read_config_byte(pdev, PCI_CLOCK_CTL, &val);
795
pci_write_config_byte(pdev, PCI_CLOCK_CTL, val & ~0x0f);
796
pci_write_config_byte(pdev, PCI_CLOCK_CTL, val | 0x01);
797
dev_dbg(&pdev->dev, "Clock Control by PCI config is disabled!\n");
798
799
return 0;
800
}
801
802
#ifdef CONFIG_PM
803
804
static int jmb38x_ms_suspend(struct pci_dev *dev, pm_message_t state)
805
{
806
struct jmb38x_ms *jm = pci_get_drvdata(dev);
807
int cnt;
808
809
for (cnt = 0; cnt < jm->host_cnt; ++cnt) {
810
if (!jm->hosts[cnt])
811
break;
812
memstick_suspend_host(jm->hosts[cnt]);
813
}
814
815
pci_save_state(dev);
816
pci_enable_wake(dev, pci_choose_state(dev, state), 0);
817
pci_disable_device(dev);
818
pci_set_power_state(dev, pci_choose_state(dev, state));
819
return 0;
820
}
821
822
static int jmb38x_ms_resume(struct pci_dev *dev)
823
{
824
struct jmb38x_ms *jm = pci_get_drvdata(dev);
825
int rc;
826
827
pci_set_power_state(dev, PCI_D0);
828
pci_restore_state(dev);
829
rc = pci_enable_device(dev);
830
if (rc)
831
return rc;
832
pci_set_master(dev);
833
834
jmb38x_ms_pmos(dev, 1);
835
836
for (rc = 0; rc < jm->host_cnt; ++rc) {
837
if (!jm->hosts[rc])
838
break;
839
memstick_resume_host(jm->hosts[rc]);
840
memstick_detect_change(jm->hosts[rc]);
841
}
842
843
return 0;
844
}
845
846
#else
847
848
#define jmb38x_ms_suspend NULL
849
#define jmb38x_ms_resume NULL
850
851
#endif /* CONFIG_PM */
852
853
static int jmb38x_ms_count_slots(struct pci_dev *pdev)
854
{
855
int cnt, rc = 0;
856
857
for (cnt = 0; cnt < PCI_ROM_RESOURCE; ++cnt) {
858
if (!(IORESOURCE_MEM & pci_resource_flags(pdev, cnt)))
859
break;
860
861
if (256 != pci_resource_len(pdev, cnt))
862
break;
863
864
++rc;
865
}
866
return rc;
867
}
868
869
static struct memstick_host *jmb38x_ms_alloc_host(struct jmb38x_ms *jm, int cnt)
870
{
871
struct memstick_host *msh;
872
struct jmb38x_ms_host *host;
873
874
msh = memstick_alloc_host(sizeof(struct jmb38x_ms_host),
875
&jm->pdev->dev);
876
if (!msh)
877
return NULL;
878
879
host = memstick_priv(msh);
880
host->chip = jm;
881
host->addr = ioremap(pci_resource_start(jm->pdev, cnt),
882
pci_resource_len(jm->pdev, cnt));
883
if (!host->addr)
884
goto err_out_free;
885
886
spin_lock_init(&host->lock);
887
host->id = cnt;
888
snprintf(host->host_id, sizeof(host->host_id), DRIVER_NAME ":slot%d",
889
host->id);
890
host->irq = jm->pdev->irq;
891
host->timeout_jiffies = msecs_to_jiffies(1000);
892
893
tasklet_init(&host->notify, jmb38x_ms_req_tasklet, (unsigned long)msh);
894
msh->request = jmb38x_ms_submit_req;
895
msh->set_param = jmb38x_ms_set_param;
896
897
msh->caps = MEMSTICK_CAP_PAR4 | MEMSTICK_CAP_PAR8;
898
899
setup_timer(&host->timer, jmb38x_ms_abort, (unsigned long)msh);
900
901
if (!request_irq(host->irq, jmb38x_ms_isr, IRQF_SHARED, host->host_id,
902
msh))
903
return msh;
904
905
iounmap(host->addr);
906
err_out_free:
907
kfree(msh);
908
return NULL;
909
}
910
911
static void jmb38x_ms_free_host(struct memstick_host *msh)
912
{
913
struct jmb38x_ms_host *host = memstick_priv(msh);
914
915
free_irq(host->irq, msh);
916
iounmap(host->addr);
917
memstick_free_host(msh);
918
}
919
920
static int jmb38x_ms_probe(struct pci_dev *pdev,
921
const struct pci_device_id *dev_id)
922
{
923
struct jmb38x_ms *jm;
924
int pci_dev_busy = 0;
925
int rc, cnt;
926
927
rc = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
928
if (rc)
929
return rc;
930
931
rc = pci_enable_device(pdev);
932
if (rc)
933
return rc;
934
935
pci_set_master(pdev);
936
937
rc = pci_request_regions(pdev, DRIVER_NAME);
938
if (rc) {
939
pci_dev_busy = 1;
940
goto err_out;
941
}
942
943
jmb38x_ms_pmos(pdev, 1);
944
945
cnt = jmb38x_ms_count_slots(pdev);
946
if (!cnt) {
947
rc = -ENODEV;
948
pci_dev_busy = 1;
949
goto err_out;
950
}
951
952
jm = kzalloc(sizeof(struct jmb38x_ms)
953
+ cnt * sizeof(struct memstick_host *), GFP_KERNEL);
954
if (!jm) {
955
rc = -ENOMEM;
956
goto err_out_int;
957
}
958
959
jm->pdev = pdev;
960
jm->host_cnt = cnt;
961
pci_set_drvdata(pdev, jm);
962
963
for (cnt = 0; cnt < jm->host_cnt; ++cnt) {
964
jm->hosts[cnt] = jmb38x_ms_alloc_host(jm, cnt);
965
if (!jm->hosts[cnt])
966
break;
967
968
rc = memstick_add_host(jm->hosts[cnt]);
969
970
if (rc) {
971
jmb38x_ms_free_host(jm->hosts[cnt]);
972
jm->hosts[cnt] = NULL;
973
break;
974
}
975
}
976
977
if (cnt)
978
return 0;
979
980
rc = -ENODEV;
981
982
pci_set_drvdata(pdev, NULL);
983
kfree(jm);
984
err_out_int:
985
pci_release_regions(pdev);
986
err_out:
987
if (!pci_dev_busy)
988
pci_disable_device(pdev);
989
return rc;
990
}
991
992
static void jmb38x_ms_remove(struct pci_dev *dev)
993
{
994
struct jmb38x_ms *jm = pci_get_drvdata(dev);
995
struct jmb38x_ms_host *host;
996
int cnt;
997
unsigned long flags;
998
999
for (cnt = 0; cnt < jm->host_cnt; ++cnt) {
1000
if (!jm->hosts[cnt])
1001
break;
1002
1003
host = memstick_priv(jm->hosts[cnt]);
1004
1005
jm->hosts[cnt]->request = jmb38x_ms_dummy_submit;
1006
tasklet_kill(&host->notify);
1007
writel(0, host->addr + INT_SIGNAL_ENABLE);
1008
writel(0, host->addr + INT_STATUS_ENABLE);
1009
mmiowb();
1010
dev_dbg(&jm->pdev->dev, "interrupts off\n");
1011
spin_lock_irqsave(&host->lock, flags);
1012
if (host->req) {
1013
host->req->error = -ETIME;
1014
jmb38x_ms_complete_cmd(jm->hosts[cnt], 1);
1015
}
1016
spin_unlock_irqrestore(&host->lock, flags);
1017
1018
memstick_remove_host(jm->hosts[cnt]);
1019
dev_dbg(&jm->pdev->dev, "host removed\n");
1020
1021
jmb38x_ms_free_host(jm->hosts[cnt]);
1022
}
1023
1024
jmb38x_ms_pmos(dev, 0);
1025
1026
pci_set_drvdata(dev, NULL);
1027
pci_release_regions(dev);
1028
pci_disable_device(dev);
1029
kfree(jm);
1030
}
1031
1032
static struct pci_device_id jmb38x_ms_id_tbl [] = {
1033
{ PCI_VDEVICE(JMICRON, PCI_DEVICE_ID_JMICRON_JMB38X_MS) },
1034
{ PCI_VDEVICE(JMICRON, PCI_DEVICE_ID_JMICRON_JMB385_MS) },
1035
{ PCI_VDEVICE(JMICRON, PCI_DEVICE_ID_JMICRON_JMB390_MS) },
1036
{ }
1037
};
1038
1039
static struct pci_driver jmb38x_ms_driver = {
1040
.name = DRIVER_NAME,
1041
.id_table = jmb38x_ms_id_tbl,
1042
.probe = jmb38x_ms_probe,
1043
.remove = jmb38x_ms_remove,
1044
.suspend = jmb38x_ms_suspend,
1045
.resume = jmb38x_ms_resume
1046
};
1047
1048
static int __init jmb38x_ms_init(void)
1049
{
1050
return pci_register_driver(&jmb38x_ms_driver);
1051
}
1052
1053
static void __exit jmb38x_ms_exit(void)
1054
{
1055
pci_unregister_driver(&jmb38x_ms_driver);
1056
}
1057
1058
MODULE_AUTHOR("Alex Dubov");
1059
MODULE_DESCRIPTION("JMicron jmb38x MemoryStick driver");
1060
MODULE_LICENSE("GPL");
1061
MODULE_DEVICE_TABLE(pci, jmb38x_ms_id_tbl);
1062
1063
module_init(jmb38x_ms_init);
1064
module_exit(jmb38x_ms_exit);
1065
1066