~ubuntu-branches/ubuntu/precise/linux-lowlatency/precise

« back to all changes in this revision

Viewing changes to drivers/memstick/host/tifm_ms.c

  • Committer: Package Import Robot
  • Author(s): Alessio Igor Bogani
  • Date: 2011-10-26 11:13:05 UTC
  • Revision ID: package-import@ubuntu.com-20111026111305-tz023xykf0i6eosh
Tags: upstream-3.2.0
ImportĀ upstreamĀ versionĀ 3.2.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 *  TI FlashMedia driver
 
3
 *
 
4
 *  Copyright (C) 2007 Alex Dubov <oakad@yahoo.com>
 
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
 * Special thanks to Carlos Corbacho for providing various MemoryStick cards
 
11
 * that made this driver possible.
 
12
 *
 
13
 */
 
14
 
 
15
#include <linux/tifm.h>
 
16
#include <linux/memstick.h>
 
17
#include <linux/highmem.h>
 
18
#include <linux/scatterlist.h>
 
19
#include <linux/log2.h>
 
20
#include <linux/module.h>
 
21
#include <asm/io.h>
 
22
 
 
23
#define DRIVER_NAME "tifm_ms"
 
24
 
 
25
static int no_dma;
 
26
module_param(no_dma, bool, 0644);
 
27
 
 
28
/*
 
29
 * Some control bits of TIFM appear to conform to Sony's reference design,
 
30
 * so I'm just assuming they all are.
 
31
 */
 
32
 
 
33
#define TIFM_MS_STAT_DRQ     0x04000
 
34
#define TIFM_MS_STAT_MSINT   0x02000
 
35
#define TIFM_MS_STAT_RDY     0x01000
 
36
#define TIFM_MS_STAT_CRC     0x00200
 
37
#define TIFM_MS_STAT_TOE     0x00100
 
38
#define TIFM_MS_STAT_EMP     0x00020
 
39
#define TIFM_MS_STAT_FUL     0x00010
 
40
#define TIFM_MS_STAT_CED     0x00008
 
41
#define TIFM_MS_STAT_ERR     0x00004
 
42
#define TIFM_MS_STAT_BRQ     0x00002
 
43
#define TIFM_MS_STAT_CNK     0x00001
 
44
 
 
45
#define TIFM_MS_SYS_DMA      0x10000
 
46
#define TIFM_MS_SYS_RESET    0x08000
 
47
#define TIFM_MS_SYS_SRAC     0x04000
 
48
#define TIFM_MS_SYS_INTEN    0x02000
 
49
#define TIFM_MS_SYS_NOCRC    0x01000
 
50
#define TIFM_MS_SYS_INTCLR   0x00800
 
51
#define TIFM_MS_SYS_MSIEN    0x00400
 
52
#define TIFM_MS_SYS_FCLR     0x00200
 
53
#define TIFM_MS_SYS_FDIR     0x00100
 
54
#define TIFM_MS_SYS_DAM      0x00080
 
55
#define TIFM_MS_SYS_DRM      0x00040
 
56
#define TIFM_MS_SYS_DRQSL    0x00020
 
57
#define TIFM_MS_SYS_REI      0x00010
 
58
#define TIFM_MS_SYS_REO      0x00008
 
59
#define TIFM_MS_SYS_BSY_MASK 0x00007
 
60
 
 
61
#define TIFM_MS_SYS_FIFO     (TIFM_MS_SYS_INTEN | TIFM_MS_SYS_MSIEN \
 
62
                              | TIFM_MS_SYS_FCLR | TIFM_MS_SYS_BSY_MASK)
 
63
 
 
64
/* Hardware flags */
 
65
enum {
 
66
        CMD_READY  = 0x01,
 
67
        FIFO_READY = 0x02,
 
68
        CARD_INT   = 0x04
 
69
};
 
70
 
 
71
struct tifm_ms {
 
72
        struct tifm_dev         *dev;
 
73
        struct timer_list       timer;
 
74
        struct memstick_request *req;
 
75
        struct tasklet_struct   notify;
 
76
        unsigned int            mode_mask;
 
77
        unsigned int            block_pos;
 
78
        unsigned long           timeout_jiffies;
 
79
        unsigned char           eject:1,
 
80
                                use_dma:1;
 
81
        unsigned char           cmd_flags;
 
82
        unsigned char           io_pos;
 
83
        unsigned int            io_word;
 
84
};
 
85
 
 
86
static unsigned int tifm_ms_read_data(struct tifm_ms *host,
 
87
                                      unsigned char *buf, unsigned int length)
 
88
{
 
89
        struct tifm_dev *sock = host->dev;
 
90
        unsigned int off = 0;
 
91
 
 
92
        while (host->io_pos && length) {
 
93
                buf[off++] = host->io_word & 0xff;
 
94
                host->io_word >>= 8;
 
95
                length--;
 
96
                host->io_pos--;
 
97
        }
 
98
 
 
99
        if (!length)
 
100
                return off;
 
101
 
 
102
        while (!(TIFM_MS_STAT_EMP & readl(sock->addr + SOCK_MS_STATUS))) {
 
103
                if (length < 4)
 
104
                        break;
 
105
                *(unsigned int *)(buf + off) = __raw_readl(sock->addr
 
106
                                                           + SOCK_MS_DATA);
 
107
                length -= 4;
 
108
                off += 4;
 
109
        }
 
110
 
 
111
        if (length
 
112
            && !(TIFM_MS_STAT_EMP & readl(sock->addr + SOCK_MS_STATUS))) {
 
113
                host->io_word = readl(sock->addr + SOCK_MS_DATA);
 
114
                for (host->io_pos = 4; host->io_pos; --host->io_pos) {
 
115
                        buf[off++] = host->io_word & 0xff;
 
116
                        host->io_word >>= 8;
 
117
                        length--;
 
118
                        if (!length)
 
119
                                break;
 
120
                }
 
121
        }
 
122
 
 
123
        return off;
 
124
}
 
125
 
 
126
static unsigned int tifm_ms_write_data(struct tifm_ms *host,
 
127
                                       unsigned char *buf, unsigned int length)
 
128
{
 
129
        struct tifm_dev *sock = host->dev;
 
130
        unsigned int off = 0;
 
131
 
 
132
        if (host->io_pos) {
 
133
                while (host->io_pos < 4 && length) {
 
134
                        host->io_word |=  buf[off++] << (host->io_pos * 8);
 
135
                        host->io_pos++;
 
136
                        length--;
 
137
                }
 
138
        }
 
139
 
 
140
        if (host->io_pos == 4
 
141
            && !(TIFM_MS_STAT_FUL & readl(sock->addr + SOCK_MS_STATUS))) {
 
142
                writel(TIFM_MS_SYS_FDIR | readl(sock->addr + SOCK_MS_SYSTEM),
 
143
                       sock->addr + SOCK_MS_SYSTEM);
 
144
                writel(host->io_word, sock->addr + SOCK_MS_DATA);
 
145
                host->io_pos = 0;
 
146
                host->io_word = 0;
 
147
        } else if (host->io_pos) {
 
148
                return off;
 
149
        }
 
150
 
 
151
        if (!length)
 
152
                return off;
 
153
 
 
154
        while (!(TIFM_MS_STAT_FUL & readl(sock->addr + SOCK_MS_STATUS))) {
 
155
                if (length < 4)
 
156
                        break;
 
157
                writel(TIFM_MS_SYS_FDIR | readl(sock->addr + SOCK_MS_SYSTEM),
 
158
                       sock->addr + SOCK_MS_SYSTEM);
 
159
                __raw_writel(*(unsigned int *)(buf + off),
 
160
                             sock->addr + SOCK_MS_DATA);
 
161
                length -= 4;
 
162
                off += 4;
 
163
        }
 
164
 
 
165
        switch (length) {
 
166
        case 3:
 
167
                host->io_word |= buf[off + 2] << 16;
 
168
                host->io_pos++;
 
169
        case 2:
 
170
                host->io_word |= buf[off + 1] << 8;
 
171
                host->io_pos++;
 
172
        case 1:
 
173
                host->io_word |= buf[off];
 
174
                host->io_pos++;
 
175
        }
 
176
 
 
177
        off += host->io_pos;
 
178
 
 
179
        return off;
 
180
}
 
181
 
 
182
static unsigned int tifm_ms_transfer_data(struct tifm_ms *host)
 
183
{
 
184
        struct tifm_dev *sock = host->dev;
 
185
        unsigned int length;
 
186
        unsigned int off;
 
187
        unsigned int t_size, p_cnt;
 
188
        unsigned char *buf;
 
189
        struct page *pg;
 
190
        unsigned long flags = 0;
 
191
 
 
192
        if (host->req->long_data) {
 
193
                length = host->req->sg.length - host->block_pos;
 
194
                off = host->req->sg.offset + host->block_pos;
 
195
        } else {
 
196
                length = host->req->data_len - host->block_pos;
 
197
                off = 0;
 
198
        }
 
199
        dev_dbg(&sock->dev, "fifo data transfer, %d, %d\n", length,
 
200
                host->block_pos);
 
201
 
 
202
        while (length) {
 
203
                unsigned int uninitialized_var(p_off);
 
204
 
 
205
                if (host->req->long_data) {
 
206
                        pg = nth_page(sg_page(&host->req->sg),
 
207
                                      off >> PAGE_SHIFT);
 
208
                        p_off = offset_in_page(off);
 
209
                        p_cnt = PAGE_SIZE - p_off;
 
210
                        p_cnt = min(p_cnt, length);
 
211
 
 
212
                        local_irq_save(flags);
 
213
                        buf = kmap_atomic(pg, KM_BIO_SRC_IRQ) + p_off;
 
214
                } else {
 
215
                        buf = host->req->data + host->block_pos;
 
216
                        p_cnt = host->req->data_len - host->block_pos;
 
217
                }
 
218
 
 
219
                t_size = host->req->data_dir == WRITE
 
220
                         ? tifm_ms_write_data(host, buf, p_cnt)
 
221
                         : tifm_ms_read_data(host, buf, p_cnt);
 
222
 
 
223
                if (host->req->long_data) {
 
224
                        kunmap_atomic(buf - p_off, KM_BIO_SRC_IRQ);
 
225
                        local_irq_restore(flags);
 
226
                }
 
227
 
 
228
                if (!t_size)
 
229
                        break;
 
230
                host->block_pos += t_size;
 
231
                length -= t_size;
 
232
                off += t_size;
 
233
        }
 
234
 
 
235
        dev_dbg(&sock->dev, "fifo data transfer, %d remaining\n", length);
 
236
        if (!length && (host->req->data_dir == WRITE)) {
 
237
                if (host->io_pos) {
 
238
                        writel(TIFM_MS_SYS_FDIR
 
239
                               | readl(sock->addr + SOCK_MS_SYSTEM),
 
240
                               sock->addr + SOCK_MS_SYSTEM);
 
241
                        writel(host->io_word, sock->addr + SOCK_MS_DATA);
 
242
                }
 
243
                writel(TIFM_MS_SYS_FDIR
 
244
                       | readl(sock->addr + SOCK_MS_SYSTEM),
 
245
                       sock->addr + SOCK_MS_SYSTEM);
 
246
                writel(0, sock->addr + SOCK_MS_DATA);
 
247
        } else {
 
248
                readl(sock->addr + SOCK_MS_DATA);
 
249
        }
 
250
 
 
251
        return length;
 
252
}
 
253
 
 
254
static int tifm_ms_issue_cmd(struct tifm_ms *host)
 
255
{
 
256
        struct tifm_dev *sock = host->dev;
 
257
        unsigned char *data;
 
258
        unsigned int data_len, cmd, sys_param;
 
259
 
 
260
        host->cmd_flags = 0;
 
261
        host->block_pos = 0;
 
262
        host->io_pos = 0;
 
263
        host->io_word = 0;
 
264
        host->cmd_flags = 0;
 
265
 
 
266
        data = host->req->data;
 
267
 
 
268
        host->use_dma = !no_dma;
 
269
 
 
270
        if (host->req->long_data) {
 
271
                data_len = host->req->sg.length;
 
272
                if (!is_power_of_2(data_len))
 
273
                        host->use_dma = 0;
 
274
        } else {
 
275
                data_len = host->req->data_len;
 
276
                host->use_dma = 0;
 
277
        }
 
278
 
 
279
        writel(TIFM_FIFO_INT_SETALL,
 
280
               sock->addr + SOCK_DMA_FIFO_INT_ENABLE_CLEAR);
 
281
        writel(TIFM_FIFO_ENABLE,
 
282
               sock->addr + SOCK_FIFO_CONTROL);
 
283
 
 
284
        if (host->use_dma) {
 
285
                if (1 != tifm_map_sg(sock, &host->req->sg, 1,
 
286
                                     host->req->data_dir == READ
 
287
                                     ? PCI_DMA_FROMDEVICE
 
288
                                     : PCI_DMA_TODEVICE)) {
 
289
                        host->req->error = -ENOMEM;
 
290
                        return host->req->error;
 
291
                }
 
292
                data_len = sg_dma_len(&host->req->sg);
 
293
 
 
294
                writel(ilog2(data_len) - 2,
 
295
                       sock->addr + SOCK_FIFO_PAGE_SIZE);
 
296
                writel(TIFM_FIFO_INTMASK,
 
297
                       sock->addr + SOCK_DMA_FIFO_INT_ENABLE_SET);
 
298
                sys_param = TIFM_DMA_EN | (1 << 8);
 
299
                if (host->req->data_dir == WRITE)
 
300
                        sys_param |= TIFM_DMA_TX;
 
301
 
 
302
                writel(TIFM_FIFO_INTMASK,
 
303
                       sock->addr + SOCK_DMA_FIFO_INT_ENABLE_SET);
 
304
 
 
305
                writel(sg_dma_address(&host->req->sg),
 
306
                       sock->addr + SOCK_DMA_ADDRESS);
 
307
                writel(sys_param, sock->addr + SOCK_DMA_CONTROL);
 
308
        } else {
 
309
                writel(host->mode_mask | TIFM_MS_SYS_FIFO,
 
310
                       sock->addr + SOCK_MS_SYSTEM);
 
311
 
 
312
                writel(TIFM_FIFO_MORE,
 
313
                       sock->addr + SOCK_DMA_FIFO_INT_ENABLE_SET);
 
314
        }
 
315
 
 
316
        mod_timer(&host->timer, jiffies + host->timeout_jiffies);
 
317
        writel(TIFM_CTRL_LED | readl(sock->addr + SOCK_CONTROL),
 
318
               sock->addr + SOCK_CONTROL);
 
319
        host->req->error = 0;
 
320
 
 
321
        sys_param = readl(sock->addr + SOCK_MS_SYSTEM);
 
322
        sys_param |= TIFM_MS_SYS_INTCLR;
 
323
 
 
324
        if (host->use_dma)
 
325
                sys_param |= TIFM_MS_SYS_DMA;
 
326
        else
 
327
                sys_param &= ~TIFM_MS_SYS_DMA;
 
328
 
 
329
        writel(sys_param, sock->addr + SOCK_MS_SYSTEM);
 
330
 
 
331
        cmd = (host->req->tpc & 0xf) << 12;
 
332
        cmd |= data_len;
 
333
        writel(cmd, sock->addr + SOCK_MS_COMMAND);
 
334
 
 
335
        dev_dbg(&sock->dev, "executing TPC %x, %x\n", cmd, sys_param);
 
336
        return 0;
 
337
}
 
338
 
 
339
static void tifm_ms_complete_cmd(struct tifm_ms *host)
 
340
{
 
341
        struct tifm_dev *sock = host->dev;
 
342
        struct memstick_host *msh = tifm_get_drvdata(sock);
 
343
        int rc;
 
344
 
 
345
        del_timer(&host->timer);
 
346
 
 
347
        host->req->int_reg = readl(sock->addr + SOCK_MS_STATUS) & 0xff;
 
348
        host->req->int_reg = (host->req->int_reg & 1)
 
349
                             | ((host->req->int_reg << 4) & 0xe0);
 
350
 
 
351
        writel(TIFM_FIFO_INT_SETALL,
 
352
               sock->addr + SOCK_DMA_FIFO_INT_ENABLE_CLEAR);
 
353
        writel(TIFM_DMA_RESET, sock->addr + SOCK_DMA_CONTROL);
 
354
 
 
355
        if (host->use_dma) {
 
356
                tifm_unmap_sg(sock, &host->req->sg, 1,
 
357
                              host->req->data_dir == READ
 
358
                              ? PCI_DMA_FROMDEVICE
 
359
                              : PCI_DMA_TODEVICE);
 
360
        }
 
361
 
 
362
        writel((~TIFM_CTRL_LED) & readl(sock->addr + SOCK_CONTROL),
 
363
               sock->addr + SOCK_CONTROL);
 
364
 
 
365
        dev_dbg(&sock->dev, "TPC complete\n");
 
366
        do {
 
367
                rc = memstick_next_req(msh, &host->req);
 
368
        } while (!rc && tifm_ms_issue_cmd(host));
 
369
}
 
370
 
 
371
static int tifm_ms_check_status(struct tifm_ms *host)
 
372
{
 
373
        if (!host->req->error) {
 
374
                if (!(host->cmd_flags & CMD_READY))
 
375
                        return 1;
 
376
                if (!(host->cmd_flags & FIFO_READY))
 
377
                        return 1;
 
378
                if (host->req->need_card_int
 
379
                    && !(host->cmd_flags & CARD_INT))
 
380
                        return 1;
 
381
        }
 
382
        return 0;
 
383
}
 
384
 
 
385
/* Called from interrupt handler */
 
386
static void tifm_ms_data_event(struct tifm_dev *sock)
 
387
{
 
388
        struct tifm_ms *host;
 
389
        unsigned int fifo_status = 0, host_status = 0;
 
390
        int rc = 1;
 
391
 
 
392
        spin_lock(&sock->lock);
 
393
        host = memstick_priv((struct memstick_host *)tifm_get_drvdata(sock));
 
394
        fifo_status = readl(sock->addr + SOCK_DMA_FIFO_STATUS);
 
395
        host_status = readl(sock->addr + SOCK_MS_STATUS);
 
396
        dev_dbg(&sock->dev,
 
397
                "data event: fifo_status %x, host_status %x, flags %x\n",
 
398
                fifo_status, host_status, host->cmd_flags);
 
399
 
 
400
        if (host->req) {
 
401
                if (host->use_dma && (fifo_status & 1)) {
 
402
                        host->cmd_flags |= FIFO_READY;
 
403
                        rc = tifm_ms_check_status(host);
 
404
                }
 
405
                if (!host->use_dma && (fifo_status & TIFM_FIFO_MORE)) {
 
406
                        if (!tifm_ms_transfer_data(host)) {
 
407
                                host->cmd_flags |= FIFO_READY;
 
408
                                rc = tifm_ms_check_status(host);
 
409
                        }
 
410
                }
 
411
        }
 
412
 
 
413
        writel(fifo_status, sock->addr + SOCK_DMA_FIFO_STATUS);
 
414
        if (!rc)
 
415
                tifm_ms_complete_cmd(host);
 
416
 
 
417
        spin_unlock(&sock->lock);
 
418
}
 
419
 
 
420
 
 
421
/* Called from interrupt handler */
 
422
static void tifm_ms_card_event(struct tifm_dev *sock)
 
423
{
 
424
        struct tifm_ms *host;
 
425
        unsigned int host_status = 0;
 
426
        int rc = 1;
 
427
 
 
428
        spin_lock(&sock->lock);
 
429
        host = memstick_priv((struct memstick_host *)tifm_get_drvdata(sock));
 
430
        host_status = readl(sock->addr + SOCK_MS_STATUS);
 
431
        dev_dbg(&sock->dev, "host event: host_status %x, flags %x\n",
 
432
                host_status, host->cmd_flags);
 
433
 
 
434
        if (host->req) {
 
435
                if (host_status & TIFM_MS_STAT_TOE)
 
436
                        host->req->error = -ETIME;
 
437
                else if (host_status & TIFM_MS_STAT_CRC)
 
438
                        host->req->error = -EILSEQ;
 
439
 
 
440
                if (host_status & TIFM_MS_STAT_RDY)
 
441
                        host->cmd_flags |= CMD_READY;
 
442
 
 
443
                if (host_status & TIFM_MS_STAT_MSINT)
 
444
                        host->cmd_flags |= CARD_INT;
 
445
 
 
446
                rc = tifm_ms_check_status(host);
 
447
 
 
448
        }
 
449
 
 
450
        writel(TIFM_MS_SYS_INTCLR | readl(sock->addr + SOCK_MS_SYSTEM),
 
451
               sock->addr + SOCK_MS_SYSTEM);
 
452
 
 
453
        if (!rc)
 
454
                tifm_ms_complete_cmd(host);
 
455
 
 
456
        spin_unlock(&sock->lock);
 
457
        return;
 
458
}
 
459
 
 
460
static void tifm_ms_req_tasklet(unsigned long data)
 
461
{
 
462
        struct memstick_host *msh = (struct memstick_host *)data;
 
463
        struct tifm_ms *host = memstick_priv(msh);
 
464
        struct tifm_dev *sock = host->dev;
 
465
        unsigned long flags;
 
466
        int rc;
 
467
 
 
468
        spin_lock_irqsave(&sock->lock, flags);
 
469
        if (!host->req) {
 
470
                if (host->eject) {
 
471
                        do {
 
472
                                rc = memstick_next_req(msh, &host->req);
 
473
                                if (!rc)
 
474
                                        host->req->error = -ETIME;
 
475
                        } while (!rc);
 
476
                        spin_unlock_irqrestore(&sock->lock, flags);
 
477
                        return;
 
478
                }
 
479
 
 
480
                do {
 
481
                        rc = memstick_next_req(msh, &host->req);
 
482
                } while (!rc && tifm_ms_issue_cmd(host));
 
483
        }
 
484
        spin_unlock_irqrestore(&sock->lock, flags);
 
485
}
 
486
 
 
487
static void tifm_ms_dummy_submit(struct memstick_host *msh)
 
488
{
 
489
        return;
 
490
}
 
491
 
 
492
static void tifm_ms_submit_req(struct memstick_host *msh)
 
493
{
 
494
        struct tifm_ms *host = memstick_priv(msh);
 
495
 
 
496
        tasklet_schedule(&host->notify);
 
497
}
 
498
 
 
499
static int tifm_ms_set_param(struct memstick_host *msh,
 
500
                             enum memstick_param param,
 
501
                             int value)
 
502
{
 
503
        struct tifm_ms *host = memstick_priv(msh);
 
504
        struct tifm_dev *sock = host->dev;
 
505
 
 
506
        switch (param) {
 
507
        case MEMSTICK_POWER:
 
508
                /* also affected by media detection mechanism */
 
509
                if (value == MEMSTICK_POWER_ON) {
 
510
                        host->mode_mask = TIFM_MS_SYS_SRAC | TIFM_MS_SYS_REI;
 
511
                        writel(TIFM_MS_SYS_RESET, sock->addr + SOCK_MS_SYSTEM);
 
512
                        writel(TIFM_MS_SYS_FCLR | TIFM_MS_SYS_INTCLR,
 
513
                               sock->addr + SOCK_MS_SYSTEM);
 
514
                        writel(0xffffffff, sock->addr + SOCK_MS_STATUS);
 
515
                } else if (value == MEMSTICK_POWER_OFF) {
 
516
                        writel(TIFM_MS_SYS_FCLR | TIFM_MS_SYS_INTCLR,
 
517
                               sock->addr + SOCK_MS_SYSTEM);
 
518
                        writel(0xffffffff, sock->addr + SOCK_MS_STATUS);
 
519
                } else
 
520
                        return -EINVAL;
 
521
                break;
 
522
        case MEMSTICK_INTERFACE:
 
523
                if (value == MEMSTICK_SERIAL) {
 
524
                        host->mode_mask = TIFM_MS_SYS_SRAC | TIFM_MS_SYS_REI;
 
525
                        writel((~TIFM_CTRL_FAST_CLK)
 
526
                               & readl(sock->addr + SOCK_CONTROL),
 
527
                               sock->addr + SOCK_CONTROL);
 
528
                } else if (value == MEMSTICK_PAR4) {
 
529
                        host->mode_mask = 0;
 
530
                        writel(TIFM_CTRL_FAST_CLK
 
531
                               | readl(sock->addr + SOCK_CONTROL),
 
532
                               sock->addr + SOCK_CONTROL);
 
533
                } else
 
534
                        return -EINVAL;
 
535
                break;
 
536
        };
 
537
 
 
538
        return 0;
 
539
}
 
540
 
 
541
static void tifm_ms_abort(unsigned long data)
 
542
{
 
543
        struct tifm_ms *host = (struct tifm_ms *)data;
 
544
 
 
545
        dev_dbg(&host->dev->dev, "status %x\n",
 
546
                readl(host->dev->addr + SOCK_MS_STATUS));
 
547
        printk(KERN_ERR
 
548
               "%s : card failed to respond for a long period of time "
 
549
               "(%x, %x)\n",
 
550
               dev_name(&host->dev->dev), host->req ? host->req->tpc : 0,
 
551
               host->cmd_flags);
 
552
 
 
553
        tifm_eject(host->dev);
 
554
}
 
555
 
 
556
static int tifm_ms_probe(struct tifm_dev *sock)
 
557
{
 
558
        struct memstick_host *msh;
 
559
        struct tifm_ms *host;
 
560
        int rc = -EIO;
 
561
 
 
562
        if (!(TIFM_SOCK_STATE_OCCUPIED
 
563
              & readl(sock->addr + SOCK_PRESENT_STATE))) {
 
564
                printk(KERN_WARNING "%s : card gone, unexpectedly\n",
 
565
                       dev_name(&sock->dev));
 
566
                return rc;
 
567
        }
 
568
 
 
569
        msh = memstick_alloc_host(sizeof(struct tifm_ms), &sock->dev);
 
570
        if (!msh)
 
571
                return -ENOMEM;
 
572
 
 
573
        host = memstick_priv(msh);
 
574
        tifm_set_drvdata(sock, msh);
 
575
        host->dev = sock;
 
576
        host->timeout_jiffies = msecs_to_jiffies(1000);
 
577
 
 
578
        setup_timer(&host->timer, tifm_ms_abort, (unsigned long)host);
 
579
        tasklet_init(&host->notify, tifm_ms_req_tasklet, (unsigned long)msh);
 
580
 
 
581
        msh->request = tifm_ms_submit_req;
 
582
        msh->set_param = tifm_ms_set_param;
 
583
        sock->card_event = tifm_ms_card_event;
 
584
        sock->data_event = tifm_ms_data_event;
 
585
        if (tifm_has_ms_pif(sock))
 
586
                msh->caps |= MEMSTICK_CAP_PAR4;
 
587
 
 
588
        rc = memstick_add_host(msh);
 
589
        if (!rc)
 
590
                return 0;
 
591
 
 
592
        memstick_free_host(msh);
 
593
        return rc;
 
594
}
 
595
 
 
596
static void tifm_ms_remove(struct tifm_dev *sock)
 
597
{
 
598
        struct memstick_host *msh = tifm_get_drvdata(sock);
 
599
        struct tifm_ms *host = memstick_priv(msh);
 
600
        int rc = 0;
 
601
        unsigned long flags;
 
602
 
 
603
        msh->request = tifm_ms_dummy_submit;
 
604
        tasklet_kill(&host->notify);
 
605
        spin_lock_irqsave(&sock->lock, flags);
 
606
        host->eject = 1;
 
607
        if (host->req) {
 
608
                del_timer(&host->timer);
 
609
                writel(TIFM_FIFO_INT_SETALL,
 
610
                       sock->addr + SOCK_DMA_FIFO_INT_ENABLE_CLEAR);
 
611
                writel(TIFM_DMA_RESET, sock->addr + SOCK_DMA_CONTROL);
 
612
                if (host->use_dma)
 
613
                        tifm_unmap_sg(sock, &host->req->sg, 1,
 
614
                                      host->req->data_dir == READ
 
615
                                      ? PCI_DMA_TODEVICE
 
616
                                      : PCI_DMA_FROMDEVICE);
 
617
                host->req->error = -ETIME;
 
618
 
 
619
                do {
 
620
                        rc = memstick_next_req(msh, &host->req);
 
621
                        if (!rc)
 
622
                                host->req->error = -ETIME;
 
623
                } while (!rc);
 
624
        }
 
625
        spin_unlock_irqrestore(&sock->lock, flags);
 
626
 
 
627
        memstick_remove_host(msh);
 
628
        memstick_free_host(msh);
 
629
}
 
630
 
 
631
#ifdef CONFIG_PM
 
632
 
 
633
static int tifm_ms_suspend(struct tifm_dev *sock, pm_message_t state)
 
634
{
 
635
        struct memstick_host *msh = tifm_get_drvdata(sock);
 
636
 
 
637
        memstick_suspend_host(msh);
 
638
        return 0;
 
639
}
 
640
 
 
641
static int tifm_ms_resume(struct tifm_dev *sock)
 
642
{
 
643
        struct memstick_host *msh = tifm_get_drvdata(sock);
 
644
 
 
645
        memstick_resume_host(msh);
 
646
        return 0;
 
647
}
 
648
 
 
649
#else
 
650
 
 
651
#define tifm_ms_suspend NULL
 
652
#define tifm_ms_resume NULL
 
653
 
 
654
#endif /* CONFIG_PM */
 
655
 
 
656
static struct tifm_device_id tifm_ms_id_tbl[] = {
 
657
        { TIFM_TYPE_MS }, { 0 }
 
658
};
 
659
 
 
660
static struct tifm_driver tifm_ms_driver = {
 
661
        .driver = {
 
662
                .name  = DRIVER_NAME,
 
663
                .owner = THIS_MODULE
 
664
        },
 
665
        .id_table = tifm_ms_id_tbl,
 
666
        .probe    = tifm_ms_probe,
 
667
        .remove   = tifm_ms_remove,
 
668
        .suspend  = tifm_ms_suspend,
 
669
        .resume   = tifm_ms_resume
 
670
};
 
671
 
 
672
static int __init tifm_ms_init(void)
 
673
{
 
674
        return tifm_register_driver(&tifm_ms_driver);
 
675
}
 
676
 
 
677
static void __exit tifm_ms_exit(void)
 
678
{
 
679
        tifm_unregister_driver(&tifm_ms_driver);
 
680
}
 
681
 
 
682
MODULE_AUTHOR("Alex Dubov");
 
683
MODULE_DESCRIPTION("TI FlashMedia MemoryStick driver");
 
684
MODULE_LICENSE("GPL");
 
685
MODULE_DEVICE_TABLE(tifm, tifm_ms_id_tbl);
 
686
 
 
687
module_init(tifm_ms_init);
 
688
module_exit(tifm_ms_exit);