diff options
author | Andrea Bastoni <bastoni@cs.unc.edu> | 2010-05-30 19:16:45 -0400 |
---|---|---|
committer | Andrea Bastoni <bastoni@cs.unc.edu> | 2010-05-30 19:16:45 -0400 |
commit | ada47b5fe13d89735805b566185f4885f5a3f750 (patch) | |
tree | 644b88f8a71896307d71438e9b3af49126ffb22b /drivers/mmc | |
parent | 43e98717ad40a4ae64545b5ba047c7b86aa44f4f (diff) | |
parent | 3280f21d43ee541f97f8cda5792150d2dbec20d5 (diff) |
Merge branch 'wip-2.6.34' into old-private-masterarchived-private-master
Diffstat (limited to 'drivers/mmc')
48 files changed, 3782 insertions, 1130 deletions
diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c index 85f0e8cd875b..cb9fbc83b090 100644 --- a/drivers/mmc/card/block.c +++ b/drivers/mmc/card/block.c | |||
@@ -23,6 +23,7 @@ | |||
23 | 23 | ||
24 | #include <linux/kernel.h> | 24 | #include <linux/kernel.h> |
25 | #include <linux/fs.h> | 25 | #include <linux/fs.h> |
26 | #include <linux/slab.h> | ||
26 | #include <linux/errno.h> | 27 | #include <linux/errno.h> |
27 | #include <linux/hdreg.h> | 28 | #include <linux/hdreg.h> |
28 | #include <linux/kdev_t.h> | 29 | #include <linux/kdev_t.h> |
@@ -85,7 +86,14 @@ static void mmc_blk_put(struct mmc_blk_data *md) | |||
85 | mutex_lock(&open_lock); | 86 | mutex_lock(&open_lock); |
86 | md->usage--; | 87 | md->usage--; |
87 | if (md->usage == 0) { | 88 | if (md->usage == 0) { |
89 | int devmaj = MAJOR(disk_devt(md->disk)); | ||
88 | int devidx = MINOR(disk_devt(md->disk)) >> MMC_SHIFT; | 90 | int devidx = MINOR(disk_devt(md->disk)) >> MMC_SHIFT; |
91 | |||
92 | if (!devmaj) | ||
93 | devidx = md->disk->first_minor >> MMC_SHIFT; | ||
94 | |||
95 | blk_cleanup_queue(md->queue.queue); | ||
96 | |||
89 | __clear_bit(devidx, dev_use); | 97 | __clear_bit(devidx, dev_use); |
90 | 98 | ||
91 | put_disk(md->disk); | 99 | put_disk(md->disk); |
@@ -613,6 +621,7 @@ static int mmc_blk_probe(struct mmc_card *card) | |||
613 | return 0; | 621 | return 0; |
614 | 622 | ||
615 | out: | 623 | out: |
624 | mmc_cleanup_queue(&md->queue); | ||
616 | mmc_blk_put(md); | 625 | mmc_blk_put(md); |
617 | 626 | ||
618 | return err; | 627 | return err; |
diff --git a/drivers/mmc/card/mmc_test.c b/drivers/mmc/card/mmc_test.c index b9f1e84897cc..445d7db2277e 100644 --- a/drivers/mmc/card/mmc_test.c +++ b/drivers/mmc/card/mmc_test.c | |||
@@ -13,6 +13,7 @@ | |||
13 | #include <linux/mmc/card.h> | 13 | #include <linux/mmc/card.h> |
14 | #include <linux/mmc/host.h> | 14 | #include <linux/mmc/host.h> |
15 | #include <linux/mmc/mmc.h> | 15 | #include <linux/mmc/mmc.h> |
16 | #include <linux/slab.h> | ||
16 | 17 | ||
17 | #include <linux/scatterlist.h> | 18 | #include <linux/scatterlist.h> |
18 | 19 | ||
@@ -74,6 +75,9 @@ static void mmc_test_prepare_mrq(struct mmc_test_card *test, | |||
74 | } | 75 | } |
75 | 76 | ||
76 | mrq->cmd->arg = dev_addr; | 77 | mrq->cmd->arg = dev_addr; |
78 | if (!mmc_card_blockaddr(test->card)) | ||
79 | mrq->cmd->arg <<= 9; | ||
80 | |||
77 | mrq->cmd->flags = MMC_RSP_R1 | MMC_CMD_ADTC; | 81 | mrq->cmd->flags = MMC_RSP_R1 | MMC_CMD_ADTC; |
78 | 82 | ||
79 | if (blocks == 1) | 83 | if (blocks == 1) |
@@ -190,7 +194,7 @@ static int __mmc_test_prepare(struct mmc_test_card *test, int write) | |||
190 | } | 194 | } |
191 | 195 | ||
192 | for (i = 0;i < BUFFER_SIZE / 512;i++) { | 196 | for (i = 0;i < BUFFER_SIZE / 512;i++) { |
193 | ret = mmc_test_buffer_transfer(test, test->buffer, i * 512, 512, 1); | 197 | ret = mmc_test_buffer_transfer(test, test->buffer, i, 512, 1); |
194 | if (ret) | 198 | if (ret) |
195 | return ret; | 199 | return ret; |
196 | } | 200 | } |
@@ -219,7 +223,7 @@ static int mmc_test_cleanup(struct mmc_test_card *test) | |||
219 | memset(test->buffer, 0, 512); | 223 | memset(test->buffer, 0, 512); |
220 | 224 | ||
221 | for (i = 0;i < BUFFER_SIZE / 512;i++) { | 225 | for (i = 0;i < BUFFER_SIZE / 512;i++) { |
222 | ret = mmc_test_buffer_transfer(test, test->buffer, i * 512, 512, 1); | 226 | ret = mmc_test_buffer_transfer(test, test->buffer, i, 512, 1); |
223 | if (ret) | 227 | if (ret) |
224 | return ret; | 228 | return ret; |
225 | } | 229 | } |
@@ -426,7 +430,7 @@ static int mmc_test_transfer(struct mmc_test_card *test, | |||
426 | for (i = 0;i < sectors;i++) { | 430 | for (i = 0;i < sectors;i++) { |
427 | ret = mmc_test_buffer_transfer(test, | 431 | ret = mmc_test_buffer_transfer(test, |
428 | test->buffer + i * 512, | 432 | test->buffer + i * 512, |
429 | dev_addr + i * 512, 512, 0); | 433 | dev_addr + i, 512, 0); |
430 | if (ret) | 434 | if (ret) |
431 | return ret; | 435 | return ret; |
432 | } | 436 | } |
diff --git a/drivers/mmc/card/queue.c b/drivers/mmc/card/queue.c index 49e582356c65..d6ded247d941 100644 --- a/drivers/mmc/card/queue.c +++ b/drivers/mmc/card/queue.c | |||
@@ -9,6 +9,7 @@ | |||
9 | * published by the Free Software Foundation. | 9 | * published by the Free Software Foundation. |
10 | * | 10 | * |
11 | */ | 11 | */ |
12 | #include <linux/slab.h> | ||
12 | #include <linux/module.h> | 13 | #include <linux/module.h> |
13 | #include <linux/blkdev.h> | 14 | #include <linux/blkdev.h> |
14 | #include <linux/freezer.h> | 15 | #include <linux/freezer.h> |
@@ -90,9 +91,10 @@ static void mmc_request(struct request_queue *q) | |||
90 | struct request *req; | 91 | struct request *req; |
91 | 92 | ||
92 | if (!mq) { | 93 | if (!mq) { |
93 | printk(KERN_ERR "MMC: killing requests for dead queue\n"); | 94 | while ((req = blk_fetch_request(q)) != NULL) { |
94 | while ((req = blk_fetch_request(q)) != NULL) | 95 | req->cmd_flags |= REQ_QUIET; |
95 | __blk_end_request_all(req, -EIO); | 96 | __blk_end_request_all(req, -EIO); |
97 | } | ||
96 | return; | 98 | return; |
97 | } | 99 | } |
98 | 100 | ||
@@ -153,9 +155,8 @@ int mmc_init_queue(struct mmc_queue *mq, struct mmc_card *card, spinlock_t *lock | |||
153 | 155 | ||
154 | if (mq->bounce_buf) { | 156 | if (mq->bounce_buf) { |
155 | blk_queue_bounce_limit(mq->queue, BLK_BOUNCE_ANY); | 157 | blk_queue_bounce_limit(mq->queue, BLK_BOUNCE_ANY); |
156 | blk_queue_max_sectors(mq->queue, bouncesz / 512); | 158 | blk_queue_max_hw_sectors(mq->queue, bouncesz / 512); |
157 | blk_queue_max_phys_segments(mq->queue, bouncesz / 512); | 159 | blk_queue_max_segments(mq->queue, bouncesz / 512); |
158 | blk_queue_max_hw_segments(mq->queue, bouncesz / 512); | ||
159 | blk_queue_max_segment_size(mq->queue, bouncesz); | 160 | blk_queue_max_segment_size(mq->queue, bouncesz); |
160 | 161 | ||
161 | mq->sg = kmalloc(sizeof(struct scatterlist), | 162 | mq->sg = kmalloc(sizeof(struct scatterlist), |
@@ -179,10 +180,9 @@ int mmc_init_queue(struct mmc_queue *mq, struct mmc_card *card, spinlock_t *lock | |||
179 | 180 | ||
180 | if (!mq->bounce_buf) { | 181 | if (!mq->bounce_buf) { |
181 | blk_queue_bounce_limit(mq->queue, limit); | 182 | blk_queue_bounce_limit(mq->queue, limit); |
182 | blk_queue_max_sectors(mq->queue, | 183 | blk_queue_max_hw_sectors(mq->queue, |
183 | min(host->max_blk_count, host->max_req_size / 512)); | 184 | min(host->max_blk_count, host->max_req_size / 512)); |
184 | blk_queue_max_phys_segments(mq->queue, host->max_phys_segs); | 185 | blk_queue_max_segments(mq->queue, host->max_hw_segs); |
185 | blk_queue_max_hw_segments(mq->queue, host->max_hw_segs); | ||
186 | blk_queue_max_segment_size(mq->queue, host->max_seg_size); | 186 | blk_queue_max_segment_size(mq->queue, host->max_seg_size); |
187 | 187 | ||
188 | mq->sg = kmalloc(sizeof(struct scatterlist) * | 188 | mq->sg = kmalloc(sizeof(struct scatterlist) * |
@@ -223,17 +223,18 @@ void mmc_cleanup_queue(struct mmc_queue *mq) | |||
223 | struct request_queue *q = mq->queue; | 223 | struct request_queue *q = mq->queue; |
224 | unsigned long flags; | 224 | unsigned long flags; |
225 | 225 | ||
226 | /* Mark that we should start throwing out stragglers */ | ||
227 | spin_lock_irqsave(q->queue_lock, flags); | ||
228 | q->queuedata = NULL; | ||
229 | spin_unlock_irqrestore(q->queue_lock, flags); | ||
230 | |||
231 | /* Make sure the queue isn't suspended, as that will deadlock */ | 226 | /* Make sure the queue isn't suspended, as that will deadlock */ |
232 | mmc_queue_resume(mq); | 227 | mmc_queue_resume(mq); |
233 | 228 | ||
234 | /* Then terminate our worker thread */ | 229 | /* Then terminate our worker thread */ |
235 | kthread_stop(mq->thread); | 230 | kthread_stop(mq->thread); |
236 | 231 | ||
232 | /* Empty the queue */ | ||
233 | spin_lock_irqsave(q->queue_lock, flags); | ||
234 | q->queuedata = NULL; | ||
235 | blk_start_queue(q); | ||
236 | spin_unlock_irqrestore(q->queue_lock, flags); | ||
237 | |||
237 | if (mq->bounce_sg) | 238 | if (mq->bounce_sg) |
238 | kfree(mq->bounce_sg); | 239 | kfree(mq->bounce_sg); |
239 | mq->bounce_sg = NULL; | 240 | mq->bounce_sg = NULL; |
@@ -245,8 +246,6 @@ void mmc_cleanup_queue(struct mmc_queue *mq) | |||
245 | kfree(mq->bounce_buf); | 246 | kfree(mq->bounce_buf); |
246 | mq->bounce_buf = NULL; | 247 | mq->bounce_buf = NULL; |
247 | 248 | ||
248 | blk_cleanup_queue(mq->queue); | ||
249 | |||
250 | mq->card = NULL; | 249 | mq->card = NULL; |
251 | } | 250 | } |
252 | EXPORT_SYMBOL(mmc_cleanup_queue); | 251 | EXPORT_SYMBOL(mmc_cleanup_queue); |
diff --git a/drivers/mmc/card/sdio_uart.c b/drivers/mmc/card/sdio_uart.c index 36a8d53ad2a2..a0716967b7c8 100644 --- a/drivers/mmc/card/sdio_uart.c +++ b/drivers/mmc/card/sdio_uart.c | |||
@@ -29,13 +29,15 @@ | |||
29 | #include <linux/module.h> | 29 | #include <linux/module.h> |
30 | #include <linux/init.h> | 30 | #include <linux/init.h> |
31 | #include <linux/kernel.h> | 31 | #include <linux/kernel.h> |
32 | #include <linux/sched.h> | ||
32 | #include <linux/mutex.h> | 33 | #include <linux/mutex.h> |
33 | #include <linux/seq_file.h> | 34 | #include <linux/seq_file.h> |
34 | #include <linux/serial_reg.h> | 35 | #include <linux/serial_reg.h> |
35 | #include <linux/circ_buf.h> | 36 | #include <linux/circ_buf.h> |
36 | #include <linux/gfp.h> | ||
37 | #include <linux/tty.h> | 37 | #include <linux/tty.h> |
38 | #include <linux/tty_flip.h> | 38 | #include <linux/tty_flip.h> |
39 | #include <linux/kfifo.h> | ||
40 | #include <linux/slab.h> | ||
39 | 41 | ||
40 | #include <linux/mmc/core.h> | 42 | #include <linux/mmc/core.h> |
41 | #include <linux/mmc/card.h> | 43 | #include <linux/mmc/card.h> |
@@ -46,19 +48,9 @@ | |||
46 | #define UART_NR 8 /* Number of UARTs this driver can handle */ | 48 | #define UART_NR 8 /* Number of UARTs this driver can handle */ |
47 | 49 | ||
48 | 50 | ||
49 | #define UART_XMIT_SIZE PAGE_SIZE | 51 | #define FIFO_SIZE PAGE_SIZE |
50 | #define WAKEUP_CHARS 256 | 52 | #define WAKEUP_CHARS 256 |
51 | 53 | ||
52 | #define circ_empty(circ) ((circ)->head == (circ)->tail) | ||
53 | #define circ_clear(circ) ((circ)->head = (circ)->tail = 0) | ||
54 | |||
55 | #define circ_chars_pending(circ) \ | ||
56 | (CIRC_CNT((circ)->head, (circ)->tail, UART_XMIT_SIZE)) | ||
57 | |||
58 | #define circ_chars_free(circ) \ | ||
59 | (CIRC_SPACE((circ)->head, (circ)->tail, UART_XMIT_SIZE)) | ||
60 | |||
61 | |||
62 | struct uart_icount { | 54 | struct uart_icount { |
63 | __u32 cts; | 55 | __u32 cts; |
64 | __u32 dsr; | 56 | __u32 dsr; |
@@ -73,20 +65,20 @@ struct uart_icount { | |||
73 | }; | 65 | }; |
74 | 66 | ||
75 | struct sdio_uart_port { | 67 | struct sdio_uart_port { |
68 | struct tty_port port; | ||
76 | struct kref kref; | 69 | struct kref kref; |
77 | struct tty_struct *tty; | 70 | struct tty_struct *tty; |
78 | unsigned int index; | 71 | unsigned int index; |
79 | unsigned int opened; | ||
80 | struct mutex open_lock; | ||
81 | struct sdio_func *func; | 72 | struct sdio_func *func; |
82 | struct mutex func_lock; | 73 | struct mutex func_lock; |
83 | struct task_struct *in_sdio_uart_irq; | 74 | struct task_struct *in_sdio_uart_irq; |
84 | unsigned int regs_offset; | 75 | unsigned int regs_offset; |
85 | struct circ_buf xmit; | 76 | struct kfifo xmit_fifo; |
86 | spinlock_t write_lock; | 77 | spinlock_t write_lock; |
87 | struct uart_icount icount; | 78 | struct uart_icount icount; |
88 | unsigned int uartclk; | 79 | unsigned int uartclk; |
89 | unsigned int mctrl; | 80 | unsigned int mctrl; |
81 | unsigned int rx_mctrl; | ||
90 | unsigned int read_status_mask; | 82 | unsigned int read_status_mask; |
91 | unsigned int ignore_status_mask; | 83 | unsigned int ignore_status_mask; |
92 | unsigned char x_char; | 84 | unsigned char x_char; |
@@ -102,9 +94,10 @@ static int sdio_uart_add_port(struct sdio_uart_port *port) | |||
102 | int index, ret = -EBUSY; | 94 | int index, ret = -EBUSY; |
103 | 95 | ||
104 | kref_init(&port->kref); | 96 | kref_init(&port->kref); |
105 | mutex_init(&port->open_lock); | ||
106 | mutex_init(&port->func_lock); | 97 | mutex_init(&port->func_lock); |
107 | spin_lock_init(&port->write_lock); | 98 | spin_lock_init(&port->write_lock); |
99 | if (kfifo_alloc(&port->xmit_fifo, FIFO_SIZE, GFP_KERNEL)) | ||
100 | return -ENOMEM; | ||
108 | 101 | ||
109 | spin_lock(&sdio_uart_table_lock); | 102 | spin_lock(&sdio_uart_table_lock); |
110 | for (index = 0; index < UART_NR; index++) { | 103 | for (index = 0; index < UART_NR; index++) { |
@@ -140,6 +133,7 @@ static void sdio_uart_port_destroy(struct kref *kref) | |||
140 | { | 133 | { |
141 | struct sdio_uart_port *port = | 134 | struct sdio_uart_port *port = |
142 | container_of(kref, struct sdio_uart_port, kref); | 135 | container_of(kref, struct sdio_uart_port, kref); |
136 | kfifo_free(&port->xmit_fifo); | ||
143 | kfree(port); | 137 | kfree(port); |
144 | } | 138 | } |
145 | 139 | ||
@@ -151,6 +145,7 @@ static void sdio_uart_port_put(struct sdio_uart_port *port) | |||
151 | static void sdio_uart_port_remove(struct sdio_uart_port *port) | 145 | static void sdio_uart_port_remove(struct sdio_uart_port *port) |
152 | { | 146 | { |
153 | struct sdio_func *func; | 147 | struct sdio_func *func; |
148 | struct tty_struct *tty; | ||
154 | 149 | ||
155 | BUG_ON(sdio_uart_table[port->index] != port); | 150 | BUG_ON(sdio_uart_table[port->index] != port); |
156 | 151 | ||
@@ -165,15 +160,19 @@ static void sdio_uart_port_remove(struct sdio_uart_port *port) | |||
165 | * give up on that port ASAP. | 160 | * give up on that port ASAP. |
166 | * Beware: the lock ordering is critical. | 161 | * Beware: the lock ordering is critical. |
167 | */ | 162 | */ |
168 | mutex_lock(&port->open_lock); | 163 | mutex_lock(&port->port.mutex); |
169 | mutex_lock(&port->func_lock); | 164 | mutex_lock(&port->func_lock); |
170 | func = port->func; | 165 | func = port->func; |
171 | sdio_claim_host(func); | 166 | sdio_claim_host(func); |
172 | port->func = NULL; | 167 | port->func = NULL; |
173 | mutex_unlock(&port->func_lock); | 168 | mutex_unlock(&port->func_lock); |
174 | if (port->opened) | 169 | tty = tty_port_tty_get(&port->port); |
175 | tty_hangup(port->tty); | 170 | /* tty_hangup is async so is this safe as is ?? */ |
176 | mutex_unlock(&port->open_lock); | 171 | if (tty) { |
172 | tty_hangup(tty); | ||
173 | tty_kref_put(tty); | ||
174 | } | ||
175 | mutex_unlock(&port->port.mutex); | ||
177 | sdio_release_irq(func); | 176 | sdio_release_irq(func); |
178 | sdio_disable_func(func); | 177 | sdio_disable_func(func); |
179 | sdio_release_host(func); | 178 | sdio_release_host(func); |
@@ -217,6 +216,8 @@ static unsigned int sdio_uart_get_mctrl(struct sdio_uart_port *port) | |||
217 | unsigned char status; | 216 | unsigned char status; |
218 | unsigned int ret; | 217 | unsigned int ret; |
219 | 218 | ||
219 | /* FIXME: What stops this losing the delta bits and breaking | ||
220 | sdio_uart_check_modem_status ? */ | ||
220 | status = sdio_in(port, UART_MSR); | 221 | status = sdio_in(port, UART_MSR); |
221 | 222 | ||
222 | ret = 0; | 223 | ret = 0; |
@@ -231,7 +232,8 @@ static unsigned int sdio_uart_get_mctrl(struct sdio_uart_port *port) | |||
231 | return ret; | 232 | return ret; |
232 | } | 233 | } |
233 | 234 | ||
234 | static void sdio_uart_write_mctrl(struct sdio_uart_port *port, unsigned int mctrl) | 235 | static void sdio_uart_write_mctrl(struct sdio_uart_port *port, |
236 | unsigned int mctrl) | ||
235 | { | 237 | { |
236 | unsigned char mcr = 0; | 238 | unsigned char mcr = 0; |
237 | 239 | ||
@@ -387,9 +389,10 @@ static void sdio_uart_stop_rx(struct sdio_uart_port *port) | |||
387 | sdio_out(port, UART_IER, port->ier); | 389 | sdio_out(port, UART_IER, port->ier); |
388 | } | 390 | } |
389 | 391 | ||
390 | static void sdio_uart_receive_chars(struct sdio_uart_port *port, unsigned int *status) | 392 | static void sdio_uart_receive_chars(struct sdio_uart_port *port, |
393 | unsigned int *status) | ||
391 | { | 394 | { |
392 | struct tty_struct *tty = port->tty; | 395 | struct tty_struct *tty = tty_port_tty_get(&port->port); |
393 | unsigned int ch, flag; | 396 | unsigned int ch, flag; |
394 | int max_count = 256; | 397 | int max_count = 256; |
395 | 398 | ||
@@ -399,7 +402,7 @@ static void sdio_uart_receive_chars(struct sdio_uart_port *port, unsigned int *s | |||
399 | port->icount.rx++; | 402 | port->icount.rx++; |
400 | 403 | ||
401 | if (unlikely(*status & (UART_LSR_BI | UART_LSR_PE | | 404 | if (unlikely(*status & (UART_LSR_BI | UART_LSR_PE | |
402 | UART_LSR_FE | UART_LSR_OE))) { | 405 | UART_LSR_FE | UART_LSR_OE))) { |
403 | /* | 406 | /* |
404 | * For statistics only | 407 | * For statistics only |
405 | */ | 408 | */ |
@@ -417,33 +420,41 @@ static void sdio_uart_receive_chars(struct sdio_uart_port *port, unsigned int *s | |||
417 | * Mask off conditions which should be ignored. | 420 | * Mask off conditions which should be ignored. |
418 | */ | 421 | */ |
419 | *status &= port->read_status_mask; | 422 | *status &= port->read_status_mask; |
420 | if (*status & UART_LSR_BI) { | 423 | if (*status & UART_LSR_BI) |
421 | flag = TTY_BREAK; | 424 | flag = TTY_BREAK; |
422 | } else if (*status & UART_LSR_PE) | 425 | else if (*status & UART_LSR_PE) |
423 | flag = TTY_PARITY; | 426 | flag = TTY_PARITY; |
424 | else if (*status & UART_LSR_FE) | 427 | else if (*status & UART_LSR_FE) |
425 | flag = TTY_FRAME; | 428 | flag = TTY_FRAME; |
426 | } | 429 | } |
427 | 430 | ||
428 | if ((*status & port->ignore_status_mask & ~UART_LSR_OE) == 0) | 431 | if ((*status & port->ignore_status_mask & ~UART_LSR_OE) == 0) |
429 | tty_insert_flip_char(tty, ch, flag); | 432 | if (tty) |
433 | tty_insert_flip_char(tty, ch, flag); | ||
430 | 434 | ||
431 | /* | 435 | /* |
432 | * Overrun is special. Since it's reported immediately, | 436 | * Overrun is special. Since it's reported immediately, |
433 | * it doesn't affect the current character. | 437 | * it doesn't affect the current character. |
434 | */ | 438 | */ |
435 | if (*status & ~port->ignore_status_mask & UART_LSR_OE) | 439 | if (*status & ~port->ignore_status_mask & UART_LSR_OE) |
436 | tty_insert_flip_char(tty, 0, TTY_OVERRUN); | 440 | if (tty) |
441 | tty_insert_flip_char(tty, 0, TTY_OVERRUN); | ||
437 | 442 | ||
438 | *status = sdio_in(port, UART_LSR); | 443 | *status = sdio_in(port, UART_LSR); |
439 | } while ((*status & UART_LSR_DR) && (max_count-- > 0)); | 444 | } while ((*status & UART_LSR_DR) && (max_count-- > 0)); |
440 | tty_flip_buffer_push(tty); | 445 | if (tty) { |
446 | tty_flip_buffer_push(tty); | ||
447 | tty_kref_put(tty); | ||
448 | } | ||
441 | } | 449 | } |
442 | 450 | ||
443 | static void sdio_uart_transmit_chars(struct sdio_uart_port *port) | 451 | static void sdio_uart_transmit_chars(struct sdio_uart_port *port) |
444 | { | 452 | { |
445 | struct circ_buf *xmit = &port->xmit; | 453 | struct kfifo *xmit = &port->xmit_fifo; |
446 | int count; | 454 | int count; |
455 | struct tty_struct *tty; | ||
456 | u8 iobuf[16]; | ||
457 | int len; | ||
447 | 458 | ||
448 | if (port->x_char) { | 459 | if (port->x_char) { |
449 | sdio_out(port, UART_TX, port->x_char); | 460 | sdio_out(port, UART_TX, port->x_char); |
@@ -451,30 +462,35 @@ static void sdio_uart_transmit_chars(struct sdio_uart_port *port) | |||
451 | port->x_char = 0; | 462 | port->x_char = 0; |
452 | return; | 463 | return; |
453 | } | 464 | } |
454 | if (circ_empty(xmit) || port->tty->stopped || port->tty->hw_stopped) { | 465 | |
466 | tty = tty_port_tty_get(&port->port); | ||
467 | |||
468 | if (tty == NULL || !kfifo_len(xmit) || | ||
469 | tty->stopped || tty->hw_stopped) { | ||
455 | sdio_uart_stop_tx(port); | 470 | sdio_uart_stop_tx(port); |
471 | tty_kref_put(tty); | ||
456 | return; | 472 | return; |
457 | } | 473 | } |
458 | 474 | ||
459 | count = 16; | 475 | len = kfifo_out_locked(xmit, iobuf, 16, &port->write_lock); |
460 | do { | 476 | for (count = 0; count < len; count++) { |
461 | sdio_out(port, UART_TX, xmit->buf[xmit->tail]); | 477 | sdio_out(port, UART_TX, iobuf[count]); |
462 | xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); | ||
463 | port->icount.tx++; | 478 | port->icount.tx++; |
464 | if (circ_empty(xmit)) | 479 | } |
465 | break; | ||
466 | } while (--count > 0); | ||
467 | |||
468 | if (circ_chars_pending(xmit) < WAKEUP_CHARS) | ||
469 | tty_wakeup(port->tty); | ||
470 | 480 | ||
471 | if (circ_empty(xmit)) | 481 | len = kfifo_len(xmit); |
472 | sdio_uart_stop_tx(port); | 482 | if (len < WAKEUP_CHARS) { |
483 | tty_wakeup(tty); | ||
484 | if (len == 0) | ||
485 | sdio_uart_stop_tx(port); | ||
486 | } | ||
487 | tty_kref_put(tty); | ||
473 | } | 488 | } |
474 | 489 | ||
475 | static void sdio_uart_check_modem_status(struct sdio_uart_port *port) | 490 | static void sdio_uart_check_modem_status(struct sdio_uart_port *port) |
476 | { | 491 | { |
477 | int status; | 492 | int status; |
493 | struct tty_struct *tty; | ||
478 | 494 | ||
479 | status = sdio_in(port, UART_MSR); | 495 | status = sdio_in(port, UART_MSR); |
480 | 496 | ||
@@ -485,25 +501,39 @@ static void sdio_uart_check_modem_status(struct sdio_uart_port *port) | |||
485 | port->icount.rng++; | 501 | port->icount.rng++; |
486 | if (status & UART_MSR_DDSR) | 502 | if (status & UART_MSR_DDSR) |
487 | port->icount.dsr++; | 503 | port->icount.dsr++; |
488 | if (status & UART_MSR_DDCD) | 504 | if (status & UART_MSR_DDCD) { |
489 | port->icount.dcd++; | 505 | port->icount.dcd++; |
506 | /* DCD raise - wake for open */ | ||
507 | if (status & UART_MSR_DCD) | ||
508 | wake_up_interruptible(&port->port.open_wait); | ||
509 | else { | ||
510 | /* DCD drop - hang up if tty attached */ | ||
511 | tty = tty_port_tty_get(&port->port); | ||
512 | if (tty) { | ||
513 | tty_hangup(tty); | ||
514 | tty_kref_put(tty); | ||
515 | } | ||
516 | } | ||
517 | } | ||
490 | if (status & UART_MSR_DCTS) { | 518 | if (status & UART_MSR_DCTS) { |
491 | port->icount.cts++; | 519 | port->icount.cts++; |
492 | if (port->tty->termios->c_cflag & CRTSCTS) { | 520 | tty = tty_port_tty_get(&port->port); |
521 | if (tty && (tty->termios->c_cflag & CRTSCTS)) { | ||
493 | int cts = (status & UART_MSR_CTS); | 522 | int cts = (status & UART_MSR_CTS); |
494 | if (port->tty->hw_stopped) { | 523 | if (tty->hw_stopped) { |
495 | if (cts) { | 524 | if (cts) { |
496 | port->tty->hw_stopped = 0; | 525 | tty->hw_stopped = 0; |
497 | sdio_uart_start_tx(port); | 526 | sdio_uart_start_tx(port); |
498 | tty_wakeup(port->tty); | 527 | tty_wakeup(tty); |
499 | } | 528 | } |
500 | } else { | 529 | } else { |
501 | if (!cts) { | 530 | if (!cts) { |
502 | port->tty->hw_stopped = 1; | 531 | tty->hw_stopped = 1; |
503 | sdio_uart_stop_tx(port); | 532 | sdio_uart_stop_tx(port); |
504 | } | 533 | } |
505 | } | 534 | } |
506 | } | 535 | } |
536 | tty_kref_put(tty); | ||
507 | } | 537 | } |
508 | } | 538 | } |
509 | 539 | ||
@@ -540,33 +570,81 @@ static void sdio_uart_irq(struct sdio_func *func) | |||
540 | port->in_sdio_uart_irq = NULL; | 570 | port->in_sdio_uart_irq = NULL; |
541 | } | 571 | } |
542 | 572 | ||
543 | static int sdio_uart_startup(struct sdio_uart_port *port) | 573 | static int uart_carrier_raised(struct tty_port *tport) |
574 | { | ||
575 | struct sdio_uart_port *port = | ||
576 | container_of(tport, struct sdio_uart_port, port); | ||
577 | unsigned int ret = sdio_uart_claim_func(port); | ||
578 | if (ret) /* Missing hardware shouldn't block for carrier */ | ||
579 | return 1; | ||
580 | ret = sdio_uart_get_mctrl(port); | ||
581 | sdio_uart_release_func(port); | ||
582 | if (ret & TIOCM_CAR) | ||
583 | return 1; | ||
584 | return 0; | ||
585 | } | ||
586 | |||
587 | /** | ||
588 | * uart_dtr_rts - port helper to set uart signals | ||
589 | * @tport: tty port to be updated | ||
590 | * @onoff: set to turn on DTR/RTS | ||
591 | * | ||
592 | * Called by the tty port helpers when the modem signals need to be | ||
593 | * adjusted during an open, close and hangup. | ||
594 | */ | ||
595 | |||
596 | static void uart_dtr_rts(struct tty_port *tport, int onoff) | ||
597 | { | ||
598 | struct sdio_uart_port *port = | ||
599 | container_of(tport, struct sdio_uart_port, port); | ||
600 | int ret = sdio_uart_claim_func(port); | ||
601 | if (ret) | ||
602 | return; | ||
603 | if (onoff == 0) | ||
604 | sdio_uart_clear_mctrl(port, TIOCM_DTR | TIOCM_RTS); | ||
605 | else | ||
606 | sdio_uart_set_mctrl(port, TIOCM_DTR | TIOCM_RTS); | ||
607 | sdio_uart_release_func(port); | ||
608 | } | ||
609 | |||
610 | /** | ||
611 | * sdio_uart_activate - start up hardware | ||
612 | * @tport: tty port to activate | ||
613 | * @tty: tty bound to this port | ||
614 | * | ||
615 | * Activate a tty port. The port locking guarantees us this will be | ||
616 | * run exactly once per set of opens, and if successful will see the | ||
617 | * shutdown method run exactly once to match. Start up and shutdown are | ||
618 | * protected from each other by the internal locking and will not run | ||
619 | * at the same time even during a hangup event. | ||
620 | * | ||
621 | * If we successfully start up the port we take an extra kref as we | ||
622 | * will keep it around until shutdown when the kref is dropped. | ||
623 | */ | ||
624 | |||
625 | static int sdio_uart_activate(struct tty_port *tport, struct tty_struct *tty) | ||
544 | { | 626 | { |
545 | unsigned long page; | 627 | struct sdio_uart_port *port = |
628 | container_of(tport, struct sdio_uart_port, port); | ||
546 | int ret; | 629 | int ret; |
547 | 630 | ||
548 | /* | 631 | /* |
549 | * Set the TTY IO error marker - we will only clear this | 632 | * Set the TTY IO error marker - we will only clear this |
550 | * once we have successfully opened the port. | 633 | * once we have successfully opened the port. |
551 | */ | 634 | */ |
552 | set_bit(TTY_IO_ERROR, &port->tty->flags); | 635 | set_bit(TTY_IO_ERROR, &tty->flags); |
553 | 636 | ||
554 | /* Initialise and allocate the transmit buffer. */ | 637 | kfifo_reset(&port->xmit_fifo); |
555 | page = __get_free_page(GFP_KERNEL); | ||
556 | if (!page) | ||
557 | return -ENOMEM; | ||
558 | port->xmit.buf = (unsigned char *)page; | ||
559 | circ_clear(&port->xmit); | ||
560 | 638 | ||
561 | ret = sdio_uart_claim_func(port); | 639 | ret = sdio_uart_claim_func(port); |
562 | if (ret) | 640 | if (ret) |
563 | goto err1; | 641 | return ret; |
564 | ret = sdio_enable_func(port->func); | 642 | ret = sdio_enable_func(port->func); |
565 | if (ret) | 643 | if (ret) |
566 | goto err2; | 644 | goto err1; |
567 | ret = sdio_claim_irq(port->func, sdio_uart_irq); | 645 | ret = sdio_claim_irq(port->func, sdio_uart_irq); |
568 | if (ret) | 646 | if (ret) |
569 | goto err3; | 647 | goto err2; |
570 | 648 | ||
571 | /* | 649 | /* |
572 | * Clear the FIFO buffers and disable them. | 650 | * Clear the FIFO buffers and disable them. |
@@ -574,7 +652,7 @@ static int sdio_uart_startup(struct sdio_uart_port *port) | |||
574 | */ | 652 | */ |
575 | sdio_out(port, UART_FCR, UART_FCR_ENABLE_FIFO); | 653 | sdio_out(port, UART_FCR, UART_FCR_ENABLE_FIFO); |
576 | sdio_out(port, UART_FCR, UART_FCR_ENABLE_FIFO | | 654 | sdio_out(port, UART_FCR, UART_FCR_ENABLE_FIFO | |
577 | UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT); | 655 | UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT); |
578 | sdio_out(port, UART_FCR, 0); | 656 | sdio_out(port, UART_FCR, 0); |
579 | 657 | ||
580 | /* | 658 | /* |
@@ -590,19 +668,19 @@ static int sdio_uart_startup(struct sdio_uart_port *port) | |||
590 | */ | 668 | */ |
591 | sdio_out(port, UART_LCR, UART_LCR_WLEN8); | 669 | sdio_out(port, UART_LCR, UART_LCR_WLEN8); |
592 | 670 | ||
593 | port->ier = UART_IER_RLSI | UART_IER_RDI | UART_IER_RTOIE | UART_IER_UUE; | 671 | port->ier = UART_IER_RLSI|UART_IER_RDI|UART_IER_RTOIE|UART_IER_UUE; |
594 | port->mctrl = TIOCM_OUT2; | 672 | port->mctrl = TIOCM_OUT2; |
595 | 673 | ||
596 | sdio_uart_change_speed(port, port->tty->termios, NULL); | 674 | sdio_uart_change_speed(port, tty->termios, NULL); |
597 | 675 | ||
598 | if (port->tty->termios->c_cflag & CBAUD) | 676 | if (tty->termios->c_cflag & CBAUD) |
599 | sdio_uart_set_mctrl(port, TIOCM_RTS | TIOCM_DTR); | 677 | sdio_uart_set_mctrl(port, TIOCM_RTS | TIOCM_DTR); |
600 | 678 | ||
601 | if (port->tty->termios->c_cflag & CRTSCTS) | 679 | if (tty->termios->c_cflag & CRTSCTS) |
602 | if (!(sdio_uart_get_mctrl(port) & TIOCM_CTS)) | 680 | if (!(sdio_uart_get_mctrl(port) & TIOCM_CTS)) |
603 | port->tty->hw_stopped = 1; | 681 | tty->hw_stopped = 1; |
604 | 682 | ||
605 | clear_bit(TTY_IO_ERROR, &port->tty->flags); | 683 | clear_bit(TTY_IO_ERROR, &tty->flags); |
606 | 684 | ||
607 | /* Kick the IRQ handler once while we're still holding the host lock */ | 685 | /* Kick the IRQ handler once while we're still holding the host lock */ |
608 | sdio_uart_irq(port->func); | 686 | sdio_uart_irq(port->func); |
@@ -610,32 +688,36 @@ static int sdio_uart_startup(struct sdio_uart_port *port) | |||
610 | sdio_uart_release_func(port); | 688 | sdio_uart_release_func(port); |
611 | return 0; | 689 | return 0; |
612 | 690 | ||
613 | err3: | ||
614 | sdio_disable_func(port->func); | ||
615 | err2: | 691 | err2: |
616 | sdio_uart_release_func(port); | 692 | sdio_disable_func(port->func); |
617 | err1: | 693 | err1: |
618 | free_page((unsigned long)port->xmit.buf); | 694 | sdio_uart_release_func(port); |
619 | return ret; | 695 | return ret; |
620 | } | 696 | } |
621 | 697 | ||
622 | static void sdio_uart_shutdown(struct sdio_uart_port *port) | 698 | /** |
699 | * sdio_uart_shutdown - stop hardware | ||
700 | * @tport: tty port to shut down | ||
701 | * | ||
702 | * Deactivate a tty port. The port locking guarantees us this will be | ||
703 | * run only if a successful matching activate already ran. The two are | ||
704 | * protected from each other by the internal locking and will not run | ||
705 | * at the same time even during a hangup event. | ||
706 | */ | ||
707 | |||
708 | static void sdio_uart_shutdown(struct tty_port *tport) | ||
623 | { | 709 | { |
710 | struct sdio_uart_port *port = | ||
711 | container_of(tport, struct sdio_uart_port, port); | ||
624 | int ret; | 712 | int ret; |
625 | 713 | ||
626 | ret = sdio_uart_claim_func(port); | 714 | ret = sdio_uart_claim_func(port); |
627 | if (ret) | 715 | if (ret) |
628 | goto skip; | 716 | return; |
629 | 717 | ||
630 | sdio_uart_stop_rx(port); | 718 | sdio_uart_stop_rx(port); |
631 | 719 | ||
632 | /* TODO: wait here for TX FIFO to drain */ | 720 | /* Disable interrupts from this port */ |
633 | |||
634 | /* Turn off DTR and RTS early. */ | ||
635 | if (port->tty->termios->c_cflag & HUPCL) | ||
636 | sdio_uart_clear_mctrl(port, TIOCM_DTR | TIOCM_RTS); | ||
637 | |||
638 | /* Disable interrupts from this port */ | ||
639 | sdio_release_irq(port->func); | 721 | sdio_release_irq(port->func); |
640 | port->ier = 0; | 722 | port->ier = 0; |
641 | sdio_out(port, UART_IER, 0); | 723 | sdio_out(port, UART_IER, 0); |
@@ -653,108 +735,82 @@ static void sdio_uart_shutdown(struct sdio_uart_port *port) | |||
653 | sdio_disable_func(port->func); | 735 | sdio_disable_func(port->func); |
654 | 736 | ||
655 | sdio_uart_release_func(port); | 737 | sdio_uart_release_func(port); |
656 | |||
657 | skip: | ||
658 | /* Free the transmit buffer page. */ | ||
659 | free_page((unsigned long)port->xmit.buf); | ||
660 | } | 738 | } |
661 | 739 | ||
662 | static int sdio_uart_open (struct tty_struct *tty, struct file * filp) | 740 | /** |
741 | * sdio_uart_install - install method | ||
742 | * @driver: the driver in use (sdio_uart in our case) | ||
743 | * @tty: the tty being bound | ||
744 | * | ||
745 | * Look up and bind the tty and the driver together. Initialize | ||
746 | * any needed private data (in our case the termios) | ||
747 | */ | ||
748 | |||
749 | static int sdio_uart_install(struct tty_driver *driver, struct tty_struct *tty) | ||
663 | { | 750 | { |
664 | struct sdio_uart_port *port; | 751 | int idx = tty->index; |
665 | int ret; | 752 | struct sdio_uart_port *port = sdio_uart_port_get(idx); |
753 | int ret = tty_init_termios(tty); | ||
754 | |||
755 | if (ret == 0) { | ||
756 | tty_driver_kref_get(driver); | ||
757 | tty->count++; | ||
758 | /* This is the ref sdio_uart_port get provided */ | ||
759 | tty->driver_data = port; | ||
760 | driver->ttys[idx] = tty; | ||
761 | } else | ||
762 | sdio_uart_port_put(port); | ||
763 | return ret; | ||
764 | } | ||
666 | 765 | ||
667 | port = sdio_uart_port_get(tty->index); | 766 | /** |
668 | if (!port) | 767 | * sdio_uart_cleanup - called on the last tty kref drop |
669 | return -ENODEV; | 768 | * @tty: the tty being destroyed |
769 | * | ||
770 | * Called asynchronously when the last reference to the tty is dropped. | ||
771 | * We cannot destroy the tty->driver_data port kref until this point | ||
772 | */ | ||
670 | 773 | ||
671 | mutex_lock(&port->open_lock); | 774 | static void sdio_uart_cleanup(struct tty_struct *tty) |
775 | { | ||
776 | struct sdio_uart_port *port = tty->driver_data; | ||
777 | tty->driver_data = NULL; /* Bug trap */ | ||
778 | sdio_uart_port_put(port); | ||
779 | } | ||
672 | 780 | ||
673 | /* | 781 | /* |
674 | * Make sure not to mess up with a dead port | 782 | * Open/close/hangup is now entirely boilerplate |
675 | * which has not been closed yet. | 783 | */ |
676 | */ | ||
677 | if (tty->driver_data && tty->driver_data != port) { | ||
678 | mutex_unlock(&port->open_lock); | ||
679 | sdio_uart_port_put(port); | ||
680 | return -EBUSY; | ||
681 | } | ||
682 | 784 | ||
683 | if (!port->opened) { | 785 | static int sdio_uart_open(struct tty_struct *tty, struct file *filp) |
684 | tty->driver_data = port; | 786 | { |
685 | port->tty = tty; | 787 | struct sdio_uart_port *port = tty->driver_data; |
686 | ret = sdio_uart_startup(port); | 788 | return tty_port_open(&port->port, tty, filp); |
687 | if (ret) { | ||
688 | tty->driver_data = NULL; | ||
689 | port->tty = NULL; | ||
690 | mutex_unlock(&port->open_lock); | ||
691 | sdio_uart_port_put(port); | ||
692 | return ret; | ||
693 | } | ||
694 | } | ||
695 | port->opened++; | ||
696 | mutex_unlock(&port->open_lock); | ||
697 | return 0; | ||
698 | } | 789 | } |
699 | 790 | ||
700 | static void sdio_uart_close(struct tty_struct *tty, struct file * filp) | 791 | static void sdio_uart_close(struct tty_struct *tty, struct file * filp) |
701 | { | 792 | { |
702 | struct sdio_uart_port *port = tty->driver_data; | 793 | struct sdio_uart_port *port = tty->driver_data; |
794 | tty_port_close(&port->port, tty, filp); | ||
795 | } | ||
703 | 796 | ||
704 | if (!port) | 797 | static void sdio_uart_hangup(struct tty_struct *tty) |
705 | return; | 798 | { |
706 | 799 | struct sdio_uart_port *port = tty->driver_data; | |
707 | mutex_lock(&port->open_lock); | 800 | tty_port_hangup(&port->port); |
708 | BUG_ON(!port->opened); | ||
709 | |||
710 | /* | ||
711 | * This is messy. The tty layer calls us even when open() | ||
712 | * returned an error. Ignore this close request if tty->count | ||
713 | * is larger than port->count. | ||
714 | */ | ||
715 | if (tty->count > port->opened) { | ||
716 | mutex_unlock(&port->open_lock); | ||
717 | return; | ||
718 | } | ||
719 | |||
720 | if (--port->opened == 0) { | ||
721 | tty->closing = 1; | ||
722 | sdio_uart_shutdown(port); | ||
723 | tty_ldisc_flush(tty); | ||
724 | port->tty = NULL; | ||
725 | tty->driver_data = NULL; | ||
726 | tty->closing = 0; | ||
727 | } | ||
728 | mutex_unlock(&port->open_lock); | ||
729 | sdio_uart_port_put(port); | ||
730 | } | 801 | } |
731 | 802 | ||
732 | static int sdio_uart_write(struct tty_struct * tty, const unsigned char *buf, | 803 | static int sdio_uart_write(struct tty_struct *tty, const unsigned char *buf, |
733 | int count) | 804 | int count) |
734 | { | 805 | { |
735 | struct sdio_uart_port *port = tty->driver_data; | 806 | struct sdio_uart_port *port = tty->driver_data; |
736 | struct circ_buf *circ = &port->xmit; | 807 | int ret; |
737 | int c, ret = 0; | ||
738 | 808 | ||
739 | if (!port->func) | 809 | if (!port->func) |
740 | return -ENODEV; | 810 | return -ENODEV; |
741 | 811 | ||
742 | spin_lock(&port->write_lock); | 812 | ret = kfifo_in_locked(&port->xmit_fifo, buf, count, &port->write_lock); |
743 | while (1) { | 813 | if (!(port->ier & UART_IER_THRI)) { |
744 | c = CIRC_SPACE_TO_END(circ->head, circ->tail, UART_XMIT_SIZE); | ||
745 | if (count < c) | ||
746 | c = count; | ||
747 | if (c <= 0) | ||
748 | break; | ||
749 | memcpy(circ->buf + circ->head, buf, c); | ||
750 | circ->head = (circ->head + c) & (UART_XMIT_SIZE - 1); | ||
751 | buf += c; | ||
752 | count -= c; | ||
753 | ret += c; | ||
754 | } | ||
755 | spin_unlock(&port->write_lock); | ||
756 | |||
757 | if ( !(port->ier & UART_IER_THRI)) { | ||
758 | int err = sdio_uart_claim_func(port); | 814 | int err = sdio_uart_claim_func(port); |
759 | if (!err) { | 815 | if (!err) { |
760 | sdio_uart_start_tx(port); | 816 | sdio_uart_start_tx(port); |
@@ -770,13 +826,13 @@ static int sdio_uart_write(struct tty_struct * tty, const unsigned char *buf, | |||
770 | static int sdio_uart_write_room(struct tty_struct *tty) | 826 | static int sdio_uart_write_room(struct tty_struct *tty) |
771 | { | 827 | { |
772 | struct sdio_uart_port *port = tty->driver_data; | 828 | struct sdio_uart_port *port = tty->driver_data; |
773 | return port ? circ_chars_free(&port->xmit) : 0; | 829 | return FIFO_SIZE - kfifo_len(&port->xmit_fifo); |
774 | } | 830 | } |
775 | 831 | ||
776 | static int sdio_uart_chars_in_buffer(struct tty_struct *tty) | 832 | static int sdio_uart_chars_in_buffer(struct tty_struct *tty) |
777 | { | 833 | { |
778 | struct sdio_uart_port *port = tty->driver_data; | 834 | struct sdio_uart_port *port = tty->driver_data; |
779 | return port ? circ_chars_pending(&port->xmit) : 0; | 835 | return kfifo_len(&port->xmit_fifo); |
780 | } | 836 | } |
781 | 837 | ||
782 | static void sdio_uart_send_xchar(struct tty_struct *tty, char ch) | 838 | static void sdio_uart_send_xchar(struct tty_struct *tty, char ch) |
@@ -841,17 +897,12 @@ static void sdio_uart_unthrottle(struct tty_struct *tty) | |||
841 | sdio_uart_release_func(port); | 897 | sdio_uart_release_func(port); |
842 | } | 898 | } |
843 | 899 | ||
844 | static void sdio_uart_set_termios(struct tty_struct *tty, struct ktermios *old_termios) | 900 | static void sdio_uart_set_termios(struct tty_struct *tty, |
901 | struct ktermios *old_termios) | ||
845 | { | 902 | { |
846 | struct sdio_uart_port *port = tty->driver_data; | 903 | struct sdio_uart_port *port = tty->driver_data; |
847 | unsigned int cflag = tty->termios->c_cflag; | 904 | unsigned int cflag = tty->termios->c_cflag; |
848 | 905 | ||
849 | #define RELEVANT_IFLAG(iflag) ((iflag) & (IGNBRK|BRKINT|IGNPAR|PARMRK|INPCK)) | ||
850 | |||
851 | if ((cflag ^ old_termios->c_cflag) == 0 && | ||
852 | RELEVANT_IFLAG(tty->termios->c_iflag ^ old_termios->c_iflag) == 0) | ||
853 | return; | ||
854 | |||
855 | if (sdio_uart_claim_func(port) != 0) | 906 | if (sdio_uart_claim_func(port) != 0) |
856 | return; | 907 | return; |
857 | 908 | ||
@@ -925,8 +976,8 @@ static int sdio_uart_tiocmset(struct tty_struct *tty, struct file *file, | |||
925 | struct sdio_uart_port *port = tty->driver_data; | 976 | struct sdio_uart_port *port = tty->driver_data; |
926 | int result; | 977 | int result; |
927 | 978 | ||
928 | result =sdio_uart_claim_func(port); | 979 | result = sdio_uart_claim_func(port); |
929 | if(!result) { | 980 | if (!result) { |
930 | sdio_uart_update_mctrl(port, set, clear); | 981 | sdio_uart_update_mctrl(port, set, clear); |
931 | sdio_uart_release_func(port); | 982 | sdio_uart_release_func(port); |
932 | } | 983 | } |
@@ -944,33 +995,33 @@ static int sdio_uart_proc_show(struct seq_file *m, void *v) | |||
944 | struct sdio_uart_port *port = sdio_uart_port_get(i); | 995 | struct sdio_uart_port *port = sdio_uart_port_get(i); |
945 | if (port) { | 996 | if (port) { |
946 | seq_printf(m, "%d: uart:SDIO", i); | 997 | seq_printf(m, "%d: uart:SDIO", i); |
947 | if(capable(CAP_SYS_ADMIN)) { | 998 | if (capable(CAP_SYS_ADMIN)) { |
948 | seq_printf(m, " tx:%d rx:%d", | 999 | seq_printf(m, " tx:%d rx:%d", |
949 | port->icount.tx, port->icount.rx); | 1000 | port->icount.tx, port->icount.rx); |
950 | if (port->icount.frame) | 1001 | if (port->icount.frame) |
951 | seq_printf(m, " fe:%d", | 1002 | seq_printf(m, " fe:%d", |
952 | port->icount.frame); | 1003 | port->icount.frame); |
953 | if (port->icount.parity) | 1004 | if (port->icount.parity) |
954 | seq_printf(m, " pe:%d", | 1005 | seq_printf(m, " pe:%d", |
955 | port->icount.parity); | 1006 | port->icount.parity); |
956 | if (port->icount.brk) | 1007 | if (port->icount.brk) |
957 | seq_printf(m, " brk:%d", | 1008 | seq_printf(m, " brk:%d", |
958 | port->icount.brk); | 1009 | port->icount.brk); |
959 | if (port->icount.overrun) | 1010 | if (port->icount.overrun) |
960 | seq_printf(m, " oe:%d", | 1011 | seq_printf(m, " oe:%d", |
961 | port->icount.overrun); | 1012 | port->icount.overrun); |
962 | if (port->icount.cts) | 1013 | if (port->icount.cts) |
963 | seq_printf(m, " cts:%d", | 1014 | seq_printf(m, " cts:%d", |
964 | port->icount.cts); | 1015 | port->icount.cts); |
965 | if (port->icount.dsr) | 1016 | if (port->icount.dsr) |
966 | seq_printf(m, " dsr:%d", | 1017 | seq_printf(m, " dsr:%d", |
967 | port->icount.dsr); | 1018 | port->icount.dsr); |
968 | if (port->icount.rng) | 1019 | if (port->icount.rng) |
969 | seq_printf(m, " rng:%d", | 1020 | seq_printf(m, " rng:%d", |
970 | port->icount.rng); | 1021 | port->icount.rng); |
971 | if (port->icount.dcd) | 1022 | if (port->icount.dcd) |
972 | seq_printf(m, " dcd:%d", | 1023 | seq_printf(m, " dcd:%d", |
973 | port->icount.dcd); | 1024 | port->icount.dcd); |
974 | } | 1025 | } |
975 | sdio_uart_port_put(port); | 1026 | sdio_uart_port_put(port); |
976 | seq_putc(m, '\n'); | 1027 | seq_putc(m, '\n'); |
@@ -992,6 +1043,13 @@ static const struct file_operations sdio_uart_proc_fops = { | |||
992 | .release = single_release, | 1043 | .release = single_release, |
993 | }; | 1044 | }; |
994 | 1045 | ||
1046 | static const struct tty_port_operations sdio_uart_port_ops = { | ||
1047 | .dtr_rts = uart_dtr_rts, | ||
1048 | .carrier_raised = uart_carrier_raised, | ||
1049 | .shutdown = sdio_uart_shutdown, | ||
1050 | .activate = sdio_uart_activate, | ||
1051 | }; | ||
1052 | |||
995 | static const struct tty_operations sdio_uart_ops = { | 1053 | static const struct tty_operations sdio_uart_ops = { |
996 | .open = sdio_uart_open, | 1054 | .open = sdio_uart_open, |
997 | .close = sdio_uart_close, | 1055 | .close = sdio_uart_close, |
@@ -1002,9 +1060,12 @@ static const struct tty_operations sdio_uart_ops = { | |||
1002 | .throttle = sdio_uart_throttle, | 1060 | .throttle = sdio_uart_throttle, |
1003 | .unthrottle = sdio_uart_unthrottle, | 1061 | .unthrottle = sdio_uart_unthrottle, |
1004 | .set_termios = sdio_uart_set_termios, | 1062 | .set_termios = sdio_uart_set_termios, |
1063 | .hangup = sdio_uart_hangup, | ||
1005 | .break_ctl = sdio_uart_break_ctl, | 1064 | .break_ctl = sdio_uart_break_ctl, |
1006 | .tiocmget = sdio_uart_tiocmget, | 1065 | .tiocmget = sdio_uart_tiocmget, |
1007 | .tiocmset = sdio_uart_tiocmset, | 1066 | .tiocmset = sdio_uart_tiocmset, |
1067 | .install = sdio_uart_install, | ||
1068 | .cleanup = sdio_uart_cleanup, | ||
1008 | .proc_fops = &sdio_uart_proc_fops, | 1069 | .proc_fops = &sdio_uart_proc_fops, |
1009 | }; | 1070 | }; |
1010 | 1071 | ||
@@ -1041,7 +1102,7 @@ static int sdio_uart_probe(struct sdio_func *func, | |||
1041 | } | 1102 | } |
1042 | if (!tpl) { | 1103 | if (!tpl) { |
1043 | printk(KERN_WARNING | 1104 | printk(KERN_WARNING |
1044 | "%s: can't find tuple 0x91 subtuple 0 (SUBTPL_SIOREG) for GPS class\n", | 1105 | "%s: can't find tuple 0x91 subtuple 0 (SUBTPL_SIOREG) for GPS class\n", |
1045 | sdio_func_id(func)); | 1106 | sdio_func_id(func)); |
1046 | kfree(port); | 1107 | kfree(port); |
1047 | return -EINVAL; | 1108 | return -EINVAL; |
@@ -1066,13 +1127,16 @@ static int sdio_uart_probe(struct sdio_func *func, | |||
1066 | 1127 | ||
1067 | port->func = func; | 1128 | port->func = func; |
1068 | sdio_set_drvdata(func, port); | 1129 | sdio_set_drvdata(func, port); |
1130 | tty_port_init(&port->port); | ||
1131 | port->port.ops = &sdio_uart_port_ops; | ||
1069 | 1132 | ||
1070 | ret = sdio_uart_add_port(port); | 1133 | ret = sdio_uart_add_port(port); |
1071 | if (ret) { | 1134 | if (ret) { |
1072 | kfree(port); | 1135 | kfree(port); |
1073 | } else { | 1136 | } else { |
1074 | struct device *dev; | 1137 | struct device *dev; |
1075 | dev = tty_register_device(sdio_uart_tty_driver, port->index, &func->dev); | 1138 | dev = tty_register_device(sdio_uart_tty_driver, |
1139 | port->index, &func->dev); | ||
1076 | if (IS_ERR(dev)) { | 1140 | if (IS_ERR(dev)) { |
1077 | sdio_uart_port_remove(port); | 1141 | sdio_uart_port_remove(port); |
1078 | ret = PTR_ERR(dev); | 1142 | ret = PTR_ERR(dev); |
diff --git a/drivers/mmc/core/Kconfig b/drivers/mmc/core/Kconfig index ab37a6d9d32a..bb22ffd76ef8 100644 --- a/drivers/mmc/core/Kconfig +++ b/drivers/mmc/core/Kconfig | |||
@@ -3,7 +3,7 @@ | |||
3 | # | 3 | # |
4 | 4 | ||
5 | config MMC_UNSAFE_RESUME | 5 | config MMC_UNSAFE_RESUME |
6 | bool "Allow unsafe resume (DANGEROUS)" | 6 | bool "Assume MMC/SD cards are non-removable (DANGEROUS)" |
7 | help | 7 | help |
8 | If you say Y here, the MMC layer will assume that all cards | 8 | If you say Y here, the MMC layer will assume that all cards |
9 | stayed in their respective slots during the suspend. The | 9 | stayed in their respective slots during the suspend. The |
@@ -14,3 +14,5 @@ config MMC_UNSAFE_RESUME | |||
14 | This option is usually just for embedded systems which use | 14 | This option is usually just for embedded systems which use |
15 | a MMC/SD card for rootfs. Most people should say N here. | 15 | a MMC/SD card for rootfs. Most people should say N here. |
16 | 16 | ||
17 | This option sets a default which can be overridden by the | ||
18 | module parameter "removable=0" or "removable=1". | ||
diff --git a/drivers/mmc/core/bus.c b/drivers/mmc/core/bus.c index bdb165f93046..49d9dcaeca49 100644 --- a/drivers/mmc/core/bus.c +++ b/drivers/mmc/core/bus.c | |||
@@ -13,6 +13,7 @@ | |||
13 | 13 | ||
14 | #include <linux/device.h> | 14 | #include <linux/device.h> |
15 | #include <linux/err.h> | 15 | #include <linux/err.h> |
16 | #include <linux/slab.h> | ||
16 | 17 | ||
17 | #include <linux/mmc/card.h> | 18 | #include <linux/mmc/card.h> |
18 | #include <linux/mmc/host.h> | 19 | #include <linux/mmc/host.h> |
diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c index 7dab2e5f4bc9..3168ebd616b2 100644 --- a/drivers/mmc/core/core.c +++ b/drivers/mmc/core/core.c | |||
@@ -48,6 +48,22 @@ int use_spi_crc = 1; | |||
48 | module_param(use_spi_crc, bool, 0); | 48 | module_param(use_spi_crc, bool, 0); |
49 | 49 | ||
50 | /* | 50 | /* |
51 | * We normally treat cards as removed during suspend if they are not | ||
52 | * known to be on a non-removable bus, to avoid the risk of writing | ||
53 | * back data to a different card after resume. Allow this to be | ||
54 | * overridden if necessary. | ||
55 | */ | ||
56 | #ifdef CONFIG_MMC_UNSAFE_RESUME | ||
57 | int mmc_assume_removable; | ||
58 | #else | ||
59 | int mmc_assume_removable = 1; | ||
60 | #endif | ||
61 | module_param_named(removable, mmc_assume_removable, bool, 0644); | ||
62 | MODULE_PARM_DESC( | ||
63 | removable, | ||
64 | "MMC/SD cards are removable and may be removed during suspend"); | ||
65 | |||
66 | /* | ||
51 | * Internal function. Schedule delayed work in the MMC work queue. | 67 | * Internal function. Schedule delayed work in the MMC work queue. |
52 | */ | 68 | */ |
53 | static int mmc_schedule_delayed_work(struct delayed_work *work, | 69 | static int mmc_schedule_delayed_work(struct delayed_work *work, |
@@ -1073,6 +1089,7 @@ void mmc_rescan(struct work_struct *work) | |||
1073 | mmc_claim_host(host); | 1089 | mmc_claim_host(host); |
1074 | 1090 | ||
1075 | mmc_power_up(host); | 1091 | mmc_power_up(host); |
1092 | sdio_reset(host); | ||
1076 | mmc_go_idle(host); | 1093 | mmc_go_idle(host); |
1077 | 1094 | ||
1078 | mmc_send_if_cond(host, host->ocr_avail); | 1095 | mmc_send_if_cond(host, host->ocr_avail); |
@@ -1135,6 +1152,9 @@ void mmc_stop_host(struct mmc_host *host) | |||
1135 | cancel_delayed_work(&host->detect); | 1152 | cancel_delayed_work(&host->detect); |
1136 | mmc_flush_scheduled_work(); | 1153 | mmc_flush_scheduled_work(); |
1137 | 1154 | ||
1155 | /* clear pm flags now and let card drivers set them as needed */ | ||
1156 | host->pm_flags = 0; | ||
1157 | |||
1138 | mmc_bus_get(host); | 1158 | mmc_bus_get(host); |
1139 | if (host->bus_ops && !host->bus_dead) { | 1159 | if (host->bus_ops && !host->bus_dead) { |
1140 | if (host->bus_ops->remove) | 1160 | if (host->bus_ops->remove) |
@@ -1257,12 +1277,13 @@ int mmc_suspend_host(struct mmc_host *host, pm_message_t state) | |||
1257 | mmc_claim_host(host); | 1277 | mmc_claim_host(host); |
1258 | mmc_detach_bus(host); | 1278 | mmc_detach_bus(host); |
1259 | mmc_release_host(host); | 1279 | mmc_release_host(host); |
1280 | host->pm_flags = 0; | ||
1260 | err = 0; | 1281 | err = 0; |
1261 | } | 1282 | } |
1262 | } | 1283 | } |
1263 | mmc_bus_put(host); | 1284 | mmc_bus_put(host); |
1264 | 1285 | ||
1265 | if (!err) | 1286 | if (!err && !(host->pm_flags & MMC_PM_KEEP_POWER)) |
1266 | mmc_power_off(host); | 1287 | mmc_power_off(host); |
1267 | 1288 | ||
1268 | return err; | 1289 | return err; |
@@ -1280,8 +1301,10 @@ int mmc_resume_host(struct mmc_host *host) | |||
1280 | 1301 | ||
1281 | mmc_bus_get(host); | 1302 | mmc_bus_get(host); |
1282 | if (host->bus_ops && !host->bus_dead) { | 1303 | if (host->bus_ops && !host->bus_dead) { |
1283 | mmc_power_up(host); | 1304 | if (!(host->pm_flags & MMC_PM_KEEP_POWER)) { |
1284 | mmc_select_voltage(host, host->ocr); | 1305 | mmc_power_up(host); |
1306 | mmc_select_voltage(host, host->ocr); | ||
1307 | } | ||
1285 | BUG_ON(!host->bus_ops->resume); | 1308 | BUG_ON(!host->bus_ops->resume); |
1286 | err = host->bus_ops->resume(host); | 1309 | err = host->bus_ops->resume(host); |
1287 | if (err) { | 1310 | if (err) { |
diff --git a/drivers/mmc/core/core.h b/drivers/mmc/core/core.h index 67ae6abc4230..a811c52a1659 100644 --- a/drivers/mmc/core/core.h +++ b/drivers/mmc/core/core.h | |||
@@ -54,7 +54,9 @@ int mmc_attach_mmc(struct mmc_host *host, u32 ocr); | |||
54 | int mmc_attach_sd(struct mmc_host *host, u32 ocr); | 54 | int mmc_attach_sd(struct mmc_host *host, u32 ocr); |
55 | int mmc_attach_sdio(struct mmc_host *host, u32 ocr); | 55 | int mmc_attach_sdio(struct mmc_host *host, u32 ocr); |
56 | 56 | ||
57 | /* Module parameters */ | ||
57 | extern int use_spi_crc; | 58 | extern int use_spi_crc; |
59 | extern int mmc_assume_removable; | ||
58 | 60 | ||
59 | /* Debugfs information for hosts and cards */ | 61 | /* Debugfs information for hosts and cards */ |
60 | void mmc_add_host_debugfs(struct mmc_host *host); | 62 | void mmc_add_host_debugfs(struct mmc_host *host); |
diff --git a/drivers/mmc/core/debugfs.c b/drivers/mmc/core/debugfs.c index 96d10f40fb23..53cb380c0987 100644 --- a/drivers/mmc/core/debugfs.c +++ b/drivers/mmc/core/debugfs.c | |||
@@ -10,6 +10,7 @@ | |||
10 | #include <linux/debugfs.h> | 10 | #include <linux/debugfs.h> |
11 | #include <linux/fs.h> | 11 | #include <linux/fs.h> |
12 | #include <linux/seq_file.h> | 12 | #include <linux/seq_file.h> |
13 | #include <linux/slab.h> | ||
13 | #include <linux/stat.h> | 14 | #include <linux/stat.h> |
14 | 15 | ||
15 | #include <linux/mmc/card.h> | 16 | #include <linux/mmc/card.h> |
diff --git a/drivers/mmc/core/host.c b/drivers/mmc/core/host.c index a268d12f1af0..47353909e345 100644 --- a/drivers/mmc/core/host.c +++ b/drivers/mmc/core/host.c | |||
@@ -16,6 +16,7 @@ | |||
16 | #include <linux/idr.h> | 16 | #include <linux/idr.h> |
17 | #include <linux/pagemap.h> | 17 | #include <linux/pagemap.h> |
18 | #include <linux/leds.h> | 18 | #include <linux/leds.h> |
19 | #include <linux/slab.h> | ||
19 | 20 | ||
20 | #include <linux/mmc/host.h> | 21 | #include <linux/mmc/host.h> |
21 | 22 | ||
diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c index bfefce365ae7..89f7a25b7ac1 100644 --- a/drivers/mmc/core/mmc.c +++ b/drivers/mmc/core/mmc.c | |||
@@ -11,6 +11,7 @@ | |||
11 | */ | 11 | */ |
12 | 12 | ||
13 | #include <linux/err.h> | 13 | #include <linux/err.h> |
14 | #include <linux/slab.h> | ||
14 | 15 | ||
15 | #include <linux/mmc/host.h> | 16 | #include <linux/mmc/host.h> |
16 | #include <linux/mmc/card.h> | 17 | #include <linux/mmc/card.h> |
@@ -207,7 +208,7 @@ static int mmc_read_ext_csd(struct mmc_card *card) | |||
207 | } | 208 | } |
208 | 209 | ||
209 | card->ext_csd.rev = ext_csd[EXT_CSD_REV]; | 210 | card->ext_csd.rev = ext_csd[EXT_CSD_REV]; |
210 | if (card->ext_csd.rev > 3) { | 211 | if (card->ext_csd.rev > 5) { |
211 | printk(KERN_ERR "%s: unrecognised EXT_CSD structure " | 212 | printk(KERN_ERR "%s: unrecognised EXT_CSD structure " |
212 | "version %d\n", mmc_hostname(card->host), | 213 | "version %d\n", mmc_hostname(card->host), |
213 | card->ext_csd.rev); | 214 | card->ext_csd.rev); |
@@ -225,7 +226,7 @@ static int mmc_read_ext_csd(struct mmc_card *card) | |||
225 | mmc_card_set_blockaddr(card); | 226 | mmc_card_set_blockaddr(card); |
226 | } | 227 | } |
227 | 228 | ||
228 | switch (ext_csd[EXT_CSD_CARD_TYPE]) { | 229 | switch (ext_csd[EXT_CSD_CARD_TYPE] & EXT_CSD_CARD_TYPE_MASK) { |
229 | case EXT_CSD_CARD_TYPE_52 | EXT_CSD_CARD_TYPE_26: | 230 | case EXT_CSD_CARD_TYPE_52 | EXT_CSD_CARD_TYPE_26: |
230 | card->ext_csd.hs_max_dtr = 52000000; | 231 | card->ext_csd.hs_max_dtr = 52000000; |
231 | break; | 232 | break; |
@@ -237,7 +238,6 @@ static int mmc_read_ext_csd(struct mmc_card *card) | |||
237 | printk(KERN_WARNING "%s: card is mmc v4 but doesn't " | 238 | printk(KERN_WARNING "%s: card is mmc v4 but doesn't " |
238 | "support any high-speed modes.\n", | 239 | "support any high-speed modes.\n", |
239 | mmc_hostname(card->host)); | 240 | mmc_hostname(card->host)); |
240 | goto out; | ||
241 | } | 241 | } |
242 | 242 | ||
243 | if (card->ext_csd.rev >= 3) { | 243 | if (card->ext_csd.rev >= 3) { |
@@ -602,25 +602,6 @@ static int mmc_awake(struct mmc_host *host) | |||
602 | return err; | 602 | return err; |
603 | } | 603 | } |
604 | 604 | ||
605 | #ifdef CONFIG_MMC_UNSAFE_RESUME | ||
606 | |||
607 | static const struct mmc_bus_ops mmc_ops = { | ||
608 | .awake = mmc_awake, | ||
609 | .sleep = mmc_sleep, | ||
610 | .remove = mmc_remove, | ||
611 | .detect = mmc_detect, | ||
612 | .suspend = mmc_suspend, | ||
613 | .resume = mmc_resume, | ||
614 | .power_restore = mmc_power_restore, | ||
615 | }; | ||
616 | |||
617 | static void mmc_attach_bus_ops(struct mmc_host *host) | ||
618 | { | ||
619 | mmc_attach_bus(host, &mmc_ops); | ||
620 | } | ||
621 | |||
622 | #else | ||
623 | |||
624 | static const struct mmc_bus_ops mmc_ops = { | 605 | static const struct mmc_bus_ops mmc_ops = { |
625 | .awake = mmc_awake, | 606 | .awake = mmc_awake, |
626 | .sleep = mmc_sleep, | 607 | .sleep = mmc_sleep, |
@@ -645,15 +626,13 @@ static void mmc_attach_bus_ops(struct mmc_host *host) | |||
645 | { | 626 | { |
646 | const struct mmc_bus_ops *bus_ops; | 627 | const struct mmc_bus_ops *bus_ops; |
647 | 628 | ||
648 | if (host->caps & MMC_CAP_NONREMOVABLE) | 629 | if (host->caps & MMC_CAP_NONREMOVABLE || !mmc_assume_removable) |
649 | bus_ops = &mmc_ops_unsafe; | 630 | bus_ops = &mmc_ops_unsafe; |
650 | else | 631 | else |
651 | bus_ops = &mmc_ops; | 632 | bus_ops = &mmc_ops; |
652 | mmc_attach_bus(host, bus_ops); | 633 | mmc_attach_bus(host, bus_ops); |
653 | } | 634 | } |
654 | 635 | ||
655 | #endif | ||
656 | |||
657 | /* | 636 | /* |
658 | * Starting point for MMC card init. | 637 | * Starting point for MMC card init. |
659 | */ | 638 | */ |
diff --git a/drivers/mmc/core/mmc_ops.c b/drivers/mmc/core/mmc_ops.c index d2cb5c634392..326447c9ede8 100644 --- a/drivers/mmc/core/mmc_ops.c +++ b/drivers/mmc/core/mmc_ops.c | |||
@@ -9,6 +9,7 @@ | |||
9 | * your option) any later version. | 9 | * your option) any later version. |
10 | */ | 10 | */ |
11 | 11 | ||
12 | #include <linux/slab.h> | ||
12 | #include <linux/types.h> | 13 | #include <linux/types.h> |
13 | #include <linux/scatterlist.h> | 14 | #include <linux/scatterlist.h> |
14 | 15 | ||
diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c index 10b2a4d20f5a..5eac21df4809 100644 --- a/drivers/mmc/core/sd.c +++ b/drivers/mmc/core/sd.c | |||
@@ -11,6 +11,7 @@ | |||
11 | */ | 11 | */ |
12 | 12 | ||
13 | #include <linux/err.h> | 13 | #include <linux/err.h> |
14 | #include <linux/slab.h> | ||
14 | 15 | ||
15 | #include <linux/mmc/host.h> | 16 | #include <linux/mmc/host.h> |
16 | #include <linux/mmc/card.h> | 17 | #include <linux/mmc/card.h> |
@@ -606,23 +607,6 @@ static void mmc_sd_power_restore(struct mmc_host *host) | |||
606 | mmc_release_host(host); | 607 | mmc_release_host(host); |
607 | } | 608 | } |
608 | 609 | ||
609 | #ifdef CONFIG_MMC_UNSAFE_RESUME | ||
610 | |||
611 | static const struct mmc_bus_ops mmc_sd_ops = { | ||
612 | .remove = mmc_sd_remove, | ||
613 | .detect = mmc_sd_detect, | ||
614 | .suspend = mmc_sd_suspend, | ||
615 | .resume = mmc_sd_resume, | ||
616 | .power_restore = mmc_sd_power_restore, | ||
617 | }; | ||
618 | |||
619 | static void mmc_sd_attach_bus_ops(struct mmc_host *host) | ||
620 | { | ||
621 | mmc_attach_bus(host, &mmc_sd_ops); | ||
622 | } | ||
623 | |||
624 | #else | ||
625 | |||
626 | static const struct mmc_bus_ops mmc_sd_ops = { | 610 | static const struct mmc_bus_ops mmc_sd_ops = { |
627 | .remove = mmc_sd_remove, | 611 | .remove = mmc_sd_remove, |
628 | .detect = mmc_sd_detect, | 612 | .detect = mmc_sd_detect, |
@@ -643,15 +627,13 @@ static void mmc_sd_attach_bus_ops(struct mmc_host *host) | |||
643 | { | 627 | { |
644 | const struct mmc_bus_ops *bus_ops; | 628 | const struct mmc_bus_ops *bus_ops; |
645 | 629 | ||
646 | if (host->caps & MMC_CAP_NONREMOVABLE) | 630 | if (host->caps & MMC_CAP_NONREMOVABLE || !mmc_assume_removable) |
647 | bus_ops = &mmc_sd_ops_unsafe; | 631 | bus_ops = &mmc_sd_ops_unsafe; |
648 | else | 632 | else |
649 | bus_ops = &mmc_sd_ops; | 633 | bus_ops = &mmc_sd_ops; |
650 | mmc_attach_bus(host, bus_ops); | 634 | mmc_attach_bus(host, bus_ops); |
651 | } | 635 | } |
652 | 636 | ||
653 | #endif | ||
654 | |||
655 | /* | 637 | /* |
656 | * Starting point for SD card init. | 638 | * Starting point for SD card init. |
657 | */ | 639 | */ |
diff --git a/drivers/mmc/core/sdio.c b/drivers/mmc/core/sdio.c index cdb845b68ab5..2dd4cfe7ca17 100644 --- a/drivers/mmc/core/sdio.c +++ b/drivers/mmc/core/sdio.c | |||
@@ -188,6 +188,40 @@ static int sdio_disable_cd(struct mmc_card *card) | |||
188 | } | 188 | } |
189 | 189 | ||
190 | /* | 190 | /* |
191 | * Devices that remain active during a system suspend are | ||
192 | * put back into 1-bit mode. | ||
193 | */ | ||
194 | static int sdio_disable_wide(struct mmc_card *card) | ||
195 | { | ||
196 | int ret; | ||
197 | u8 ctrl; | ||
198 | |||
199 | if (!(card->host->caps & MMC_CAP_4_BIT_DATA)) | ||
200 | return 0; | ||
201 | |||
202 | if (card->cccr.low_speed && !card->cccr.wide_bus) | ||
203 | return 0; | ||
204 | |||
205 | ret = mmc_io_rw_direct(card, 0, 0, SDIO_CCCR_IF, 0, &ctrl); | ||
206 | if (ret) | ||
207 | return ret; | ||
208 | |||
209 | if (!(ctrl & SDIO_BUS_WIDTH_4BIT)) | ||
210 | return 0; | ||
211 | |||
212 | ctrl &= ~SDIO_BUS_WIDTH_4BIT; | ||
213 | ctrl |= SDIO_BUS_ASYNC_INT; | ||
214 | |||
215 | ret = mmc_io_rw_direct(card, 1, 0, SDIO_CCCR_IF, ctrl, NULL); | ||
216 | if (ret) | ||
217 | return ret; | ||
218 | |||
219 | mmc_set_bus_width(card->host, MMC_BUS_WIDTH_1); | ||
220 | |||
221 | return 0; | ||
222 | } | ||
223 | |||
224 | /* | ||
191 | * Test if the card supports high-speed mode and, if so, switch to it. | 225 | * Test if the card supports high-speed mode and, if so, switch to it. |
192 | */ | 226 | */ |
193 | static int sdio_enable_hs(struct mmc_card *card) | 227 | static int sdio_enable_hs(struct mmc_card *card) |
@@ -224,7 +258,7 @@ static int sdio_enable_hs(struct mmc_card *card) | |||
224 | * we're trying to reinitialise. | 258 | * we're trying to reinitialise. |
225 | */ | 259 | */ |
226 | static int mmc_sdio_init_card(struct mmc_host *host, u32 ocr, | 260 | static int mmc_sdio_init_card(struct mmc_host *host, u32 ocr, |
227 | struct mmc_card *oldcard) | 261 | struct mmc_card *oldcard, int powered_resume) |
228 | { | 262 | { |
229 | struct mmc_card *card; | 263 | struct mmc_card *card; |
230 | int err; | 264 | int err; |
@@ -235,9 +269,11 @@ static int mmc_sdio_init_card(struct mmc_host *host, u32 ocr, | |||
235 | /* | 269 | /* |
236 | * Inform the card of the voltage | 270 | * Inform the card of the voltage |
237 | */ | 271 | */ |
238 | err = mmc_send_io_op_cond(host, host->ocr, &ocr); | 272 | if (!powered_resume) { |
239 | if (err) | 273 | err = mmc_send_io_op_cond(host, host->ocr, &ocr); |
240 | goto err; | 274 | if (err) |
275 | goto err; | ||
276 | } | ||
241 | 277 | ||
242 | /* | 278 | /* |
243 | * For SPI, enable CRC as appropriate. | 279 | * For SPI, enable CRC as appropriate. |
@@ -262,7 +298,7 @@ static int mmc_sdio_init_card(struct mmc_host *host, u32 ocr, | |||
262 | /* | 298 | /* |
263 | * For native busses: set card RCA and quit open drain mode. | 299 | * For native busses: set card RCA and quit open drain mode. |
264 | */ | 300 | */ |
265 | if (!mmc_host_is_spi(host)) { | 301 | if (!powered_resume && !mmc_host_is_spi(host)) { |
266 | err = mmc_send_relative_addr(host, &card->rca); | 302 | err = mmc_send_relative_addr(host, &card->rca); |
267 | if (err) | 303 | if (err) |
268 | goto remove; | 304 | goto remove; |
@@ -273,7 +309,7 @@ static int mmc_sdio_init_card(struct mmc_host *host, u32 ocr, | |||
273 | /* | 309 | /* |
274 | * Select card, as all following commands rely on that. | 310 | * Select card, as all following commands rely on that. |
275 | */ | 311 | */ |
276 | if (!mmc_host_is_spi(host)) { | 312 | if (!powered_resume && !mmc_host_is_spi(host)) { |
277 | err = mmc_select_card(card); | 313 | err = mmc_select_card(card); |
278 | if (err) | 314 | if (err) |
279 | goto remove; | 315 | goto remove; |
@@ -425,6 +461,12 @@ static int mmc_sdio_suspend(struct mmc_host *host) | |||
425 | } | 461 | } |
426 | } | 462 | } |
427 | 463 | ||
464 | if (!err && host->pm_flags & MMC_PM_KEEP_POWER) { | ||
465 | mmc_claim_host(host); | ||
466 | sdio_disable_wide(host->card); | ||
467 | mmc_release_host(host); | ||
468 | } | ||
469 | |||
428 | return err; | 470 | return err; |
429 | } | 471 | } |
430 | 472 | ||
@@ -437,7 +479,13 @@ static int mmc_sdio_resume(struct mmc_host *host) | |||
437 | 479 | ||
438 | /* Basic card reinitialization. */ | 480 | /* Basic card reinitialization. */ |
439 | mmc_claim_host(host); | 481 | mmc_claim_host(host); |
440 | err = mmc_sdio_init_card(host, host->ocr, host->card); | 482 | err = mmc_sdio_init_card(host, host->ocr, host->card, |
483 | (host->pm_flags & MMC_PM_KEEP_POWER)); | ||
484 | if (!err) | ||
485 | /* We may have switched to 1-bit mode during suspend. */ | ||
486 | err = sdio_enable_wide(host->card); | ||
487 | if (!err && host->sdio_irqs) | ||
488 | mmc_signal_sdio_irq(host); | ||
441 | mmc_release_host(host); | 489 | mmc_release_host(host); |
442 | 490 | ||
443 | /* | 491 | /* |
@@ -507,7 +555,7 @@ int mmc_attach_sdio(struct mmc_host *host, u32 ocr) | |||
507 | /* | 555 | /* |
508 | * Detect and init the card. | 556 | * Detect and init the card. |
509 | */ | 557 | */ |
510 | err = mmc_sdio_init_card(host, host->ocr, NULL); | 558 | err = mmc_sdio_init_card(host, host->ocr, NULL, 0); |
511 | if (err) | 559 | if (err) |
512 | goto err; | 560 | goto err; |
513 | card = host->card; | 561 | card = host->card; |
@@ -516,7 +564,8 @@ int mmc_attach_sdio(struct mmc_host *host, u32 ocr) | |||
516 | * The number of functions on the card is encoded inside | 564 | * The number of functions on the card is encoded inside |
517 | * the ocr. | 565 | * the ocr. |
518 | */ | 566 | */ |
519 | card->sdio_funcs = funcs = (ocr & 0x70000000) >> 28; | 567 | funcs = (ocr & 0x70000000) >> 28; |
568 | card->sdio_funcs = 0; | ||
520 | 569 | ||
521 | /* | 570 | /* |
522 | * If needed, disconnect card detection pull-up resistor. | 571 | * If needed, disconnect card detection pull-up resistor. |
@@ -528,7 +577,7 @@ int mmc_attach_sdio(struct mmc_host *host, u32 ocr) | |||
528 | /* | 577 | /* |
529 | * Initialize (but don't add) all present functions. | 578 | * Initialize (but don't add) all present functions. |
530 | */ | 579 | */ |
531 | for (i = 0;i < funcs;i++) { | 580 | for (i = 0; i < funcs; i++, card->sdio_funcs++) { |
532 | err = sdio_init_func(host->card, i + 1); | 581 | err = sdio_init_func(host->card, i + 1); |
533 | if (err) | 582 | if (err) |
534 | goto remove; | 583 | goto remove; |
diff --git a/drivers/mmc/core/sdio_bus.c b/drivers/mmc/core/sdio_bus.c index d37464e296a5..4a890dcb95ab 100644 --- a/drivers/mmc/core/sdio_bus.c +++ b/drivers/mmc/core/sdio_bus.c | |||
@@ -13,6 +13,7 @@ | |||
13 | 13 | ||
14 | #include <linux/device.h> | 14 | #include <linux/device.h> |
15 | #include <linux/err.h> | 15 | #include <linux/err.h> |
16 | #include <linux/slab.h> | ||
16 | 17 | ||
17 | #include <linux/mmc/card.h> | 18 | #include <linux/mmc/card.h> |
18 | #include <linux/mmc/sdio_func.h> | 19 | #include <linux/mmc/sdio_func.h> |
@@ -248,12 +249,15 @@ int sdio_add_func(struct sdio_func *func) | |||
248 | /* | 249 | /* |
249 | * Unregister a SDIO function with the driver model, and | 250 | * Unregister a SDIO function with the driver model, and |
250 | * (eventually) free it. | 251 | * (eventually) free it. |
252 | * This function can be called through error paths where sdio_add_func() was | ||
253 | * never executed (because a failure occurred at an earlier point). | ||
251 | */ | 254 | */ |
252 | void sdio_remove_func(struct sdio_func *func) | 255 | void sdio_remove_func(struct sdio_func *func) |
253 | { | 256 | { |
254 | if (sdio_func_present(func)) | 257 | if (!sdio_func_present(func)) |
255 | device_del(&func->dev); | 258 | return; |
256 | 259 | ||
260 | device_del(&func->dev); | ||
257 | put_device(&func->dev); | 261 | put_device(&func->dev); |
258 | } | 262 | } |
259 | 263 | ||
diff --git a/drivers/mmc/core/sdio_cis.c b/drivers/mmc/core/sdio_cis.c index f85dcd536508..541bdb89e0c5 100644 --- a/drivers/mmc/core/sdio_cis.c +++ b/drivers/mmc/core/sdio_cis.c | |||
@@ -14,6 +14,7 @@ | |||
14 | */ | 14 | */ |
15 | 15 | ||
16 | #include <linux/kernel.h> | 16 | #include <linux/kernel.h> |
17 | #include <linux/slab.h> | ||
17 | 18 | ||
18 | #include <linux/mmc/host.h> | 19 | #include <linux/mmc/host.h> |
19 | #include <linux/mmc/card.h> | 20 | #include <linux/mmc/card.h> |
@@ -97,26 +98,56 @@ static const unsigned char speed_val[16] = | |||
97 | static const unsigned int speed_unit[8] = | 98 | static const unsigned int speed_unit[8] = |
98 | { 10000, 100000, 1000000, 10000000, 0, 0, 0, 0 }; | 99 | { 10000, 100000, 1000000, 10000000, 0, 0, 0, 0 }; |
99 | 100 | ||
100 | /* FUNCE tuples with these types get passed to SDIO drivers */ | 101 | |
101 | static const unsigned char funce_type_whitelist[] = { | 102 | typedef int (tpl_parse_t)(struct mmc_card *, struct sdio_func *, |
102 | 4 /* CISTPL_FUNCE_LAN_NODE_ID used in Broadcom cards */ | 103 | const unsigned char *, unsigned); |
104 | |||
105 | struct cis_tpl { | ||
106 | unsigned char code; | ||
107 | unsigned char min_size; | ||
108 | tpl_parse_t *parse; | ||
103 | }; | 109 | }; |
104 | 110 | ||
105 | static int cistpl_funce_whitelisted(unsigned char type) | 111 | static int cis_tpl_parse(struct mmc_card *card, struct sdio_func *func, |
112 | const char *tpl_descr, | ||
113 | const struct cis_tpl *tpl, int tpl_count, | ||
114 | unsigned char code, | ||
115 | const unsigned char *buf, unsigned size) | ||
106 | { | 116 | { |
107 | int i; | 117 | int i, ret; |
108 | 118 | ||
109 | for (i = 0; i < ARRAY_SIZE(funce_type_whitelist); i++) { | 119 | /* look for a matching code in the table */ |
110 | if (funce_type_whitelist[i] == type) | 120 | for (i = 0; i < tpl_count; i++, tpl++) { |
111 | return 1; | 121 | if (tpl->code == code) |
122 | break; | ||
112 | } | 123 | } |
113 | return 0; | 124 | if (i < tpl_count) { |
125 | if (size >= tpl->min_size) { | ||
126 | if (tpl->parse) | ||
127 | ret = tpl->parse(card, func, buf, size); | ||
128 | else | ||
129 | ret = -EILSEQ; /* known tuple, not parsed */ | ||
130 | } else { | ||
131 | /* invalid tuple */ | ||
132 | ret = -EINVAL; | ||
133 | } | ||
134 | if (ret && ret != -EILSEQ && ret != -ENOENT) { | ||
135 | printk(KERN_ERR "%s: bad %s tuple 0x%02x (%u bytes)\n", | ||
136 | mmc_hostname(card->host), tpl_descr, code, size); | ||
137 | } | ||
138 | } else { | ||
139 | /* unknown tuple */ | ||
140 | ret = -ENOENT; | ||
141 | } | ||
142 | |||
143 | return ret; | ||
114 | } | 144 | } |
115 | 145 | ||
116 | static int cistpl_funce_common(struct mmc_card *card, | 146 | static int cistpl_funce_common(struct mmc_card *card, struct sdio_func *func, |
117 | const unsigned char *buf, unsigned size) | 147 | const unsigned char *buf, unsigned size) |
118 | { | 148 | { |
119 | if (size < 0x04 || buf[0] != 0) | 149 | /* Only valid for the common CIS (function 0) */ |
150 | if (func) | ||
120 | return -EINVAL; | 151 | return -EINVAL; |
121 | 152 | ||
122 | /* TPLFE_FN0_BLK_SIZE */ | 153 | /* TPLFE_FN0_BLK_SIZE */ |
@@ -129,20 +160,24 @@ static int cistpl_funce_common(struct mmc_card *card, | |||
129 | return 0; | 160 | return 0; |
130 | } | 161 | } |
131 | 162 | ||
132 | static int cistpl_funce_func(struct sdio_func *func, | 163 | static int cistpl_funce_func(struct mmc_card *card, struct sdio_func *func, |
133 | const unsigned char *buf, unsigned size) | 164 | const unsigned char *buf, unsigned size) |
134 | { | 165 | { |
135 | unsigned vsn; | 166 | unsigned vsn; |
136 | unsigned min_size; | 167 | unsigned min_size; |
137 | 168 | ||
138 | /* let SDIO drivers take care of whitelisted FUNCE tuples */ | 169 | /* Only valid for the individual function's CIS (1-7) */ |
139 | if (cistpl_funce_whitelisted(buf[0])) | 170 | if (!func) |
140 | return -EILSEQ; | 171 | return -EINVAL; |
141 | 172 | ||
173 | /* | ||
174 | * This tuple has a different length depending on the SDIO spec | ||
175 | * version. | ||
176 | */ | ||
142 | vsn = func->card->cccr.sdio_vsn; | 177 | vsn = func->card->cccr.sdio_vsn; |
143 | min_size = (vsn == SDIO_SDIO_REV_1_00) ? 28 : 42; | 178 | min_size = (vsn == SDIO_SDIO_REV_1_00) ? 28 : 42; |
144 | 179 | ||
145 | if (size < min_size || buf[0] != 1) | 180 | if (size < min_size) |
146 | return -EINVAL; | 181 | return -EINVAL; |
147 | 182 | ||
148 | /* TPLFE_MAX_BLK_SIZE */ | 183 | /* TPLFE_MAX_BLK_SIZE */ |
@@ -157,39 +192,32 @@ static int cistpl_funce_func(struct sdio_func *func, | |||
157 | return 0; | 192 | return 0; |
158 | } | 193 | } |
159 | 194 | ||
195 | /* | ||
196 | * Known TPLFE_TYPEs table for CISTPL_FUNCE tuples. | ||
197 | * | ||
198 | * Note that, unlike PCMCIA, CISTPL_FUNCE tuples are not parsed depending | ||
199 | * on the TPLFID_FUNCTION value of the previous CISTPL_FUNCID as on SDIO | ||
200 | * TPLFID_FUNCTION is always hardcoded to 0x0C. | ||
201 | */ | ||
202 | static const struct cis_tpl cis_tpl_funce_list[] = { | ||
203 | { 0x00, 4, cistpl_funce_common }, | ||
204 | { 0x01, 0, cistpl_funce_func }, | ||
205 | { 0x04, 1+1+6, /* CISTPL_FUNCE_LAN_NODE_ID */ }, | ||
206 | }; | ||
207 | |||
160 | static int cistpl_funce(struct mmc_card *card, struct sdio_func *func, | 208 | static int cistpl_funce(struct mmc_card *card, struct sdio_func *func, |
161 | const unsigned char *buf, unsigned size) | 209 | const unsigned char *buf, unsigned size) |
162 | { | 210 | { |
163 | int ret; | 211 | if (size < 1) |
164 | 212 | return -EINVAL; | |
165 | /* | ||
166 | * There should be two versions of the CISTPL_FUNCE tuple, | ||
167 | * one for the common CIS (function 0) and a version used by | ||
168 | * the individual function's CIS (1-7). Yet, the later has a | ||
169 | * different length depending on the SDIO spec version. | ||
170 | */ | ||
171 | if (func) | ||
172 | ret = cistpl_funce_func(func, buf, size); | ||
173 | else | ||
174 | ret = cistpl_funce_common(card, buf, size); | ||
175 | |||
176 | if (ret && ret != -EILSEQ) { | ||
177 | printk(KERN_ERR "%s: bad CISTPL_FUNCE size %u " | ||
178 | "type %u\n", mmc_hostname(card->host), size, buf[0]); | ||
179 | } | ||
180 | 213 | ||
181 | return ret; | 214 | return cis_tpl_parse(card, func, "CISTPL_FUNCE", |
215 | cis_tpl_funce_list, | ||
216 | ARRAY_SIZE(cis_tpl_funce_list), | ||
217 | buf[0], buf, size); | ||
182 | } | 218 | } |
183 | 219 | ||
184 | typedef int (tpl_parse_t)(struct mmc_card *, struct sdio_func *, | 220 | /* Known TPL_CODEs table for CIS tuples */ |
185 | const unsigned char *, unsigned); | ||
186 | |||
187 | struct cis_tpl { | ||
188 | unsigned char code; | ||
189 | unsigned char min_size; | ||
190 | tpl_parse_t *parse; | ||
191 | }; | ||
192 | |||
193 | static const struct cis_tpl cis_tpl_list[] = { | 221 | static const struct cis_tpl cis_tpl_list[] = { |
194 | { 0x15, 3, cistpl_vers_1 }, | 222 | { 0x15, 3, cistpl_vers_1 }, |
195 | { 0x20, 4, cistpl_manfid }, | 223 | { 0x20, 4, cistpl_manfid }, |
@@ -268,46 +296,38 @@ static int sdio_read_cis(struct mmc_card *card, struct sdio_func *func) | |||
268 | break; | 296 | break; |
269 | } | 297 | } |
270 | 298 | ||
271 | for (i = 0; i < ARRAY_SIZE(cis_tpl_list); i++) | 299 | /* Try to parse the CIS tuple */ |
272 | if (cis_tpl_list[i].code == tpl_code) | 300 | ret = cis_tpl_parse(card, func, "CIS", |
273 | break; | 301 | cis_tpl_list, ARRAY_SIZE(cis_tpl_list), |
274 | if (i < ARRAY_SIZE(cis_tpl_list)) { | 302 | tpl_code, this->data, tpl_link); |
275 | const struct cis_tpl *tpl = cis_tpl_list + i; | 303 | if (ret == -EILSEQ || ret == -ENOENT) { |
276 | if (tpl_link < tpl->min_size) { | ||
277 | printk(KERN_ERR | ||
278 | "%s: bad CIS tuple 0x%02x" | ||
279 | " (length = %u, expected >= %u)\n", | ||
280 | mmc_hostname(card->host), | ||
281 | tpl_code, tpl_link, tpl->min_size); | ||
282 | ret = -EINVAL; | ||
283 | } else if (tpl->parse) { | ||
284 | ret = tpl->parse(card, func, | ||
285 | this->data, tpl_link); | ||
286 | } | ||
287 | /* | 304 | /* |
288 | * We don't need the tuple anymore if it was | 305 | * The tuple is unknown or known but not parsed. |
289 | * successfully parsed by the SDIO core or if it is | 306 | * Queue the tuple for the function driver. |
290 | * not going to be parsed by SDIO drivers. | ||
291 | */ | 307 | */ |
292 | if (!ret || ret != -EILSEQ) | ||
293 | kfree(this); | ||
294 | } else { | ||
295 | /* unknown tuple */ | ||
296 | ret = -EILSEQ; | ||
297 | } | ||
298 | |||
299 | if (ret == -EILSEQ) { | ||
300 | /* this tuple is unknown to the core or whitelisted */ | ||
301 | this->next = NULL; | 308 | this->next = NULL; |
302 | this->code = tpl_code; | 309 | this->code = tpl_code; |
303 | this->size = tpl_link; | 310 | this->size = tpl_link; |
304 | *prev = this; | 311 | *prev = this; |
305 | prev = &this->next; | 312 | prev = &this->next; |
306 | printk(KERN_DEBUG | 313 | |
307 | "%s: queuing CIS tuple 0x%02x length %u\n", | 314 | if (ret == -ENOENT) { |
308 | mmc_hostname(card->host), tpl_code, tpl_link); | 315 | /* warn about unknown tuples */ |
316 | printk(KERN_WARNING "%s: queuing unknown" | ||
317 | " CIS tuple 0x%02x (%u bytes)\n", | ||
318 | mmc_hostname(card->host), | ||
319 | tpl_code, tpl_link); | ||
320 | } | ||
321 | |||
309 | /* keep on analyzing tuples */ | 322 | /* keep on analyzing tuples */ |
310 | ret = 0; | 323 | ret = 0; |
324 | } else { | ||
325 | /* | ||
326 | * We don't need the tuple anymore if it was | ||
327 | * successfully parsed by the SDIO core or if it is | ||
328 | * not going to be queued for a driver. | ||
329 | */ | ||
330 | kfree(this); | ||
311 | } | 331 | } |
312 | 332 | ||
313 | ptr += tpl_link; | 333 | ptr += tpl_link; |
diff --git a/drivers/mmc/core/sdio_io.c b/drivers/mmc/core/sdio_io.c index f9aa8a7deffa..ff27c8c71355 100644 --- a/drivers/mmc/core/sdio_io.c +++ b/drivers/mmc/core/sdio_io.c | |||
@@ -189,7 +189,12 @@ static inline unsigned int sdio_max_byte_size(struct sdio_func *func) | |||
189 | { | 189 | { |
190 | unsigned mval = min(func->card->host->max_seg_size, | 190 | unsigned mval = min(func->card->host->max_seg_size, |
191 | func->card->host->max_blk_size); | 191 | func->card->host->max_blk_size); |
192 | mval = min(mval, func->max_blksize); | 192 | |
193 | if (mmc_blksz_for_byte_mode(func->card)) | ||
194 | mval = min(mval, func->cur_blksize); | ||
195 | else | ||
196 | mval = min(mval, func->max_blksize); | ||
197 | |||
193 | return min(mval, 512u); /* maximum size for byte mode */ | 198 | return min(mval, 512u); /* maximum size for byte mode */ |
194 | } | 199 | } |
195 | 200 | ||
@@ -635,3 +640,52 @@ void sdio_f0_writeb(struct sdio_func *func, unsigned char b, unsigned int addr, | |||
635 | *err_ret = ret; | 640 | *err_ret = ret; |
636 | } | 641 | } |
637 | EXPORT_SYMBOL_GPL(sdio_f0_writeb); | 642 | EXPORT_SYMBOL_GPL(sdio_f0_writeb); |
643 | |||
644 | /** | ||
645 | * sdio_get_host_pm_caps - get host power management capabilities | ||
646 | * @func: SDIO function attached to host | ||
647 | * | ||
648 | * Returns a capability bitmask corresponding to power management | ||
649 | * features supported by the host controller that the card function | ||
650 | * might rely upon during a system suspend. The host doesn't need | ||
651 | * to be claimed, nor the function active, for this information to be | ||
652 | * obtained. | ||
653 | */ | ||
654 | mmc_pm_flag_t sdio_get_host_pm_caps(struct sdio_func *func) | ||
655 | { | ||
656 | BUG_ON(!func); | ||
657 | BUG_ON(!func->card); | ||
658 | |||
659 | return func->card->host->pm_caps; | ||
660 | } | ||
661 | EXPORT_SYMBOL_GPL(sdio_get_host_pm_caps); | ||
662 | |||
663 | /** | ||
664 | * sdio_set_host_pm_flags - set wanted host power management capabilities | ||
665 | * @func: SDIO function attached to host | ||
666 | * | ||
667 | * Set a capability bitmask corresponding to wanted host controller | ||
668 | * power management features for the upcoming suspend state. | ||
669 | * This must be called, if needed, each time the suspend method of | ||
670 | * the function driver is called, and must contain only bits that | ||
671 | * were returned by sdio_get_host_pm_caps(). | ||
672 | * The host doesn't need to be claimed, nor the function active, | ||
673 | * for this information to be set. | ||
674 | */ | ||
675 | int sdio_set_host_pm_flags(struct sdio_func *func, mmc_pm_flag_t flags) | ||
676 | { | ||
677 | struct mmc_host *host; | ||
678 | |||
679 | BUG_ON(!func); | ||
680 | BUG_ON(!func->card); | ||
681 | |||
682 | host = func->card->host; | ||
683 | |||
684 | if (flags & ~host->pm_caps) | ||
685 | return -EINVAL; | ||
686 | |||
687 | /* function suspend methods are serialized, hence no lock needed */ | ||
688 | host->pm_flags |= flags; | ||
689 | return 0; | ||
690 | } | ||
691 | EXPORT_SYMBOL_GPL(sdio_set_host_pm_flags); | ||
diff --git a/drivers/mmc/core/sdio_ops.c b/drivers/mmc/core/sdio_ops.c index 4eb7825fd1a7..dea36d9c22e6 100644 --- a/drivers/mmc/core/sdio_ops.c +++ b/drivers/mmc/core/sdio_ops.c | |||
@@ -67,13 +67,13 @@ int mmc_send_io_op_cond(struct mmc_host *host, u32 ocr, u32 *rocr) | |||
67 | return err; | 67 | return err; |
68 | } | 68 | } |
69 | 69 | ||
70 | int mmc_io_rw_direct(struct mmc_card *card, int write, unsigned fn, | 70 | static int mmc_io_rw_direct_host(struct mmc_host *host, int write, unsigned fn, |
71 | unsigned addr, u8 in, u8* out) | 71 | unsigned addr, u8 in, u8 *out) |
72 | { | 72 | { |
73 | struct mmc_command cmd; | 73 | struct mmc_command cmd; |
74 | int err; | 74 | int err; |
75 | 75 | ||
76 | BUG_ON(!card); | 76 | BUG_ON(!host); |
77 | BUG_ON(fn > 7); | 77 | BUG_ON(fn > 7); |
78 | 78 | ||
79 | /* sanity check */ | 79 | /* sanity check */ |
@@ -90,11 +90,11 @@ int mmc_io_rw_direct(struct mmc_card *card, int write, unsigned fn, | |||
90 | cmd.arg |= in; | 90 | cmd.arg |= in; |
91 | cmd.flags = MMC_RSP_SPI_R5 | MMC_RSP_R5 | MMC_CMD_AC; | 91 | cmd.flags = MMC_RSP_SPI_R5 | MMC_RSP_R5 | MMC_CMD_AC; |
92 | 92 | ||
93 | err = mmc_wait_for_cmd(card->host, &cmd, 0); | 93 | err = mmc_wait_for_cmd(host, &cmd, 0); |
94 | if (err) | 94 | if (err) |
95 | return err; | 95 | return err; |
96 | 96 | ||
97 | if (mmc_host_is_spi(card->host)) { | 97 | if (mmc_host_is_spi(host)) { |
98 | /* host driver already reported errors */ | 98 | /* host driver already reported errors */ |
99 | } else { | 99 | } else { |
100 | if (cmd.resp[0] & R5_ERROR) | 100 | if (cmd.resp[0] & R5_ERROR) |
@@ -106,7 +106,7 @@ int mmc_io_rw_direct(struct mmc_card *card, int write, unsigned fn, | |||
106 | } | 106 | } |
107 | 107 | ||
108 | if (out) { | 108 | if (out) { |
109 | if (mmc_host_is_spi(card->host)) | 109 | if (mmc_host_is_spi(host)) |
110 | *out = (cmd.resp[0] >> 8) & 0xFF; | 110 | *out = (cmd.resp[0] >> 8) & 0xFF; |
111 | else | 111 | else |
112 | *out = cmd.resp[0] & 0xFF; | 112 | *out = cmd.resp[0] & 0xFF; |
@@ -115,6 +115,13 @@ int mmc_io_rw_direct(struct mmc_card *card, int write, unsigned fn, | |||
115 | return 0; | 115 | return 0; |
116 | } | 116 | } |
117 | 117 | ||
118 | int mmc_io_rw_direct(struct mmc_card *card, int write, unsigned fn, | ||
119 | unsigned addr, u8 in, u8 *out) | ||
120 | { | ||
121 | BUG_ON(!card); | ||
122 | return mmc_io_rw_direct_host(card->host, write, fn, addr, in, out); | ||
123 | } | ||
124 | |||
118 | int mmc_io_rw_extended(struct mmc_card *card, int write, unsigned fn, | 125 | int mmc_io_rw_extended(struct mmc_card *card, int write, unsigned fn, |
119 | unsigned addr, int incr_addr, u8 *buf, unsigned blocks, unsigned blksz) | 126 | unsigned addr, int incr_addr, u8 *buf, unsigned blocks, unsigned blksz) |
120 | { | 127 | { |
@@ -182,3 +189,20 @@ int mmc_io_rw_extended(struct mmc_card *card, int write, unsigned fn, | |||
182 | return 0; | 189 | return 0; |
183 | } | 190 | } |
184 | 191 | ||
192 | int sdio_reset(struct mmc_host *host) | ||
193 | { | ||
194 | int ret; | ||
195 | u8 abort; | ||
196 | |||
197 | /* SDIO Simplified Specification V2.0, 4.4 Reset for SDIO */ | ||
198 | |||
199 | ret = mmc_io_rw_direct_host(host, 0, 0, SDIO_CCCR_ABORT, 0, &abort); | ||
200 | if (ret) | ||
201 | abort = 0x08; | ||
202 | else | ||
203 | abort |= 0x08; | ||
204 | |||
205 | ret = mmc_io_rw_direct_host(host, 1, 0, SDIO_CCCR_ABORT, abort, NULL); | ||
206 | return ret; | ||
207 | } | ||
208 | |||
diff --git a/drivers/mmc/core/sdio_ops.h b/drivers/mmc/core/sdio_ops.h index e2e74b0d17d8..12a4d3ab174c 100644 --- a/drivers/mmc/core/sdio_ops.h +++ b/drivers/mmc/core/sdio_ops.h | |||
@@ -17,6 +17,7 @@ int mmc_io_rw_direct(struct mmc_card *card, int write, unsigned fn, | |||
17 | unsigned addr, u8 in, u8* out); | 17 | unsigned addr, u8 in, u8* out); |
18 | int mmc_io_rw_extended(struct mmc_card *card, int write, unsigned fn, | 18 | int mmc_io_rw_extended(struct mmc_card *card, int write, unsigned fn, |
19 | unsigned addr, int incr_addr, u8 *buf, unsigned blocks, unsigned blksz); | 19 | unsigned addr, int incr_addr, u8 *buf, unsigned blocks, unsigned blksz); |
20 | int sdio_reset(struct mmc_host *host); | ||
20 | 21 | ||
21 | #endif | 22 | #endif |
22 | 23 | ||
diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig index 432ae8358c86..2e13b94769fd 100644 --- a/drivers/mmc/host/Kconfig +++ b/drivers/mmc/host/Kconfig | |||
@@ -44,6 +44,19 @@ config MMC_SDHCI_IO_ACCESSORS | |||
44 | This is silent Kconfig symbol that is selected by the drivers that | 44 | This is silent Kconfig symbol that is selected by the drivers that |
45 | need to overwrite SDHCI IO memory accessors. | 45 | need to overwrite SDHCI IO memory accessors. |
46 | 46 | ||
47 | config MMC_SDHCI_BIG_ENDIAN_32BIT_BYTE_SWAPPER | ||
48 | bool | ||
49 | select MMC_SDHCI_IO_ACCESSORS | ||
50 | help | ||
51 | This option is selected by drivers running on big endian hosts | ||
52 | and performing I/O to a SDHCI controller through a bus that | ||
53 | implements a hardware byte swapper using a 32-bit datum. | ||
54 | This endian mapping mode is called "data invariance" and | ||
55 | has the effect of scrambling the addresses and formats of data | ||
56 | accessed in sizes other than the datum size. | ||
57 | |||
58 | This is the case for the Freescale eSDHC and Nintendo Wii SDHCI. | ||
59 | |||
47 | config MMC_SDHCI_PCI | 60 | config MMC_SDHCI_PCI |
48 | tristate "SDHCI support on PCI bus" | 61 | tristate "SDHCI support on PCI bus" |
49 | depends on MMC_SDHCI && PCI | 62 | depends on MMC_SDHCI && PCI |
@@ -56,30 +69,44 @@ config MMC_SDHCI_PCI | |||
56 | If unsure, say N. | 69 | If unsure, say N. |
57 | 70 | ||
58 | config MMC_RICOH_MMC | 71 | config MMC_RICOH_MMC |
59 | tristate "Ricoh MMC Controller Disabler (EXPERIMENTAL)" | 72 | bool "Ricoh MMC Controller Disabler (EXPERIMENTAL)" |
60 | depends on MMC_SDHCI_PCI | 73 | depends on MMC_SDHCI_PCI |
61 | help | 74 | help |
62 | This selects the disabler for the Ricoh MMC Controller. This | 75 | This adds a pci quirk to disable Ricoh MMC Controller. This |
63 | proprietary controller is unnecessary because the SDHCI driver | 76 | proprietary controller is unnecessary because the SDHCI driver |
64 | supports MMC cards on the SD controller, but if it is not | 77 | supports MMC cards on the SD controller, but if it is not |
65 | disabled, it will steal the MMC cards away - rendering them | 78 | disabled, it will steal the MMC cards away - rendering them |
66 | useless. It is safe to select this driver even if you don't | 79 | useless. It is safe to select this even if you don't |
67 | have a Ricoh based card reader. | 80 | have a Ricoh based card reader. |
68 | 81 | ||
69 | |||
70 | To compile this driver as a module, choose M here: | ||
71 | the module will be called ricoh_mmc. | ||
72 | |||
73 | If unsure, say Y. | 82 | If unsure, say Y. |
74 | 83 | ||
75 | config MMC_SDHCI_OF | 84 | config MMC_SDHCI_OF |
76 | tristate "SDHCI support on OpenFirmware platforms" | 85 | tristate "SDHCI support on OpenFirmware platforms" |
77 | depends on MMC_SDHCI && PPC_OF | 86 | depends on MMC_SDHCI && PPC_OF |
78 | select MMC_SDHCI_IO_ACCESSORS | ||
79 | help | 87 | help |
80 | This selects the OF support for Secure Digital Host Controller | 88 | This selects the OF support for Secure Digital Host Controller |
81 | Interfaces. So far, only the Freescale eSDHC controller is known | 89 | Interfaces. |
82 | to exist on OF platforms. | 90 | |
91 | If unsure, say N. | ||
92 | |||
93 | config MMC_SDHCI_OF_ESDHC | ||
94 | bool "SDHCI OF support for the Freescale eSDHC controller" | ||
95 | depends on MMC_SDHCI_OF | ||
96 | select MMC_SDHCI_BIG_ENDIAN_32BIT_BYTE_SWAPPER | ||
97 | help | ||
98 | This selects the Freescale eSDHC controller support. | ||
99 | |||
100 | If unsure, say N. | ||
101 | |||
102 | config MMC_SDHCI_OF_HLWD | ||
103 | bool "SDHCI OF support for the Nintendo Wii SDHCI controllers" | ||
104 | depends on MMC_SDHCI_OF | ||
105 | select MMC_SDHCI_BIG_ENDIAN_32BIT_BYTE_SWAPPER | ||
106 | help | ||
107 | This selects the Secure Digital Host Controller Interface (SDHCI) | ||
108 | found in the "Hollywood" chipset of the Nintendo Wii video game | ||
109 | console. | ||
83 | 110 | ||
84 | If unsure, say N. | 111 | If unsure, say N. |
85 | 112 | ||
@@ -162,6 +189,7 @@ config MMC_AU1X | |||
162 | 189 | ||
163 | choice | 190 | choice |
164 | prompt "Atmel SD/MMC Driver" | 191 | prompt "Atmel SD/MMC Driver" |
192 | depends on AVR32 || ARCH_AT91 | ||
165 | default MMC_ATMELMCI if AVR32 | 193 | default MMC_ATMELMCI if AVR32 |
166 | help | 194 | help |
167 | Choose which driver to use for the Atmel MCI Silicon | 195 | Choose which driver to use for the Atmel MCI Silicon |
@@ -251,6 +279,14 @@ config MMC_MVSDIO | |||
251 | To compile this driver as a module, choose M here: the | 279 | To compile this driver as a module, choose M here: the |
252 | module will be called mvsdio. | 280 | module will be called mvsdio. |
253 | 281 | ||
282 | config MMC_DAVINCI | ||
283 | tristate "TI DAVINCI Multimedia Card Interface support" | ||
284 | depends on ARCH_DAVINCI | ||
285 | help | ||
286 | This selects the TI DAVINCI Multimedia card Interface. | ||
287 | If you have an DAVINCI board with a Multimedia Card slot, | ||
288 | say Y or M here. If unsure, say N. | ||
289 | |||
254 | config MMC_SPI | 290 | config MMC_SPI |
255 | tristate "MMC/SD/SDIO over SPI" | 291 | tristate "MMC/SD/SDIO over SPI" |
256 | depends on SPI_MASTER && !HIGHMEM && HAS_DMA | 292 | depends on SPI_MASTER && !HIGHMEM && HAS_DMA |
@@ -329,7 +365,7 @@ config MMC_SDRICOH_CS | |||
329 | 365 | ||
330 | config MMC_TMIO | 366 | config MMC_TMIO |
331 | tristate "Toshiba Mobile IO Controller (TMIO) MMC/SD function support" | 367 | tristate "Toshiba Mobile IO Controller (TMIO) MMC/SD function support" |
332 | depends on MFD_TMIO || MFD_ASIC3 | 368 | depends on MFD_TMIO || MFD_ASIC3 || MFD_SH_MOBILE_SDHI |
333 | help | 369 | help |
334 | This provides support for the SD/MMC cell found in TC6393XB, | 370 | This provides support for the SD/MMC cell found in TC6393XB, |
335 | T7L66XB and also HTC ASIC3 | 371 | T7L66XB and also HTC ASIC3 |
@@ -357,3 +393,22 @@ config MMC_VIA_SDMMC | |||
357 | If you have a controller with this interface, say Y or M here. | 393 | If you have a controller with this interface, say Y or M here. |
358 | 394 | ||
359 | If unsure, say N. | 395 | If unsure, say N. |
396 | |||
397 | config SDH_BFIN | ||
398 | tristate "Blackfin Secure Digital Host support" | ||
399 | depends on (BF54x && !BF544) || (BF51x && !BF512) | ||
400 | help | ||
401 | If you say yes here you will get support for the Blackfin on-chip | ||
402 | Secure Digital Host interface. This includes support for MMC and | ||
403 | SD cards. | ||
404 | |||
405 | To compile this driver as a module, choose M here: the | ||
406 | module will be called bfin_sdh. | ||
407 | |||
408 | If unsure, say N. | ||
409 | |||
410 | config SDH_BFIN_MISSING_CMD_PULLUP_WORKAROUND | ||
411 | bool "Blackfin EZkit Missing SDH_CMD Pull Up Resistor Workaround" | ||
412 | depends on SDH_BFIN | ||
413 | help | ||
414 | If you say yes here SD-Cards may work on the EZkit. | ||
diff --git a/drivers/mmc/host/Makefile b/drivers/mmc/host/Makefile index abcb0400e06d..f4803977dfce 100644 --- a/drivers/mmc/host/Makefile +++ b/drivers/mmc/host/Makefile | |||
@@ -12,8 +12,6 @@ obj-$(CONFIG_MMC_IMX) += imxmmc.o | |||
12 | obj-$(CONFIG_MMC_MXC) += mxcmmc.o | 12 | obj-$(CONFIG_MMC_MXC) += mxcmmc.o |
13 | obj-$(CONFIG_MMC_SDHCI) += sdhci.o | 13 | obj-$(CONFIG_MMC_SDHCI) += sdhci.o |
14 | obj-$(CONFIG_MMC_SDHCI_PCI) += sdhci-pci.o | 14 | obj-$(CONFIG_MMC_SDHCI_PCI) += sdhci-pci.o |
15 | obj-$(CONFIG_MMC_RICOH_MMC) += ricoh_mmc.o | ||
16 | obj-$(CONFIG_MMC_SDHCI_OF) += sdhci-of.o | ||
17 | obj-$(CONFIG_MMC_SDHCI_PLTFM) += sdhci-pltfm.o | 15 | obj-$(CONFIG_MMC_SDHCI_PLTFM) += sdhci-pltfm.o |
18 | obj-$(CONFIG_MMC_SDHCI_S3C) += sdhci-s3c.o | 16 | obj-$(CONFIG_MMC_SDHCI_S3C) += sdhci-s3c.o |
19 | obj-$(CONFIG_MMC_WBSD) += wbsd.o | 17 | obj-$(CONFIG_MMC_WBSD) += wbsd.o |
@@ -25,6 +23,7 @@ obj-$(CONFIG_MMC_ATMELMCI) += atmel-mci.o | |||
25 | obj-$(CONFIG_MMC_TIFM_SD) += tifm_sd.o | 23 | obj-$(CONFIG_MMC_TIFM_SD) += tifm_sd.o |
26 | obj-$(CONFIG_MMC_MSM7X00A) += msm_sdcc.o | 24 | obj-$(CONFIG_MMC_MSM7X00A) += msm_sdcc.o |
27 | obj-$(CONFIG_MMC_MVSDIO) += mvsdio.o | 25 | obj-$(CONFIG_MMC_MVSDIO) += mvsdio.o |
26 | obj-$(CONFIG_MMC_DAVINCI) += davinci_mmc.o | ||
28 | obj-$(CONFIG_MMC_SPI) += mmc_spi.o | 27 | obj-$(CONFIG_MMC_SPI) += mmc_spi.o |
29 | ifeq ($(CONFIG_OF),y) | 28 | ifeq ($(CONFIG_OF),y) |
30 | obj-$(CONFIG_MMC_SPI) += of_mmc_spi.o | 29 | obj-$(CONFIG_MMC_SPI) += of_mmc_spi.o |
@@ -34,6 +33,12 @@ obj-$(CONFIG_MMC_SDRICOH_CS) += sdricoh_cs.o | |||
34 | obj-$(CONFIG_MMC_TMIO) += tmio_mmc.o | 33 | obj-$(CONFIG_MMC_TMIO) += tmio_mmc.o |
35 | obj-$(CONFIG_MMC_CB710) += cb710-mmc.o | 34 | obj-$(CONFIG_MMC_CB710) += cb710-mmc.o |
36 | obj-$(CONFIG_MMC_VIA_SDMMC) += via-sdmmc.o | 35 | obj-$(CONFIG_MMC_VIA_SDMMC) += via-sdmmc.o |
36 | obj-$(CONFIG_SDH_BFIN) += bfin_sdh.o | ||
37 | |||
38 | obj-$(CONFIG_MMC_SDHCI_OF) += sdhci-of.o | ||
39 | sdhci-of-y := sdhci-of-core.o | ||
40 | sdhci-of-$(CONFIG_MMC_SDHCI_OF_ESDHC) += sdhci-of-esdhc.o | ||
41 | sdhci-of-$(CONFIG_MMC_SDHCI_OF_HLWD) += sdhci-of-hlwd.o | ||
37 | 42 | ||
38 | ifeq ($(CONFIG_CB710_DEBUG),y) | 43 | ifeq ($(CONFIG_CB710_DEBUG),y) |
39 | CFLAGS-cb710-mmc += -DDEBUG | 44 | CFLAGS-cb710-mmc += -DDEBUG |
diff --git a/drivers/mmc/host/at91_mci.c b/drivers/mmc/host/at91_mci.c index 63924e0c7ea9..336d9f553f3e 100644 --- a/drivers/mmc/host/at91_mci.c +++ b/drivers/mmc/host/at91_mci.c | |||
@@ -65,6 +65,7 @@ | |||
65 | #include <linux/dma-mapping.h> | 65 | #include <linux/dma-mapping.h> |
66 | #include <linux/clk.h> | 66 | #include <linux/clk.h> |
67 | #include <linux/atmel_pdc.h> | 67 | #include <linux/atmel_pdc.h> |
68 | #include <linux/gfp.h> | ||
68 | 69 | ||
69 | #include <linux/mmc/host.h> | 70 | #include <linux/mmc/host.h> |
70 | 71 | ||
@@ -78,6 +79,17 @@ | |||
78 | 79 | ||
79 | #define DRIVER_NAME "at91_mci" | 80 | #define DRIVER_NAME "at91_mci" |
80 | 81 | ||
82 | static inline int at91mci_is_mci1rev2xx(void) | ||
83 | { | ||
84 | return ( cpu_is_at91sam9260() | ||
85 | || cpu_is_at91sam9263() | ||
86 | || cpu_is_at91cap9() | ||
87 | || cpu_is_at91sam9rl() | ||
88 | || cpu_is_at91sam9g10() | ||
89 | || cpu_is_at91sam9g20() | ||
90 | ); | ||
91 | } | ||
92 | |||
81 | #define FL_SENT_COMMAND (1 << 0) | 93 | #define FL_SENT_COMMAND (1 << 0) |
82 | #define FL_SENT_STOP (1 << 1) | 94 | #define FL_SENT_STOP (1 << 1) |
83 | 95 | ||
@@ -88,6 +100,10 @@ | |||
88 | #define at91_mci_read(host, reg) __raw_readl((host)->baseaddr + (reg)) | 100 | #define at91_mci_read(host, reg) __raw_readl((host)->baseaddr + (reg)) |
89 | #define at91_mci_write(host, reg, val) __raw_writel((val), (host)->baseaddr + (reg)) | 101 | #define at91_mci_write(host, reg, val) __raw_writel((val), (host)->baseaddr + (reg)) |
90 | 102 | ||
103 | #define MCI_BLKSIZE 512 | ||
104 | #define MCI_MAXBLKSIZE 4095 | ||
105 | #define MCI_BLKATONCE 256 | ||
106 | #define MCI_BUFSIZE (MCI_BLKSIZE * MCI_BLKATONCE) | ||
91 | 107 | ||
92 | /* | 108 | /* |
93 | * Low level type for this driver | 109 | * Low level type for this driver |
@@ -200,8 +216,8 @@ static inline void at91_mci_sg_to_dma(struct at91mci_host *host, struct mmc_data | |||
200 | size = data->blksz * data->blocks; | 216 | size = data->blksz * data->blocks; |
201 | len = data->sg_len; | 217 | len = data->sg_len; |
202 | 218 | ||
203 | /* AT91SAM926[0/3] Data Write Operation and number of bytes erratum */ | 219 | /* MCI1 rev2xx Data Write Operation and number of bytes erratum */ |
204 | if (cpu_is_at91sam9260() || cpu_is_at91sam9263()) | 220 | if (at91mci_is_mci1rev2xx()) |
205 | if (host->total_length == 12) | 221 | if (host->total_length == 12) |
206 | memset(dmabuf, 0, 12); | 222 | memset(dmabuf, 0, 12); |
207 | 223 | ||
@@ -227,8 +243,10 @@ static inline void at91_mci_sg_to_dma(struct at91mci_host *host, struct mmc_data | |||
227 | for (index = 0; index < (amount / 4); index++) | 243 | for (index = 0; index < (amount / 4); index++) |
228 | *dmabuf++ = swab32(sgbuffer[index]); | 244 | *dmabuf++ = swab32(sgbuffer[index]); |
229 | } else { | 245 | } else { |
230 | memcpy(dmabuf, sgbuffer, amount); | 246 | char *tmpv = (char *)dmabuf; |
231 | dmabuf += amount; | 247 | memcpy(tmpv, sgbuffer, amount); |
248 | tmpv += amount; | ||
249 | dmabuf = (unsigned *)tmpv; | ||
232 | } | 250 | } |
233 | 251 | ||
234 | kunmap_atomic(sgbuffer, KM_BIO_SRC_IRQ); | 252 | kunmap_atomic(sgbuffer, KM_BIO_SRC_IRQ); |
@@ -245,80 +263,14 @@ static inline void at91_mci_sg_to_dma(struct at91mci_host *host, struct mmc_data | |||
245 | } | 263 | } |
246 | 264 | ||
247 | /* | 265 | /* |
248 | * Prepare a dma read | ||
249 | */ | ||
250 | static void at91_mci_pre_dma_read(struct at91mci_host *host) | ||
251 | { | ||
252 | int i; | ||
253 | struct scatterlist *sg; | ||
254 | struct mmc_command *cmd; | ||
255 | struct mmc_data *data; | ||
256 | |||
257 | pr_debug("pre dma read\n"); | ||
258 | |||
259 | cmd = host->cmd; | ||
260 | if (!cmd) { | ||
261 | pr_debug("no command\n"); | ||
262 | return; | ||
263 | } | ||
264 | |||
265 | data = cmd->data; | ||
266 | if (!data) { | ||
267 | pr_debug("no data\n"); | ||
268 | return; | ||
269 | } | ||
270 | |||
271 | for (i = 0; i < 2; i++) { | ||
272 | /* nothing left to transfer */ | ||
273 | if (host->transfer_index >= data->sg_len) { | ||
274 | pr_debug("Nothing left to transfer (index = %d)\n", host->transfer_index); | ||
275 | break; | ||
276 | } | ||
277 | |||
278 | /* Check to see if this needs filling */ | ||
279 | if (i == 0) { | ||
280 | if (at91_mci_read(host, ATMEL_PDC_RCR) != 0) { | ||
281 | pr_debug("Transfer active in current\n"); | ||
282 | continue; | ||
283 | } | ||
284 | } | ||
285 | else { | ||
286 | if (at91_mci_read(host, ATMEL_PDC_RNCR) != 0) { | ||
287 | pr_debug("Transfer active in next\n"); | ||
288 | continue; | ||
289 | } | ||
290 | } | ||
291 | |||
292 | /* Setup the next transfer */ | ||
293 | pr_debug("Using transfer index %d\n", host->transfer_index); | ||
294 | |||
295 | sg = &data->sg[host->transfer_index++]; | ||
296 | pr_debug("sg = %p\n", sg); | ||
297 | |||
298 | sg->dma_address = dma_map_page(NULL, sg_page(sg), sg->offset, sg->length, DMA_FROM_DEVICE); | ||
299 | |||
300 | pr_debug("dma address = %08X, length = %d\n", sg->dma_address, sg->length); | ||
301 | |||
302 | if (i == 0) { | ||
303 | at91_mci_write(host, ATMEL_PDC_RPR, sg->dma_address); | ||
304 | at91_mci_write(host, ATMEL_PDC_RCR, (data->blksz & 0x3) ? sg->length : sg->length / 4); | ||
305 | } | ||
306 | else { | ||
307 | at91_mci_write(host, ATMEL_PDC_RNPR, sg->dma_address); | ||
308 | at91_mci_write(host, ATMEL_PDC_RNCR, (data->blksz & 0x3) ? sg->length : sg->length / 4); | ||
309 | } | ||
310 | } | ||
311 | |||
312 | pr_debug("pre dma read done\n"); | ||
313 | } | ||
314 | |||
315 | /* | ||
316 | * Handle after a dma read | 266 | * Handle after a dma read |
317 | */ | 267 | */ |
318 | static void at91_mci_post_dma_read(struct at91mci_host *host) | 268 | static void at91_mci_post_dma_read(struct at91mci_host *host) |
319 | { | 269 | { |
320 | struct mmc_command *cmd; | 270 | struct mmc_command *cmd; |
321 | struct mmc_data *data; | 271 | struct mmc_data *data; |
272 | unsigned int len, i, size; | ||
273 | unsigned *dmabuf = host->buffer; | ||
322 | 274 | ||
323 | pr_debug("post dma read\n"); | 275 | pr_debug("post dma read\n"); |
324 | 276 | ||
@@ -334,42 +286,39 @@ static void at91_mci_post_dma_read(struct at91mci_host *host) | |||
334 | return; | 286 | return; |
335 | } | 287 | } |
336 | 288 | ||
337 | while (host->in_use_index < host->transfer_index) { | 289 | size = data->blksz * data->blocks; |
338 | struct scatterlist *sg; | 290 | len = data->sg_len; |
339 | 291 | ||
340 | pr_debug("finishing index %d\n", host->in_use_index); | 292 | at91_mci_write(host, AT91_MCI_IDR, AT91_MCI_ENDRX); |
293 | at91_mci_write(host, AT91_MCI_IER, AT91_MCI_RXBUFF); | ||
341 | 294 | ||
342 | sg = &data->sg[host->in_use_index++]; | 295 | for (i = 0; i < len; i++) { |
296 | struct scatterlist *sg; | ||
297 | int amount; | ||
298 | unsigned int *sgbuffer; | ||
343 | 299 | ||
344 | pr_debug("Unmapping page %08X\n", sg->dma_address); | 300 | sg = &data->sg[i]; |
345 | 301 | ||
346 | dma_unmap_page(NULL, sg->dma_address, sg->length, DMA_FROM_DEVICE); | 302 | sgbuffer = kmap_atomic(sg_page(sg), KM_BIO_SRC_IRQ) + sg->offset; |
303 | amount = min(size, sg->length); | ||
304 | size -= amount; | ||
347 | 305 | ||
348 | if (cpu_is_at91rm9200()) { /* AT91RM9200 errata */ | 306 | if (cpu_is_at91rm9200()) { /* AT91RM9200 errata */ |
349 | unsigned int *buffer; | ||
350 | int index; | 307 | int index; |
351 | 308 | for (index = 0; index < (amount / 4); index++) | |
352 | /* Swap the contents of the buffer */ | 309 | sgbuffer[index] = swab32(*dmabuf++); |
353 | buffer = kmap_atomic(sg_page(sg), KM_BIO_SRC_IRQ) + sg->offset; | 310 | } else { |
354 | pr_debug("buffer = %p, length = %d\n", buffer, sg->length); | 311 | char *tmpv = (char *)dmabuf; |
355 | 312 | memcpy(sgbuffer, tmpv, amount); | |
356 | for (index = 0; index < (sg->length / 4); index++) | 313 | tmpv += amount; |
357 | buffer[index] = swab32(buffer[index]); | 314 | dmabuf = (unsigned *)tmpv; |
358 | |||
359 | kunmap_atomic(buffer, KM_BIO_SRC_IRQ); | ||
360 | } | 315 | } |
361 | 316 | ||
362 | flush_dcache_page(sg_page(sg)); | 317 | flush_kernel_dcache_page(sg_page(sg)); |
363 | 318 | kunmap_atomic(sgbuffer, KM_BIO_SRC_IRQ); | |
364 | data->bytes_xfered += sg->length; | 319 | data->bytes_xfered += amount; |
365 | } | 320 | if (size == 0) |
366 | 321 | break; | |
367 | /* Is there another transfer to trigger? */ | ||
368 | if (host->transfer_index < data->sg_len) | ||
369 | at91_mci_pre_dma_read(host); | ||
370 | else { | ||
371 | at91_mci_write(host, AT91_MCI_IDR, AT91_MCI_ENDRX); | ||
372 | at91_mci_write(host, AT91_MCI_IER, AT91_MCI_RXBUFF); | ||
373 | } | 322 | } |
374 | 323 | ||
375 | pr_debug("post dma read done\n"); | 324 | pr_debug("post dma read done\n"); |
@@ -461,7 +410,7 @@ static void at91_mci_enable(struct at91mci_host *host) | |||
461 | at91_mci_write(host, AT91_MCI_DTOR, AT91_MCI_DTOMUL_1M | AT91_MCI_DTOCYC); | 410 | at91_mci_write(host, AT91_MCI_DTOR, AT91_MCI_DTOMUL_1M | AT91_MCI_DTOCYC); |
462 | mr = AT91_MCI_PDCMODE | 0x34a; | 411 | mr = AT91_MCI_PDCMODE | 0x34a; |
463 | 412 | ||
464 | if (cpu_is_at91sam9260() || cpu_is_at91sam9263()) | 413 | if (at91mci_is_mci1rev2xx()) |
465 | mr |= AT91_MCI_RDPROOF | AT91_MCI_WRPROOF; | 414 | mr |= AT91_MCI_RDPROOF | AT91_MCI_WRPROOF; |
466 | 415 | ||
467 | at91_mci_write(host, AT91_MCI_MR, mr); | 416 | at91_mci_write(host, AT91_MCI_MR, mr); |
@@ -602,10 +551,14 @@ static void at91_mci_send_command(struct at91mci_host *host, struct mmc_command | |||
602 | /* | 551 | /* |
603 | * Handle a read | 552 | * Handle a read |
604 | */ | 553 | */ |
605 | host->buffer = NULL; | ||
606 | host->total_length = 0; | 554 | host->total_length = 0; |
607 | 555 | ||
608 | at91_mci_pre_dma_read(host); | 556 | at91_mci_write(host, ATMEL_PDC_RPR, host->physical_address); |
557 | at91_mci_write(host, ATMEL_PDC_RCR, (data->blksz & 0x3) ? | ||
558 | (blocks * block_length) : (blocks * block_length) / 4); | ||
559 | at91_mci_write(host, ATMEL_PDC_RNPR, 0); | ||
560 | at91_mci_write(host, ATMEL_PDC_RNCR, 0); | ||
561 | |||
609 | ier = AT91_MCI_ENDRX /* | AT91_MCI_RXBUFF */; | 562 | ier = AT91_MCI_ENDRX /* | AT91_MCI_RXBUFF */; |
610 | } | 563 | } |
611 | else { | 564 | else { |
@@ -614,27 +567,15 @@ static void at91_mci_send_command(struct at91mci_host *host, struct mmc_command | |||
614 | */ | 567 | */ |
615 | host->total_length = block_length * blocks; | 568 | host->total_length = block_length * blocks; |
616 | /* | 569 | /* |
617 | * AT91SAM926[0/3] Data Write Operation and | 570 | * MCI1 rev2xx Data Write Operation and |
618 | * number of bytes erratum | 571 | * number of bytes erratum |
619 | */ | 572 | */ |
620 | if (cpu_is_at91sam9260 () || cpu_is_at91sam9263()) | 573 | if (at91mci_is_mci1rev2xx()) |
621 | if (host->total_length < 12) | 574 | if (host->total_length < 12) |
622 | host->total_length = 12; | 575 | host->total_length = 12; |
623 | 576 | ||
624 | host->buffer = kmalloc(host->total_length, GFP_KERNEL); | ||
625 | if (!host->buffer) { | ||
626 | pr_debug("Can't alloc tx buffer\n"); | ||
627 | cmd->error = -ENOMEM; | ||
628 | mmc_request_done(host->mmc, host->request); | ||
629 | return; | ||
630 | } | ||
631 | |||
632 | at91_mci_sg_to_dma(host, data); | 577 | at91_mci_sg_to_dma(host, data); |
633 | 578 | ||
634 | host->physical_address = dma_map_single(NULL, | ||
635 | host->buffer, host->total_length, | ||
636 | DMA_TO_DEVICE); | ||
637 | |||
638 | pr_debug("Transmitting %d bytes\n", host->total_length); | 579 | pr_debug("Transmitting %d bytes\n", host->total_length); |
639 | 580 | ||
640 | at91_mci_write(host, ATMEL_PDC_TPR, host->physical_address); | 581 | at91_mci_write(host, ATMEL_PDC_TPR, host->physical_address); |
@@ -701,14 +642,6 @@ static void at91_mci_completed_command(struct at91mci_host *host, unsigned int s | |||
701 | cmd->resp[2] = at91_mci_read(host, AT91_MCI_RSPR(2)); | 642 | cmd->resp[2] = at91_mci_read(host, AT91_MCI_RSPR(2)); |
702 | cmd->resp[3] = at91_mci_read(host, AT91_MCI_RSPR(3)); | 643 | cmd->resp[3] = at91_mci_read(host, AT91_MCI_RSPR(3)); |
703 | 644 | ||
704 | if (host->buffer) { | ||
705 | dma_unmap_single(NULL, | ||
706 | host->physical_address, host->total_length, | ||
707 | DMA_TO_DEVICE); | ||
708 | kfree(host->buffer); | ||
709 | host->buffer = NULL; | ||
710 | } | ||
711 | |||
712 | pr_debug("Status = %08X/%08x [%08X %08X %08X %08X]\n", | 645 | pr_debug("Status = %08X/%08x [%08X %08X %08X %08X]\n", |
713 | status, at91_mci_read(host, AT91_MCI_SR), | 646 | status, at91_mci_read(host, AT91_MCI_SR), |
714 | cmd->resp[0], cmd->resp[1], cmd->resp[2], cmd->resp[3]); | 647 | cmd->resp[0], cmd->resp[1], cmd->resp[2], cmd->resp[3]); |
@@ -754,7 +687,8 @@ static void at91_mci_request(struct mmc_host *mmc, struct mmc_request *mrq) | |||
754 | host->request = mrq; | 687 | host->request = mrq; |
755 | host->flags = 0; | 688 | host->flags = 0; |
756 | 689 | ||
757 | mod_timer(&host->timer, jiffies + HZ); | 690 | /* more than 1s timeout needed with slow SD cards */ |
691 | mod_timer(&host->timer, jiffies + msecs_to_jiffies(2000)); | ||
758 | 692 | ||
759 | at91_mci_process_next(host); | 693 | at91_mci_process_next(host); |
760 | } | 694 | } |
@@ -942,7 +876,8 @@ static irqreturn_t at91_mmc_det_irq(int irq, void *_host) | |||
942 | pr_debug("****** Resetting SD-card bus width ******\n"); | 876 | pr_debug("****** Resetting SD-card bus width ******\n"); |
943 | at91_mci_write(host, AT91_MCI_SDCR, at91_mci_read(host, AT91_MCI_SDCR) & ~AT91_MCI_SDCBUS); | 877 | at91_mci_write(host, AT91_MCI_SDCR, at91_mci_read(host, AT91_MCI_SDCR) & ~AT91_MCI_SDCBUS); |
944 | } | 878 | } |
945 | mmc_detect_change(host->mmc, msecs_to_jiffies(100)); | 879 | /* 0.5s needed because of early card detect switch firing */ |
880 | mmc_detect_change(host->mmc, msecs_to_jiffies(500)); | ||
946 | } | 881 | } |
947 | return IRQ_HANDLED; | 882 | return IRQ_HANDLED; |
948 | } | 883 | } |
@@ -1006,24 +941,42 @@ static int __init at91_mci_probe(struct platform_device *pdev) | |||
1006 | mmc->f_min = 375000; | 941 | mmc->f_min = 375000; |
1007 | mmc->f_max = 25000000; | 942 | mmc->f_max = 25000000; |
1008 | mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34; | 943 | mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34; |
1009 | mmc->caps = MMC_CAP_SDIO_IRQ; | 944 | mmc->caps = 0; |
1010 | 945 | ||
1011 | mmc->max_blk_size = 4095; | 946 | mmc->max_blk_size = MCI_MAXBLKSIZE; |
1012 | mmc->max_blk_count = mmc->max_req_size; | 947 | mmc->max_blk_count = MCI_BLKATONCE; |
948 | mmc->max_req_size = MCI_BUFSIZE; | ||
949 | mmc->max_phys_segs = MCI_BLKATONCE; | ||
950 | mmc->max_hw_segs = MCI_BLKATONCE; | ||
951 | mmc->max_seg_size = MCI_BUFSIZE; | ||
1013 | 952 | ||
1014 | host = mmc_priv(mmc); | 953 | host = mmc_priv(mmc); |
1015 | host->mmc = mmc; | 954 | host->mmc = mmc; |
1016 | host->buffer = NULL; | ||
1017 | host->bus_mode = 0; | 955 | host->bus_mode = 0; |
1018 | host->board = pdev->dev.platform_data; | 956 | host->board = pdev->dev.platform_data; |
1019 | if (host->board->wire4) { | 957 | if (host->board->wire4) { |
1020 | if (cpu_is_at91sam9260() || cpu_is_at91sam9263()) | 958 | if (at91mci_is_mci1rev2xx()) |
1021 | mmc->caps |= MMC_CAP_4_BIT_DATA; | 959 | mmc->caps |= MMC_CAP_4_BIT_DATA; |
1022 | else | 960 | else |
1023 | dev_warn(&pdev->dev, "4 wire bus mode not supported" | 961 | dev_warn(&pdev->dev, "4 wire bus mode not supported" |
1024 | " - using 1 wire\n"); | 962 | " - using 1 wire\n"); |
1025 | } | 963 | } |
1026 | 964 | ||
965 | host->buffer = dma_alloc_coherent(&pdev->dev, MCI_BUFSIZE, | ||
966 | &host->physical_address, GFP_KERNEL); | ||
967 | if (!host->buffer) { | ||
968 | ret = -ENOMEM; | ||
969 | dev_err(&pdev->dev, "Can't allocate transmit buffer\n"); | ||
970 | goto fail5; | ||
971 | } | ||
972 | |||
973 | /* Add SDIO capability when available */ | ||
974 | if (at91mci_is_mci1rev2xx()) { | ||
975 | /* at91mci MCI1 rev2xx sdio interrupt erratum */ | ||
976 | if (host->board->wire4 || !host->board->slot_b) | ||
977 | mmc->caps |= MMC_CAP_SDIO_IRQ; | ||
978 | } | ||
979 | |||
1027 | /* | 980 | /* |
1028 | * Reserve GPIOs ... board init code makes sure these pins are set | 981 | * Reserve GPIOs ... board init code makes sure these pins are set |
1029 | * up as GPIOs with the right direction (input, except for vcc) | 982 | * up as GPIOs with the right direction (input, except for vcc) |
@@ -1032,7 +985,7 @@ static int __init at91_mci_probe(struct platform_device *pdev) | |||
1032 | ret = gpio_request(host->board->det_pin, "mmc_detect"); | 985 | ret = gpio_request(host->board->det_pin, "mmc_detect"); |
1033 | if (ret < 0) { | 986 | if (ret < 0) { |
1034 | dev_dbg(&pdev->dev, "couldn't claim card detect pin\n"); | 987 | dev_dbg(&pdev->dev, "couldn't claim card detect pin\n"); |
1035 | goto fail5; | 988 | goto fail4b; |
1036 | } | 989 | } |
1037 | } | 990 | } |
1038 | if (host->board->wp_pin) { | 991 | if (host->board->wp_pin) { |
@@ -1132,6 +1085,10 @@ fail3: | |||
1132 | fail4: | 1085 | fail4: |
1133 | if (host->board->det_pin) | 1086 | if (host->board->det_pin) |
1134 | gpio_free(host->board->det_pin); | 1087 | gpio_free(host->board->det_pin); |
1088 | fail4b: | ||
1089 | if (host->buffer) | ||
1090 | dma_free_coherent(&pdev->dev, MCI_BUFSIZE, | ||
1091 | host->buffer, host->physical_address); | ||
1135 | fail5: | 1092 | fail5: |
1136 | mmc_free_host(mmc); | 1093 | mmc_free_host(mmc); |
1137 | fail6: | 1094 | fail6: |
@@ -1154,6 +1111,10 @@ static int __exit at91_mci_remove(struct platform_device *pdev) | |||
1154 | 1111 | ||
1155 | host = mmc_priv(mmc); | 1112 | host = mmc_priv(mmc); |
1156 | 1113 | ||
1114 | if (host->buffer) | ||
1115 | dma_free_coherent(&pdev->dev, MCI_BUFSIZE, | ||
1116 | host->buffer, host->physical_address); | ||
1117 | |||
1157 | if (host->board->det_pin) { | 1118 | if (host->board->det_pin) { |
1158 | if (device_can_wakeup(&pdev->dev)) | 1119 | if (device_can_wakeup(&pdev->dev)) |
1159 | free_irq(gpio_to_irq(host->board->det_pin), host); | 1120 | free_irq(gpio_to_irq(host->board->det_pin), host); |
diff --git a/drivers/mmc/host/atmel-mci.c b/drivers/mmc/host/atmel-mci.c index fc25586b7ee1..fb279f4ed8b3 100644 --- a/drivers/mmc/host/atmel-mci.c +++ b/drivers/mmc/host/atmel-mci.c | |||
@@ -22,9 +22,12 @@ | |||
22 | #include <linux/platform_device.h> | 22 | #include <linux/platform_device.h> |
23 | #include <linux/scatterlist.h> | 23 | #include <linux/scatterlist.h> |
24 | #include <linux/seq_file.h> | 24 | #include <linux/seq_file.h> |
25 | #include <linux/slab.h> | ||
25 | #include <linux/stat.h> | 26 | #include <linux/stat.h> |
26 | 27 | ||
27 | #include <linux/mmc/host.h> | 28 | #include <linux/mmc/host.h> |
29 | |||
30 | #include <mach/atmel-mci.h> | ||
28 | #include <linux/atmel-mci.h> | 31 | #include <linux/atmel-mci.h> |
29 | 32 | ||
30 | #include <asm/io.h> | 33 | #include <asm/io.h> |
@@ -92,6 +95,7 @@ struct atmel_mci_dma { | |||
92 | * @need_clock_update: Update the clock rate before the next request. | 95 | * @need_clock_update: Update the clock rate before the next request. |
93 | * @need_reset: Reset controller before next request. | 96 | * @need_reset: Reset controller before next request. |
94 | * @mode_reg: Value of the MR register. | 97 | * @mode_reg: Value of the MR register. |
98 | * @cfg_reg: Value of the CFG register. | ||
95 | * @bus_hz: The rate of @mck in Hz. This forms the basis for MMC bus | 99 | * @bus_hz: The rate of @mck in Hz. This forms the basis for MMC bus |
96 | * rate and timeout calculations. | 100 | * rate and timeout calculations. |
97 | * @mapbase: Physical address of the MMIO registers. | 101 | * @mapbase: Physical address of the MMIO registers. |
@@ -155,6 +159,7 @@ struct atmel_mci { | |||
155 | bool need_clock_update; | 159 | bool need_clock_update; |
156 | bool need_reset; | 160 | bool need_reset; |
157 | u32 mode_reg; | 161 | u32 mode_reg; |
162 | u32 cfg_reg; | ||
158 | unsigned long bus_hz; | 163 | unsigned long bus_hz; |
159 | unsigned long mapbase; | 164 | unsigned long mapbase; |
160 | struct clk *mck; | 165 | struct clk *mck; |
@@ -223,6 +228,19 @@ static bool mci_has_rwproof(void) | |||
223 | } | 228 | } |
224 | 229 | ||
225 | /* | 230 | /* |
231 | * The new MCI2 module isn't 100% compatible with the old MCI module, | ||
232 | * and it has a few nice features which we want to use... | ||
233 | */ | ||
234 | static inline bool atmci_is_mci2(void) | ||
235 | { | ||
236 | if (cpu_is_at91sam9g45()) | ||
237 | return true; | ||
238 | |||
239 | return false; | ||
240 | } | ||
241 | |||
242 | |||
243 | /* | ||
226 | * The debugfs stuff below is mostly optimized away when | 244 | * The debugfs stuff below is mostly optimized away when |
227 | * CONFIG_DEBUG_FS is not set. | 245 | * CONFIG_DEBUG_FS is not set. |
228 | */ | 246 | */ |
@@ -248,7 +266,7 @@ static int atmci_req_show(struct seq_file *s, void *v) | |||
248 | "CMD%u(0x%x) flg %x rsp %x %x %x %x err %d\n", | 266 | "CMD%u(0x%x) flg %x rsp %x %x %x %x err %d\n", |
249 | cmd->opcode, cmd->arg, cmd->flags, | 267 | cmd->opcode, cmd->arg, cmd->flags, |
250 | cmd->resp[0], cmd->resp[1], cmd->resp[2], | 268 | cmd->resp[0], cmd->resp[1], cmd->resp[2], |
251 | cmd->resp[2], cmd->error); | 269 | cmd->resp[3], cmd->error); |
252 | if (data) | 270 | if (data) |
253 | seq_printf(s, "DATA %u / %u * %u flg %x err %d\n", | 271 | seq_printf(s, "DATA %u / %u * %u flg %x err %d\n", |
254 | data->bytes_xfered, data->blocks, | 272 | data->bytes_xfered, data->blocks, |
@@ -258,7 +276,7 @@ static int atmci_req_show(struct seq_file *s, void *v) | |||
258 | "CMD%u(0x%x) flg %x rsp %x %x %x %x err %d\n", | 276 | "CMD%u(0x%x) flg %x rsp %x %x %x %x err %d\n", |
259 | stop->opcode, stop->arg, stop->flags, | 277 | stop->opcode, stop->arg, stop->flags, |
260 | stop->resp[0], stop->resp[1], stop->resp[2], | 278 | stop->resp[0], stop->resp[1], stop->resp[2], |
261 | stop->resp[2], stop->error); | 279 | stop->resp[3], stop->error); |
262 | } | 280 | } |
263 | 281 | ||
264 | spin_unlock_bh(&slot->host->lock); | 282 | spin_unlock_bh(&slot->host->lock); |
@@ -357,12 +375,33 @@ static int atmci_regs_show(struct seq_file *s, void *v) | |||
357 | buf[MCI_BLKR / 4], | 375 | buf[MCI_BLKR / 4], |
358 | buf[MCI_BLKR / 4] & 0xffff, | 376 | buf[MCI_BLKR / 4] & 0xffff, |
359 | (buf[MCI_BLKR / 4] >> 16) & 0xffff); | 377 | (buf[MCI_BLKR / 4] >> 16) & 0xffff); |
378 | if (atmci_is_mci2()) | ||
379 | seq_printf(s, "CSTOR:\t0x%08x\n", buf[MCI_CSTOR / 4]); | ||
360 | 380 | ||
361 | /* Don't read RSPR and RDR; it will consume the data there */ | 381 | /* Don't read RSPR and RDR; it will consume the data there */ |
362 | 382 | ||
363 | atmci_show_status_reg(s, "SR", buf[MCI_SR / 4]); | 383 | atmci_show_status_reg(s, "SR", buf[MCI_SR / 4]); |
364 | atmci_show_status_reg(s, "IMR", buf[MCI_IMR / 4]); | 384 | atmci_show_status_reg(s, "IMR", buf[MCI_IMR / 4]); |
365 | 385 | ||
386 | if (atmci_is_mci2()) { | ||
387 | u32 val; | ||
388 | |||
389 | val = buf[MCI_DMA / 4]; | ||
390 | seq_printf(s, "DMA:\t0x%08x OFFSET=%u CHKSIZE=%u%s\n", | ||
391 | val, val & 3, | ||
392 | ((val >> 4) & 3) ? | ||
393 | 1 << (((val >> 4) & 3) + 1) : 1, | ||
394 | val & MCI_DMAEN ? " DMAEN" : ""); | ||
395 | |||
396 | val = buf[MCI_CFG / 4]; | ||
397 | seq_printf(s, "CFG:\t0x%08x%s%s%s%s\n", | ||
398 | val, | ||
399 | val & MCI_CFG_FIFOMODE_1DATA ? " FIFOMODE_ONE_DATA" : "", | ||
400 | val & MCI_CFG_FERRCTRL_COR ? " FERRCTRL_CLEAR_ON_READ" : "", | ||
401 | val & MCI_CFG_HSMODE ? " HSMODE" : "", | ||
402 | val & MCI_CFG_LSYNC ? " LSYNC" : ""); | ||
403 | } | ||
404 | |||
366 | kfree(buf); | 405 | kfree(buf); |
367 | 406 | ||
368 | return 0; | 407 | return 0; |
@@ -530,9 +569,10 @@ static void atmci_dma_cleanup(struct atmel_mci *host) | |||
530 | { | 569 | { |
531 | struct mmc_data *data = host->data; | 570 | struct mmc_data *data = host->data; |
532 | 571 | ||
533 | dma_unmap_sg(&host->pdev->dev, data->sg, data->sg_len, | 572 | if (data) |
534 | ((data->flags & MMC_DATA_WRITE) | 573 | dma_unmap_sg(&host->pdev->dev, data->sg, data->sg_len, |
535 | ? DMA_TO_DEVICE : DMA_FROM_DEVICE)); | 574 | ((data->flags & MMC_DATA_WRITE) |
575 | ? DMA_TO_DEVICE : DMA_FROM_DEVICE)); | ||
536 | } | 576 | } |
537 | 577 | ||
538 | static void atmci_stop_dma(struct atmel_mci *host) | 578 | static void atmci_stop_dma(struct atmel_mci *host) |
@@ -557,6 +597,10 @@ static void atmci_dma_complete(void *arg) | |||
557 | 597 | ||
558 | dev_vdbg(&host->pdev->dev, "DMA complete\n"); | 598 | dev_vdbg(&host->pdev->dev, "DMA complete\n"); |
559 | 599 | ||
600 | if (atmci_is_mci2()) | ||
601 | /* Disable DMA hardware handshaking on MCI */ | ||
602 | mci_writel(host, DMA, mci_readl(host, DMA) & ~MCI_DMAEN); | ||
603 | |||
560 | atmci_dma_cleanup(host); | 604 | atmci_dma_cleanup(host); |
561 | 605 | ||
562 | /* | 606 | /* |
@@ -592,7 +636,7 @@ static void atmci_dma_complete(void *arg) | |||
592 | } | 636 | } |
593 | 637 | ||
594 | static int | 638 | static int |
595 | atmci_submit_data_dma(struct atmel_mci *host, struct mmc_data *data) | 639 | atmci_prepare_data_dma(struct atmel_mci *host, struct mmc_data *data) |
596 | { | 640 | { |
597 | struct dma_chan *chan; | 641 | struct dma_chan *chan; |
598 | struct dma_async_tx_descriptor *desc; | 642 | struct dma_async_tx_descriptor *desc; |
@@ -624,6 +668,9 @@ atmci_submit_data_dma(struct atmel_mci *host, struct mmc_data *data) | |||
624 | if (!chan) | 668 | if (!chan) |
625 | return -ENODEV; | 669 | return -ENODEV; |
626 | 670 | ||
671 | if (atmci_is_mci2()) | ||
672 | mci_writel(host, DMA, MCI_DMA_CHKSIZE(3) | MCI_DMAEN); | ||
673 | |||
627 | if (data->flags & MMC_DATA_READ) | 674 | if (data->flags & MMC_DATA_READ) |
628 | direction = DMA_FROM_DEVICE; | 675 | direction = DMA_FROM_DEVICE; |
629 | else | 676 | else |
@@ -641,10 +688,6 @@ atmci_submit_data_dma(struct atmel_mci *host, struct mmc_data *data) | |||
641 | host->dma.data_desc = desc; | 688 | host->dma.data_desc = desc; |
642 | desc->callback = atmci_dma_complete; | 689 | desc->callback = atmci_dma_complete; |
643 | desc->callback_param = host; | 690 | desc->callback_param = host; |
644 | desc->tx_submit(desc); | ||
645 | |||
646 | /* Go! */ | ||
647 | chan->device->device_issue_pending(chan); | ||
648 | 691 | ||
649 | return 0; | 692 | return 0; |
650 | unmap_exit: | 693 | unmap_exit: |
@@ -652,13 +695,26 @@ unmap_exit: | |||
652 | return -ENOMEM; | 695 | return -ENOMEM; |
653 | } | 696 | } |
654 | 697 | ||
698 | static void atmci_submit_data(struct atmel_mci *host) | ||
699 | { | ||
700 | struct dma_chan *chan = host->data_chan; | ||
701 | struct dma_async_tx_descriptor *desc = host->dma.data_desc; | ||
702 | |||
703 | if (chan) { | ||
704 | desc->tx_submit(desc); | ||
705 | chan->device->device_issue_pending(chan); | ||
706 | } | ||
707 | } | ||
708 | |||
655 | #else /* CONFIG_MMC_ATMELMCI_DMA */ | 709 | #else /* CONFIG_MMC_ATMELMCI_DMA */ |
656 | 710 | ||
657 | static int atmci_submit_data_dma(struct atmel_mci *host, struct mmc_data *data) | 711 | static int atmci_prepare_data_dma(struct atmel_mci *host, struct mmc_data *data) |
658 | { | 712 | { |
659 | return -ENOSYS; | 713 | return -ENOSYS; |
660 | } | 714 | } |
661 | 715 | ||
716 | static void atmci_submit_data(struct atmel_mci *host) {} | ||
717 | |||
662 | static void atmci_stop_dma(struct atmel_mci *host) | 718 | static void atmci_stop_dma(struct atmel_mci *host) |
663 | { | 719 | { |
664 | /* Data transfer was stopped by the interrupt handler */ | 720 | /* Data transfer was stopped by the interrupt handler */ |
@@ -672,7 +728,7 @@ static void atmci_stop_dma(struct atmel_mci *host) | |||
672 | * Returns a mask of interrupt flags to be enabled after the whole | 728 | * Returns a mask of interrupt flags to be enabled after the whole |
673 | * request has been prepared. | 729 | * request has been prepared. |
674 | */ | 730 | */ |
675 | static u32 atmci_submit_data(struct atmel_mci *host, struct mmc_data *data) | 731 | static u32 atmci_prepare_data(struct atmel_mci *host, struct mmc_data *data) |
676 | { | 732 | { |
677 | u32 iflags; | 733 | u32 iflags; |
678 | 734 | ||
@@ -683,7 +739,7 @@ static u32 atmci_submit_data(struct atmel_mci *host, struct mmc_data *data) | |||
683 | host->data = data; | 739 | host->data = data; |
684 | 740 | ||
685 | iflags = ATMCI_DATA_ERROR_FLAGS; | 741 | iflags = ATMCI_DATA_ERROR_FLAGS; |
686 | if (atmci_submit_data_dma(host, data)) { | 742 | if (atmci_prepare_data_dma(host, data)) { |
687 | host->data_chan = NULL; | 743 | host->data_chan = NULL; |
688 | 744 | ||
689 | /* | 745 | /* |
@@ -729,6 +785,8 @@ static void atmci_start_request(struct atmel_mci *host, | |||
729 | mci_writel(host, CR, MCI_CR_SWRST); | 785 | mci_writel(host, CR, MCI_CR_SWRST); |
730 | mci_writel(host, CR, MCI_CR_MCIEN); | 786 | mci_writel(host, CR, MCI_CR_MCIEN); |
731 | mci_writel(host, MR, host->mode_reg); | 787 | mci_writel(host, MR, host->mode_reg); |
788 | if (atmci_is_mci2()) | ||
789 | mci_writel(host, CFG, host->cfg_reg); | ||
732 | host->need_reset = false; | 790 | host->need_reset = false; |
733 | } | 791 | } |
734 | mci_writel(host, SDCR, slot->sdc_reg); | 792 | mci_writel(host, SDCR, slot->sdc_reg); |
@@ -744,6 +802,7 @@ static void atmci_start_request(struct atmel_mci *host, | |||
744 | while (!(mci_readl(host, SR) & MCI_CMDRDY)) | 802 | while (!(mci_readl(host, SR) & MCI_CMDRDY)) |
745 | cpu_relax(); | 803 | cpu_relax(); |
746 | } | 804 | } |
805 | iflags = 0; | ||
747 | data = mrq->data; | 806 | data = mrq->data; |
748 | if (data) { | 807 | if (data) { |
749 | atmci_set_timeout(host, slot, data); | 808 | atmci_set_timeout(host, slot, data); |
@@ -753,15 +812,17 @@ static void atmci_start_request(struct atmel_mci *host, | |||
753 | | MCI_BLKLEN(data->blksz)); | 812 | | MCI_BLKLEN(data->blksz)); |
754 | dev_vdbg(&slot->mmc->class_dev, "BLKR=0x%08x\n", | 813 | dev_vdbg(&slot->mmc->class_dev, "BLKR=0x%08x\n", |
755 | MCI_BCNT(data->blocks) | MCI_BLKLEN(data->blksz)); | 814 | MCI_BCNT(data->blocks) | MCI_BLKLEN(data->blksz)); |
815 | |||
816 | iflags |= atmci_prepare_data(host, data); | ||
756 | } | 817 | } |
757 | 818 | ||
758 | iflags = MCI_CMDRDY; | 819 | iflags |= MCI_CMDRDY; |
759 | cmd = mrq->cmd; | 820 | cmd = mrq->cmd; |
760 | cmdflags = atmci_prepare_command(slot->mmc, cmd); | 821 | cmdflags = atmci_prepare_command(slot->mmc, cmd); |
761 | atmci_start_command(host, cmd, cmdflags); | 822 | atmci_start_command(host, cmd, cmdflags); |
762 | 823 | ||
763 | if (data) | 824 | if (data) |
764 | iflags |= atmci_submit_data(host, data); | 825 | atmci_submit_data(host); |
765 | 826 | ||
766 | if (mrq->stop) { | 827 | if (mrq->stop) { |
767 | host->stop_cmdr = atmci_prepare_command(slot->mmc, mrq->stop); | 828 | host->stop_cmdr = atmci_prepare_command(slot->mmc, mrq->stop); |
@@ -857,6 +918,8 @@ static void atmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) | |||
857 | clk_enable(host->mck); | 918 | clk_enable(host->mck); |
858 | mci_writel(host, CR, MCI_CR_SWRST); | 919 | mci_writel(host, CR, MCI_CR_SWRST); |
859 | mci_writel(host, CR, MCI_CR_MCIEN); | 920 | mci_writel(host, CR, MCI_CR_MCIEN); |
921 | if (atmci_is_mci2()) | ||
922 | mci_writel(host, CFG, host->cfg_reg); | ||
860 | } | 923 | } |
861 | 924 | ||
862 | /* | 925 | /* |
@@ -1037,8 +1100,8 @@ static void atmci_command_complete(struct atmel_mci *host, | |||
1037 | "command error: status=0x%08x\n", status); | 1100 | "command error: status=0x%08x\n", status); |
1038 | 1101 | ||
1039 | if (cmd->data) { | 1102 | if (cmd->data) { |
1040 | host->data = NULL; | ||
1041 | atmci_stop_dma(host); | 1103 | atmci_stop_dma(host); |
1104 | host->data = NULL; | ||
1042 | mci_writel(host, IDR, MCI_NOTBUSY | 1105 | mci_writel(host, IDR, MCI_NOTBUSY |
1043 | | MCI_TXRDY | MCI_RXRDY | 1106 | | MCI_TXRDY | MCI_RXRDY |
1044 | | ATMCI_DATA_ERROR_FLAGS); | 1107 | | ATMCI_DATA_ERROR_FLAGS); |
@@ -1095,6 +1158,8 @@ static void atmci_detect_change(unsigned long data) | |||
1095 | mci_writel(host, CR, MCI_CR_SWRST); | 1158 | mci_writel(host, CR, MCI_CR_SWRST); |
1096 | mci_writel(host, CR, MCI_CR_MCIEN); | 1159 | mci_writel(host, CR, MCI_CR_MCIEN); |
1097 | mci_writel(host, MR, host->mode_reg); | 1160 | mci_writel(host, MR, host->mode_reg); |
1161 | if (atmci_is_mci2()) | ||
1162 | mci_writel(host, CFG, host->cfg_reg); | ||
1098 | 1163 | ||
1099 | host->data = NULL; | 1164 | host->data = NULL; |
1100 | host->cmd = NULL; | 1165 | host->cmd = NULL; |
@@ -1229,6 +1294,7 @@ static void atmci_tasklet_func(unsigned long priv) | |||
1229 | } else { | 1294 | } else { |
1230 | data->bytes_xfered = data->blocks * data->blksz; | 1295 | data->bytes_xfered = data->blocks * data->blksz; |
1231 | data->error = 0; | 1296 | data->error = 0; |
1297 | mci_writel(host, IDR, ATMCI_DATA_ERROR_FLAGS); | ||
1232 | } | 1298 | } |
1233 | 1299 | ||
1234 | if (!data->stop) { | 1300 | if (!data->stop) { |
@@ -1584,14 +1650,47 @@ static void __exit atmci_cleanup_slot(struct atmel_mci_slot *slot, | |||
1584 | #ifdef CONFIG_MMC_ATMELMCI_DMA | 1650 | #ifdef CONFIG_MMC_ATMELMCI_DMA |
1585 | static bool filter(struct dma_chan *chan, void *slave) | 1651 | static bool filter(struct dma_chan *chan, void *slave) |
1586 | { | 1652 | { |
1587 | struct dw_dma_slave *dws = slave; | 1653 | struct mci_dma_data *sl = slave; |
1588 | 1654 | ||
1589 | if (dws->dma_dev == chan->device->dev) { | 1655 | if (sl && find_slave_dev(sl) == chan->device->dev) { |
1590 | chan->private = dws; | 1656 | chan->private = slave_data_ptr(sl); |
1591 | return true; | 1657 | return true; |
1592 | } else | 1658 | } else { |
1593 | return false; | 1659 | return false; |
1660 | } | ||
1594 | } | 1661 | } |
1662 | |||
1663 | static void atmci_configure_dma(struct atmel_mci *host) | ||
1664 | { | ||
1665 | struct mci_platform_data *pdata; | ||
1666 | |||
1667 | if (host == NULL) | ||
1668 | return; | ||
1669 | |||
1670 | pdata = host->pdev->dev.platform_data; | ||
1671 | |||
1672 | if (pdata && find_slave_dev(pdata->dma_slave)) { | ||
1673 | dma_cap_mask_t mask; | ||
1674 | |||
1675 | setup_dma_addr(pdata->dma_slave, | ||
1676 | host->mapbase + MCI_TDR, | ||
1677 | host->mapbase + MCI_RDR); | ||
1678 | |||
1679 | /* Try to grab a DMA channel */ | ||
1680 | dma_cap_zero(mask); | ||
1681 | dma_cap_set(DMA_SLAVE, mask); | ||
1682 | host->dma.chan = | ||
1683 | dma_request_channel(mask, filter, pdata->dma_slave); | ||
1684 | } | ||
1685 | if (!host->dma.chan) | ||
1686 | dev_notice(&host->pdev->dev, "DMA not available, using PIO\n"); | ||
1687 | else | ||
1688 | dev_info(&host->pdev->dev, | ||
1689 | "Using %s for DMA transfers\n", | ||
1690 | dma_chan_name(host->dma.chan)); | ||
1691 | } | ||
1692 | #else | ||
1693 | static void atmci_configure_dma(struct atmel_mci *host) {} | ||
1595 | #endif | 1694 | #endif |
1596 | 1695 | ||
1597 | static int __init atmci_probe(struct platform_device *pdev) | 1696 | static int __init atmci_probe(struct platform_device *pdev) |
@@ -1645,22 +1744,7 @@ static int __init atmci_probe(struct platform_device *pdev) | |||
1645 | if (ret) | 1744 | if (ret) |
1646 | goto err_request_irq; | 1745 | goto err_request_irq; |
1647 | 1746 | ||
1648 | #ifdef CONFIG_MMC_ATMELMCI_DMA | 1747 | atmci_configure_dma(host); |
1649 | if (pdata->dma_slave.dma_dev) { | ||
1650 | struct dw_dma_slave *dws = &pdata->dma_slave; | ||
1651 | dma_cap_mask_t mask; | ||
1652 | |||
1653 | dws->tx_reg = regs->start + MCI_TDR; | ||
1654 | dws->rx_reg = regs->start + MCI_RDR; | ||
1655 | |||
1656 | /* Try to grab a DMA channel */ | ||
1657 | dma_cap_zero(mask); | ||
1658 | dma_cap_set(DMA_SLAVE, mask); | ||
1659 | host->dma.chan = dma_request_channel(mask, filter, dws); | ||
1660 | } | ||
1661 | if (!host->dma.chan) | ||
1662 | dev_notice(&pdev->dev, "DMA not available, using PIO\n"); | ||
1663 | #endif /* CONFIG_MMC_ATMELMCI_DMA */ | ||
1664 | 1748 | ||
1665 | platform_set_drvdata(pdev, host); | 1749 | platform_set_drvdata(pdev, host); |
1666 | 1750 | ||
@@ -1669,13 +1753,13 @@ static int __init atmci_probe(struct platform_device *pdev) | |||
1669 | ret = -ENODEV; | 1753 | ret = -ENODEV; |
1670 | if (pdata->slot[0].bus_width) { | 1754 | if (pdata->slot[0].bus_width) { |
1671 | ret = atmci_init_slot(host, &pdata->slot[0], | 1755 | ret = atmci_init_slot(host, &pdata->slot[0], |
1672 | MCI_SDCSEL_SLOT_A, 0); | 1756 | 0, MCI_SDCSEL_SLOT_A); |
1673 | if (!ret) | 1757 | if (!ret) |
1674 | nr_slots++; | 1758 | nr_slots++; |
1675 | } | 1759 | } |
1676 | if (pdata->slot[1].bus_width) { | 1760 | if (pdata->slot[1].bus_width) { |
1677 | ret = atmci_init_slot(host, &pdata->slot[1], | 1761 | ret = atmci_init_slot(host, &pdata->slot[1], |
1678 | MCI_SDCSEL_SLOT_B, 1); | 1762 | 1, MCI_SDCSEL_SLOT_B); |
1679 | if (!ret) | 1763 | if (!ret) |
1680 | nr_slots++; | 1764 | nr_slots++; |
1681 | } | 1765 | } |
diff --git a/drivers/mmc/host/au1xmmc.c b/drivers/mmc/host/au1xmmc.c index d3f55615c099..f5834449400e 100644 --- a/drivers/mmc/host/au1xmmc.c +++ b/drivers/mmc/host/au1xmmc.c | |||
@@ -41,6 +41,7 @@ | |||
41 | #include <linux/scatterlist.h> | 41 | #include <linux/scatterlist.h> |
42 | #include <linux/leds.h> | 42 | #include <linux/leds.h> |
43 | #include <linux/mmc/host.h> | 43 | #include <linux/mmc/host.h> |
44 | #include <linux/slab.h> | ||
44 | 45 | ||
45 | #include <asm/io.h> | 46 | #include <asm/io.h> |
46 | #include <asm/mach-au1x00/au1000.h> | 47 | #include <asm/mach-au1x00/au1000.h> |
@@ -650,11 +651,11 @@ static int au1xmmc_prepare_data(struct au1xmmc_host *host, | |||
650 | flags = DDMA_FLAGS_IE; | 651 | flags = DDMA_FLAGS_IE; |
651 | 652 | ||
652 | if (host->flags & HOST_F_XMIT) { | 653 | if (host->flags & HOST_F_XMIT) { |
653 | ret = au1xxx_dbdma_put_source_flags(channel, | 654 | ret = au1xxx_dbdma_put_source(channel, |
654 | (void *)sg_virt(sg), len, flags); | 655 | sg_phys(sg), len, flags); |
655 | } else { | 656 | } else { |
656 | ret = au1xxx_dbdma_put_dest_flags(channel, | 657 | ret = au1xxx_dbdma_put_dest(channel, |
657 | (void *)sg_virt(sg), len, flags); | 658 | sg_phys(sg), len, flags); |
658 | } | 659 | } |
659 | 660 | ||
660 | if (!ret) | 661 | if (!ret) |
@@ -1017,6 +1018,10 @@ static int __devinit au1xmmc_probe(struct platform_device *pdev) | |||
1017 | } else | 1018 | } else |
1018 | mmc->caps |= MMC_CAP_NEEDS_POLL; | 1019 | mmc->caps |= MMC_CAP_NEEDS_POLL; |
1019 | 1020 | ||
1021 | /* platform may not be able to use all advertised caps */ | ||
1022 | if (host->platdata) | ||
1023 | mmc->caps &= ~(host->platdata->mask_host_caps); | ||
1024 | |||
1020 | tasklet_init(&host->data_task, au1xmmc_tasklet_data, | 1025 | tasklet_init(&host->data_task, au1xmmc_tasklet_data, |
1021 | (unsigned long)host); | 1026 | (unsigned long)host); |
1022 | 1027 | ||
diff --git a/drivers/mmc/host/bfin_sdh.c b/drivers/mmc/host/bfin_sdh.c new file mode 100644 index 000000000000..6919e844072c --- /dev/null +++ b/drivers/mmc/host/bfin_sdh.c | |||
@@ -0,0 +1,644 @@ | |||
1 | /* | ||
2 | * bfin_sdh.c - Analog Devices Blackfin SDH Controller | ||
3 | * | ||
4 | * Copyright (C) 2007-2009 Analog Device Inc. | ||
5 | * | ||
6 | * Licensed under the GPL-2 or later. | ||
7 | */ | ||
8 | |||
9 | #define DRIVER_NAME "bfin-sdh" | ||
10 | |||
11 | #include <linux/module.h> | ||
12 | #include <linux/init.h> | ||
13 | #include <linux/ioport.h> | ||
14 | #include <linux/platform_device.h> | ||
15 | #include <linux/delay.h> | ||
16 | #include <linux/interrupt.h> | ||
17 | #include <linux/dma-mapping.h> | ||
18 | #include <linux/mmc/host.h> | ||
19 | #include <linux/proc_fs.h> | ||
20 | #include <linux/gfp.h> | ||
21 | |||
22 | #include <asm/cacheflush.h> | ||
23 | #include <asm/dma.h> | ||
24 | #include <asm/portmux.h> | ||
25 | #include <asm/bfin_sdh.h> | ||
26 | |||
27 | #if defined(CONFIG_BF51x) | ||
28 | #define bfin_read_SDH_PWR_CTL bfin_read_RSI_PWR_CTL | ||
29 | #define bfin_write_SDH_PWR_CTL bfin_write_RSI_PWR_CTL | ||
30 | #define bfin_read_SDH_CLK_CTL bfin_read_RSI_CLK_CTL | ||
31 | #define bfin_write_SDH_CLK_CTL bfin_write_RSI_CLK_CTL | ||
32 | #define bfin_write_SDH_ARGUMENT bfin_write_RSI_ARGUMENT | ||
33 | #define bfin_write_SDH_COMMAND bfin_write_RSI_COMMAND | ||
34 | #define bfin_write_SDH_DATA_TIMER bfin_write_RSI_DATA_TIMER | ||
35 | #define bfin_read_SDH_RESPONSE0 bfin_read_RSI_RESPONSE0 | ||
36 | #define bfin_read_SDH_RESPONSE1 bfin_read_RSI_RESPONSE1 | ||
37 | #define bfin_read_SDH_RESPONSE2 bfin_read_RSI_RESPONSE2 | ||
38 | #define bfin_read_SDH_RESPONSE3 bfin_read_RSI_RESPONSE3 | ||
39 | #define bfin_write_SDH_DATA_LGTH bfin_write_RSI_DATA_LGTH | ||
40 | #define bfin_read_SDH_DATA_CTL bfin_read_RSI_DATA_CTL | ||
41 | #define bfin_write_SDH_DATA_CTL bfin_write_RSI_DATA_CTL | ||
42 | #define bfin_read_SDH_DATA_CNT bfin_read_RSI_DATA_CNT | ||
43 | #define bfin_write_SDH_STATUS_CLR bfin_write_RSI_STATUS_CLR | ||
44 | #define bfin_read_SDH_E_STATUS bfin_read_RSI_E_STATUS | ||
45 | #define bfin_write_SDH_E_STATUS bfin_write_RSI_E_STATUS | ||
46 | #define bfin_read_SDH_STATUS bfin_read_RSI_STATUS | ||
47 | #define bfin_write_SDH_MASK0 bfin_write_RSI_MASK0 | ||
48 | #define bfin_read_SDH_CFG bfin_read_RSI_CFG | ||
49 | #define bfin_write_SDH_CFG bfin_write_RSI_CFG | ||
50 | #endif | ||
51 | |||
52 | struct dma_desc_array { | ||
53 | unsigned long start_addr; | ||
54 | unsigned short cfg; | ||
55 | unsigned short x_count; | ||
56 | short x_modify; | ||
57 | } __packed; | ||
58 | |||
59 | struct sdh_host { | ||
60 | struct mmc_host *mmc; | ||
61 | spinlock_t lock; | ||
62 | struct resource *res; | ||
63 | void __iomem *base; | ||
64 | int irq; | ||
65 | int stat_irq; | ||
66 | int dma_ch; | ||
67 | int dma_dir; | ||
68 | struct dma_desc_array *sg_cpu; | ||
69 | dma_addr_t sg_dma; | ||
70 | int dma_len; | ||
71 | |||
72 | unsigned int imask; | ||
73 | unsigned int power_mode; | ||
74 | unsigned int clk_div; | ||
75 | |||
76 | struct mmc_request *mrq; | ||
77 | struct mmc_command *cmd; | ||
78 | struct mmc_data *data; | ||
79 | }; | ||
80 | |||
81 | static struct bfin_sd_host *get_sdh_data(struct platform_device *pdev) | ||
82 | { | ||
83 | return pdev->dev.platform_data; | ||
84 | } | ||
85 | |||
86 | static void sdh_stop_clock(struct sdh_host *host) | ||
87 | { | ||
88 | bfin_write_SDH_CLK_CTL(bfin_read_SDH_CLK_CTL() & ~CLK_E); | ||
89 | SSYNC(); | ||
90 | } | ||
91 | |||
92 | static void sdh_enable_stat_irq(struct sdh_host *host, unsigned int mask) | ||
93 | { | ||
94 | unsigned long flags; | ||
95 | |||
96 | spin_lock_irqsave(&host->lock, flags); | ||
97 | host->imask |= mask; | ||
98 | bfin_write_SDH_MASK0(mask); | ||
99 | SSYNC(); | ||
100 | spin_unlock_irqrestore(&host->lock, flags); | ||
101 | } | ||
102 | |||
103 | static void sdh_disable_stat_irq(struct sdh_host *host, unsigned int mask) | ||
104 | { | ||
105 | unsigned long flags; | ||
106 | |||
107 | spin_lock_irqsave(&host->lock, flags); | ||
108 | host->imask &= ~mask; | ||
109 | bfin_write_SDH_MASK0(host->imask); | ||
110 | SSYNC(); | ||
111 | spin_unlock_irqrestore(&host->lock, flags); | ||
112 | } | ||
113 | |||
114 | static int sdh_setup_data(struct sdh_host *host, struct mmc_data *data) | ||
115 | { | ||
116 | unsigned int length; | ||
117 | unsigned int data_ctl; | ||
118 | unsigned int dma_cfg; | ||
119 | unsigned int cycle_ns, timeout; | ||
120 | |||
121 | dev_dbg(mmc_dev(host->mmc), "%s enter flags: 0x%x\n", __func__, data->flags); | ||
122 | host->data = data; | ||
123 | data_ctl = 0; | ||
124 | dma_cfg = 0; | ||
125 | |||
126 | length = data->blksz * data->blocks; | ||
127 | bfin_write_SDH_DATA_LGTH(length); | ||
128 | |||
129 | if (data->flags & MMC_DATA_STREAM) | ||
130 | data_ctl |= DTX_MODE; | ||
131 | |||
132 | if (data->flags & MMC_DATA_READ) | ||
133 | data_ctl |= DTX_DIR; | ||
134 | /* Only supports power-of-2 block size */ | ||
135 | if (data->blksz & (data->blksz - 1)) | ||
136 | return -EINVAL; | ||
137 | data_ctl |= ((ffs(data->blksz) - 1) << 4); | ||
138 | |||
139 | bfin_write_SDH_DATA_CTL(data_ctl); | ||
140 | /* the time of a host clock period in ns */ | ||
141 | cycle_ns = 1000000000 / (get_sclk() / (2 * (host->clk_div + 1))); | ||
142 | timeout = data->timeout_ns / cycle_ns; | ||
143 | timeout += data->timeout_clks; | ||
144 | bfin_write_SDH_DATA_TIMER(timeout); | ||
145 | SSYNC(); | ||
146 | |||
147 | if (data->flags & MMC_DATA_READ) { | ||
148 | host->dma_dir = DMA_FROM_DEVICE; | ||
149 | dma_cfg |= WNR; | ||
150 | } else | ||
151 | host->dma_dir = DMA_TO_DEVICE; | ||
152 | |||
153 | sdh_enable_stat_irq(host, (DAT_CRC_FAIL | DAT_TIME_OUT | DAT_END)); | ||
154 | host->dma_len = dma_map_sg(mmc_dev(host->mmc), data->sg, data->sg_len, host->dma_dir); | ||
155 | #if defined(CONFIG_BF54x) | ||
156 | dma_cfg |= DMAFLOW_ARRAY | NDSIZE_5 | RESTART | WDSIZE_32 | DMAEN; | ||
157 | { | ||
158 | struct scatterlist *sg; | ||
159 | int i; | ||
160 | for_each_sg(data->sg, sg, host->dma_len, i) { | ||
161 | host->sg_cpu[i].start_addr = sg_dma_address(sg); | ||
162 | host->sg_cpu[i].cfg = dma_cfg; | ||
163 | host->sg_cpu[i].x_count = sg_dma_len(sg) / 4; | ||
164 | host->sg_cpu[i].x_modify = 4; | ||
165 | dev_dbg(mmc_dev(host->mmc), "%d: start_addr:0x%lx, " | ||
166 | "cfg:0x%x, x_count:0x%x, x_modify:0x%x\n", | ||
167 | i, host->sg_cpu[i].start_addr, | ||
168 | host->sg_cpu[i].cfg, host->sg_cpu[i].x_count, | ||
169 | host->sg_cpu[i].x_modify); | ||
170 | } | ||
171 | } | ||
172 | flush_dcache_range((unsigned int)host->sg_cpu, | ||
173 | (unsigned int)host->sg_cpu + | ||
174 | host->dma_len * sizeof(struct dma_desc_array)); | ||
175 | /* Set the last descriptor to stop mode */ | ||
176 | host->sg_cpu[host->dma_len - 1].cfg &= ~(DMAFLOW | NDSIZE); | ||
177 | host->sg_cpu[host->dma_len - 1].cfg |= DI_EN; | ||
178 | |||
179 | set_dma_curr_desc_addr(host->dma_ch, (unsigned long *)host->sg_dma); | ||
180 | set_dma_x_count(host->dma_ch, 0); | ||
181 | set_dma_x_modify(host->dma_ch, 0); | ||
182 | set_dma_config(host->dma_ch, dma_cfg); | ||
183 | #elif defined(CONFIG_BF51x) | ||
184 | /* RSI DMA doesn't work in array mode */ | ||
185 | dma_cfg |= WDSIZE_32 | DMAEN; | ||
186 | set_dma_start_addr(host->dma_ch, sg_dma_address(&data->sg[0])); | ||
187 | set_dma_x_count(host->dma_ch, length / 4); | ||
188 | set_dma_x_modify(host->dma_ch, 4); | ||
189 | set_dma_config(host->dma_ch, dma_cfg); | ||
190 | #endif | ||
191 | bfin_write_SDH_DATA_CTL(bfin_read_SDH_DATA_CTL() | DTX_DMA_E | DTX_E); | ||
192 | |||
193 | SSYNC(); | ||
194 | |||
195 | dev_dbg(mmc_dev(host->mmc), "%s exit\n", __func__); | ||
196 | return 0; | ||
197 | } | ||
198 | |||
199 | static void sdh_start_cmd(struct sdh_host *host, struct mmc_command *cmd) | ||
200 | { | ||
201 | unsigned int sdh_cmd; | ||
202 | unsigned int stat_mask; | ||
203 | |||
204 | dev_dbg(mmc_dev(host->mmc), "%s enter cmd: 0x%p\n", __func__, cmd); | ||
205 | WARN_ON(host->cmd != NULL); | ||
206 | host->cmd = cmd; | ||
207 | |||
208 | sdh_cmd = 0; | ||
209 | stat_mask = 0; | ||
210 | |||
211 | sdh_cmd |= cmd->opcode; | ||
212 | |||
213 | if (cmd->flags & MMC_RSP_PRESENT) { | ||
214 | sdh_cmd |= CMD_RSP; | ||
215 | stat_mask |= CMD_RESP_END; | ||
216 | } else { | ||
217 | stat_mask |= CMD_SENT; | ||
218 | } | ||
219 | |||
220 | if (cmd->flags & MMC_RSP_136) | ||
221 | sdh_cmd |= CMD_L_RSP; | ||
222 | |||
223 | stat_mask |= CMD_CRC_FAIL | CMD_TIME_OUT; | ||
224 | |||
225 | sdh_enable_stat_irq(host, stat_mask); | ||
226 | |||
227 | bfin_write_SDH_ARGUMENT(cmd->arg); | ||
228 | bfin_write_SDH_COMMAND(sdh_cmd | CMD_E); | ||
229 | bfin_write_SDH_CLK_CTL(bfin_read_SDH_CLK_CTL() | CLK_E); | ||
230 | SSYNC(); | ||
231 | } | ||
232 | |||
233 | static void sdh_finish_request(struct sdh_host *host, struct mmc_request *mrq) | ||
234 | { | ||
235 | dev_dbg(mmc_dev(host->mmc), "%s enter\n", __func__); | ||
236 | host->mrq = NULL; | ||
237 | host->cmd = NULL; | ||
238 | host->data = NULL; | ||
239 | mmc_request_done(host->mmc, mrq); | ||
240 | } | ||
241 | |||
242 | static int sdh_cmd_done(struct sdh_host *host, unsigned int stat) | ||
243 | { | ||
244 | struct mmc_command *cmd = host->cmd; | ||
245 | int ret = 0; | ||
246 | |||
247 | dev_dbg(mmc_dev(host->mmc), "%s enter cmd: %p\n", __func__, cmd); | ||
248 | if (!cmd) | ||
249 | return 0; | ||
250 | |||
251 | host->cmd = NULL; | ||
252 | |||
253 | if (cmd->flags & MMC_RSP_PRESENT) { | ||
254 | cmd->resp[0] = bfin_read_SDH_RESPONSE0(); | ||
255 | if (cmd->flags & MMC_RSP_136) { | ||
256 | cmd->resp[1] = bfin_read_SDH_RESPONSE1(); | ||
257 | cmd->resp[2] = bfin_read_SDH_RESPONSE2(); | ||
258 | cmd->resp[3] = bfin_read_SDH_RESPONSE3(); | ||
259 | } | ||
260 | } | ||
261 | if (stat & CMD_TIME_OUT) | ||
262 | cmd->error = -ETIMEDOUT; | ||
263 | else if (stat & CMD_CRC_FAIL && cmd->flags & MMC_RSP_CRC) | ||
264 | cmd->error = -EILSEQ; | ||
265 | |||
266 | sdh_disable_stat_irq(host, (CMD_SENT | CMD_RESP_END | CMD_TIME_OUT | CMD_CRC_FAIL)); | ||
267 | |||
268 | if (host->data && !cmd->error) { | ||
269 | if (host->data->flags & MMC_DATA_WRITE) { | ||
270 | ret = sdh_setup_data(host, host->data); | ||
271 | if (ret) | ||
272 | return 0; | ||
273 | } | ||
274 | |||
275 | sdh_enable_stat_irq(host, DAT_END | RX_OVERRUN | TX_UNDERRUN | DAT_TIME_OUT); | ||
276 | } else | ||
277 | sdh_finish_request(host, host->mrq); | ||
278 | |||
279 | return 1; | ||
280 | } | ||
281 | |||
282 | static int sdh_data_done(struct sdh_host *host, unsigned int stat) | ||
283 | { | ||
284 | struct mmc_data *data = host->data; | ||
285 | |||
286 | dev_dbg(mmc_dev(host->mmc), "%s enter stat: 0x%x\n", __func__, stat); | ||
287 | if (!data) | ||
288 | return 0; | ||
289 | |||
290 | disable_dma(host->dma_ch); | ||
291 | dma_unmap_sg(mmc_dev(host->mmc), data->sg, data->sg_len, | ||
292 | host->dma_dir); | ||
293 | |||
294 | if (stat & DAT_TIME_OUT) | ||
295 | data->error = -ETIMEDOUT; | ||
296 | else if (stat & DAT_CRC_FAIL) | ||
297 | data->error = -EILSEQ; | ||
298 | else if (stat & (RX_OVERRUN | TX_UNDERRUN)) | ||
299 | data->error = -EIO; | ||
300 | |||
301 | if (!data->error) | ||
302 | data->bytes_xfered = data->blocks * data->blksz; | ||
303 | else | ||
304 | data->bytes_xfered = 0; | ||
305 | |||
306 | sdh_disable_stat_irq(host, DAT_END | DAT_TIME_OUT | DAT_CRC_FAIL | RX_OVERRUN | TX_UNDERRUN); | ||
307 | bfin_write_SDH_STATUS_CLR(DAT_END_STAT | DAT_TIMEOUT_STAT | \ | ||
308 | DAT_CRC_FAIL_STAT | DAT_BLK_END_STAT | RX_OVERRUN | TX_UNDERRUN); | ||
309 | bfin_write_SDH_DATA_CTL(0); | ||
310 | SSYNC(); | ||
311 | |||
312 | host->data = NULL; | ||
313 | if (host->mrq->stop) { | ||
314 | sdh_stop_clock(host); | ||
315 | sdh_start_cmd(host, host->mrq->stop); | ||
316 | } else { | ||
317 | sdh_finish_request(host, host->mrq); | ||
318 | } | ||
319 | |||
320 | return 1; | ||
321 | } | ||
322 | |||
323 | static void sdh_request(struct mmc_host *mmc, struct mmc_request *mrq) | ||
324 | { | ||
325 | struct sdh_host *host = mmc_priv(mmc); | ||
326 | int ret = 0; | ||
327 | |||
328 | dev_dbg(mmc_dev(host->mmc), "%s enter, mrp:%p, cmd:%p\n", __func__, mrq, mrq->cmd); | ||
329 | WARN_ON(host->mrq != NULL); | ||
330 | |||
331 | host->mrq = mrq; | ||
332 | host->data = mrq->data; | ||
333 | |||
334 | if (mrq->data && mrq->data->flags & MMC_DATA_READ) { | ||
335 | ret = sdh_setup_data(host, mrq->data); | ||
336 | if (ret) | ||
337 | return; | ||
338 | } | ||
339 | |||
340 | sdh_start_cmd(host, mrq->cmd); | ||
341 | } | ||
342 | |||
343 | static void sdh_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) | ||
344 | { | ||
345 | struct sdh_host *host; | ||
346 | unsigned long flags; | ||
347 | u16 clk_ctl = 0; | ||
348 | u16 pwr_ctl = 0; | ||
349 | u16 cfg; | ||
350 | host = mmc_priv(mmc); | ||
351 | |||
352 | spin_lock_irqsave(&host->lock, flags); | ||
353 | if (ios->clock) { | ||
354 | unsigned long sys_clk, ios_clk; | ||
355 | unsigned char clk_div; | ||
356 | ios_clk = 2 * ios->clock; | ||
357 | sys_clk = get_sclk(); | ||
358 | clk_div = sys_clk / ios_clk; | ||
359 | if (sys_clk % ios_clk == 0) | ||
360 | clk_div -= 1; | ||
361 | clk_div = min_t(unsigned char, clk_div, 0xFF); | ||
362 | clk_ctl |= clk_div; | ||
363 | clk_ctl |= CLK_E; | ||
364 | host->clk_div = clk_div; | ||
365 | } else | ||
366 | sdh_stop_clock(host); | ||
367 | |||
368 | if (ios->bus_mode == MMC_BUSMODE_OPENDRAIN) | ||
369 | #ifdef CONFIG_SDH_BFIN_MISSING_CMD_PULLUP_WORKAROUND | ||
370 | pwr_ctl |= ROD_CTL; | ||
371 | #else | ||
372 | pwr_ctl |= SD_CMD_OD | ROD_CTL; | ||
373 | #endif | ||
374 | |||
375 | if (ios->bus_width == MMC_BUS_WIDTH_4) { | ||
376 | cfg = bfin_read_SDH_CFG(); | ||
377 | cfg &= ~PD_SDDAT3; | ||
378 | cfg |= PUP_SDDAT3; | ||
379 | /* Enable 4 bit SDIO */ | ||
380 | cfg |= (SD4E | MWE); | ||
381 | bfin_write_SDH_CFG(cfg); | ||
382 | clk_ctl |= WIDE_BUS; | ||
383 | } else { | ||
384 | cfg = bfin_read_SDH_CFG(); | ||
385 | cfg |= MWE; | ||
386 | bfin_write_SDH_CFG(cfg); | ||
387 | } | ||
388 | |||
389 | bfin_write_SDH_CLK_CTL(clk_ctl); | ||
390 | |||
391 | host->power_mode = ios->power_mode; | ||
392 | if (ios->power_mode == MMC_POWER_ON) | ||
393 | pwr_ctl |= PWR_ON; | ||
394 | |||
395 | bfin_write_SDH_PWR_CTL(pwr_ctl); | ||
396 | SSYNC(); | ||
397 | |||
398 | spin_unlock_irqrestore(&host->lock, flags); | ||
399 | |||
400 | dev_dbg(mmc_dev(host->mmc), "SDH: clk_div = 0x%x actual clock:%ld expected clock:%d\n", | ||
401 | host->clk_div, | ||
402 | host->clk_div ? get_sclk() / (2 * (host->clk_div + 1)) : 0, | ||
403 | ios->clock); | ||
404 | } | ||
405 | |||
406 | static const struct mmc_host_ops sdh_ops = { | ||
407 | .request = sdh_request, | ||
408 | .set_ios = sdh_set_ios, | ||
409 | }; | ||
410 | |||
411 | static irqreturn_t sdh_dma_irq(int irq, void *devid) | ||
412 | { | ||
413 | struct sdh_host *host = devid; | ||
414 | |||
415 | dev_dbg(mmc_dev(host->mmc), "%s enter, irq_stat: 0x%04x\n", __func__, | ||
416 | get_dma_curr_irqstat(host->dma_ch)); | ||
417 | clear_dma_irqstat(host->dma_ch); | ||
418 | SSYNC(); | ||
419 | |||
420 | return IRQ_HANDLED; | ||
421 | } | ||
422 | |||
423 | static irqreturn_t sdh_stat_irq(int irq, void *devid) | ||
424 | { | ||
425 | struct sdh_host *host = devid; | ||
426 | unsigned int status; | ||
427 | int handled = 0; | ||
428 | |||
429 | dev_dbg(mmc_dev(host->mmc), "%s enter\n", __func__); | ||
430 | status = bfin_read_SDH_E_STATUS(); | ||
431 | if (status & SD_CARD_DET) { | ||
432 | mmc_detect_change(host->mmc, 0); | ||
433 | bfin_write_SDH_E_STATUS(SD_CARD_DET); | ||
434 | } | ||
435 | status = bfin_read_SDH_STATUS(); | ||
436 | if (status & (CMD_SENT | CMD_RESP_END | CMD_TIME_OUT | CMD_CRC_FAIL)) { | ||
437 | handled |= sdh_cmd_done(host, status); | ||
438 | bfin_write_SDH_STATUS_CLR(CMD_SENT_STAT | CMD_RESP_END_STAT | \ | ||
439 | CMD_TIMEOUT_STAT | CMD_CRC_FAIL_STAT); | ||
440 | SSYNC(); | ||
441 | } | ||
442 | |||
443 | status = bfin_read_SDH_STATUS(); | ||
444 | if (status & (DAT_END | DAT_TIME_OUT | DAT_CRC_FAIL | RX_OVERRUN | TX_UNDERRUN)) | ||
445 | handled |= sdh_data_done(host, status); | ||
446 | |||
447 | dev_dbg(mmc_dev(host->mmc), "%s exit\n\n", __func__); | ||
448 | |||
449 | return IRQ_RETVAL(handled); | ||
450 | } | ||
451 | |||
452 | static int __devinit sdh_probe(struct platform_device *pdev) | ||
453 | { | ||
454 | struct mmc_host *mmc; | ||
455 | struct sdh_host *host; | ||
456 | struct bfin_sd_host *drv_data = get_sdh_data(pdev); | ||
457 | int ret; | ||
458 | |||
459 | if (!drv_data) { | ||
460 | dev_err(&pdev->dev, "missing platform driver data\n"); | ||
461 | ret = -EINVAL; | ||
462 | goto out; | ||
463 | } | ||
464 | |||
465 | mmc = mmc_alloc_host(sizeof(*mmc), &pdev->dev); | ||
466 | if (!mmc) { | ||
467 | ret = -ENOMEM; | ||
468 | goto out; | ||
469 | } | ||
470 | |||
471 | mmc->ops = &sdh_ops; | ||
472 | mmc->max_phys_segs = 32; | ||
473 | mmc->max_seg_size = 1 << 16; | ||
474 | mmc->max_blk_size = 1 << 11; | ||
475 | mmc->max_blk_count = 1 << 11; | ||
476 | mmc->max_req_size = PAGE_SIZE; | ||
477 | mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34; | ||
478 | mmc->f_max = get_sclk(); | ||
479 | mmc->f_min = mmc->f_max >> 9; | ||
480 | mmc->caps = MMC_CAP_4_BIT_DATA | MMC_CAP_NEEDS_POLL; | ||
481 | host = mmc_priv(mmc); | ||
482 | host->mmc = mmc; | ||
483 | |||
484 | spin_lock_init(&host->lock); | ||
485 | host->irq = drv_data->irq_int0; | ||
486 | host->dma_ch = drv_data->dma_chan; | ||
487 | |||
488 | ret = request_dma(host->dma_ch, DRIVER_NAME "DMA"); | ||
489 | if (ret) { | ||
490 | dev_err(&pdev->dev, "unable to request DMA channel\n"); | ||
491 | goto out1; | ||
492 | } | ||
493 | |||
494 | ret = set_dma_callback(host->dma_ch, sdh_dma_irq, host); | ||
495 | if (ret) { | ||
496 | dev_err(&pdev->dev, "unable to request DMA irq\n"); | ||
497 | goto out2; | ||
498 | } | ||
499 | |||
500 | host->sg_cpu = dma_alloc_coherent(&pdev->dev, PAGE_SIZE, &host->sg_dma, GFP_KERNEL); | ||
501 | if (host->sg_cpu == NULL) { | ||
502 | ret = -ENOMEM; | ||
503 | goto out2; | ||
504 | } | ||
505 | |||
506 | platform_set_drvdata(pdev, mmc); | ||
507 | mmc_add_host(mmc); | ||
508 | |||
509 | ret = request_irq(host->irq, sdh_stat_irq, 0, "SDH Status IRQ", host); | ||
510 | if (ret) { | ||
511 | dev_err(&pdev->dev, "unable to request status irq\n"); | ||
512 | goto out3; | ||
513 | } | ||
514 | |||
515 | ret = peripheral_request_list(drv_data->pin_req, DRIVER_NAME); | ||
516 | if (ret) { | ||
517 | dev_err(&pdev->dev, "unable to request peripheral pins\n"); | ||
518 | goto out4; | ||
519 | } | ||
520 | #if defined(CONFIG_BF54x) | ||
521 | /* Secure Digital Host shares DMA with Nand controller */ | ||
522 | bfin_write_DMAC1_PERIMUX(bfin_read_DMAC1_PERIMUX() | 0x1); | ||
523 | #endif | ||
524 | |||
525 | bfin_write_SDH_CFG(bfin_read_SDH_CFG() | CLKS_EN); | ||
526 | SSYNC(); | ||
527 | |||
528 | /* Disable card inserting detection pin. set MMC_CAP_NEES_POLL, and | ||
529 | * mmc stack will do the detection. | ||
530 | */ | ||
531 | bfin_write_SDH_CFG((bfin_read_SDH_CFG() & 0x1F) | (PUP_SDDAT | PUP_SDDAT3)); | ||
532 | SSYNC(); | ||
533 | |||
534 | return 0; | ||
535 | |||
536 | out4: | ||
537 | free_irq(host->irq, host); | ||
538 | out3: | ||
539 | mmc_remove_host(mmc); | ||
540 | dma_free_coherent(&pdev->dev, PAGE_SIZE, host->sg_cpu, host->sg_dma); | ||
541 | out2: | ||
542 | free_dma(host->dma_ch); | ||
543 | out1: | ||
544 | mmc_free_host(mmc); | ||
545 | out: | ||
546 | return ret; | ||
547 | } | ||
548 | |||
549 | static int __devexit sdh_remove(struct platform_device *pdev) | ||
550 | { | ||
551 | struct mmc_host *mmc = platform_get_drvdata(pdev); | ||
552 | |||
553 | platform_set_drvdata(pdev, NULL); | ||
554 | |||
555 | if (mmc) { | ||
556 | struct sdh_host *host = mmc_priv(mmc); | ||
557 | |||
558 | mmc_remove_host(mmc); | ||
559 | |||
560 | sdh_stop_clock(host); | ||
561 | free_irq(host->irq, host); | ||
562 | free_dma(host->dma_ch); | ||
563 | dma_free_coherent(&pdev->dev, PAGE_SIZE, host->sg_cpu, host->sg_dma); | ||
564 | |||
565 | mmc_free_host(mmc); | ||
566 | } | ||
567 | |||
568 | return 0; | ||
569 | } | ||
570 | |||
571 | #ifdef CONFIG_PM | ||
572 | static int sdh_suspend(struct platform_device *dev, pm_message_t state) | ||
573 | { | ||
574 | struct mmc_host *mmc = platform_get_drvdata(dev); | ||
575 | struct bfin_sd_host *drv_data = get_sdh_data(dev); | ||
576 | int ret = 0; | ||
577 | |||
578 | if (mmc) | ||
579 | ret = mmc_suspend_host(mmc, state); | ||
580 | |||
581 | bfin_write_SDH_PWR_CTL(bfin_read_SDH_PWR_CTL() & ~PWR_ON); | ||
582 | peripheral_free_list(drv_data->pin_req); | ||
583 | |||
584 | return ret; | ||
585 | } | ||
586 | |||
587 | static int sdh_resume(struct platform_device *dev) | ||
588 | { | ||
589 | struct mmc_host *mmc = platform_get_drvdata(dev); | ||
590 | struct bfin_sd_host *drv_data = get_sdh_data(dev); | ||
591 | int ret = 0; | ||
592 | |||
593 | ret = peripheral_request_list(drv_data->pin_req, DRIVER_NAME); | ||
594 | if (ret) { | ||
595 | dev_err(&dev->dev, "unable to request peripheral pins\n"); | ||
596 | return ret; | ||
597 | } | ||
598 | |||
599 | bfin_write_SDH_PWR_CTL(bfin_read_SDH_PWR_CTL() | PWR_ON); | ||
600 | #if defined(CONFIG_BF54x) | ||
601 | /* Secure Digital Host shares DMA with Nand controller */ | ||
602 | bfin_write_DMAC1_PERIMUX(bfin_read_DMAC1_PERIMUX() | 0x1); | ||
603 | #endif | ||
604 | bfin_write_SDH_CFG(bfin_read_SDH_CFG() | CLKS_EN); | ||
605 | SSYNC(); | ||
606 | |||
607 | bfin_write_SDH_CFG((bfin_read_SDH_CFG() & 0x1F) | (PUP_SDDAT | PUP_SDDAT3)); | ||
608 | SSYNC(); | ||
609 | |||
610 | if (mmc) | ||
611 | ret = mmc_resume_host(mmc); | ||
612 | |||
613 | return ret; | ||
614 | } | ||
615 | #else | ||
616 | # define sdh_suspend NULL | ||
617 | # define sdh_resume NULL | ||
618 | #endif | ||
619 | |||
620 | static struct platform_driver sdh_driver = { | ||
621 | .probe = sdh_probe, | ||
622 | .remove = __devexit_p(sdh_remove), | ||
623 | .suspend = sdh_suspend, | ||
624 | .resume = sdh_resume, | ||
625 | .driver = { | ||
626 | .name = DRIVER_NAME, | ||
627 | }, | ||
628 | }; | ||
629 | |||
630 | static int __init sdh_init(void) | ||
631 | { | ||
632 | return platform_driver_register(&sdh_driver); | ||
633 | } | ||
634 | module_init(sdh_init); | ||
635 | |||
636 | static void __exit sdh_exit(void) | ||
637 | { | ||
638 | platform_driver_unregister(&sdh_driver); | ||
639 | } | ||
640 | module_exit(sdh_exit); | ||
641 | |||
642 | MODULE_DESCRIPTION("Blackfin Secure Digital Host Driver"); | ||
643 | MODULE_AUTHOR("Cliff Cai, Roy Huang"); | ||
644 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/mmc/host/cb710-mmc.c b/drivers/mmc/host/cb710-mmc.c index 4e72964a7b43..92a324f7417c 100644 --- a/drivers/mmc/host/cb710-mmc.c +++ b/drivers/mmc/host/cb710-mmc.c | |||
@@ -9,7 +9,6 @@ | |||
9 | */ | 9 | */ |
10 | #include <linux/kernel.h> | 10 | #include <linux/kernel.h> |
11 | #include <linux/module.h> | 11 | #include <linux/module.h> |
12 | #include <linux/slab.h> | ||
13 | #include <linux/pci.h> | 12 | #include <linux/pci.h> |
14 | #include <linux/delay.h> | 13 | #include <linux/delay.h> |
15 | #include "cb710-mmc.h" | 14 | #include "cb710-mmc.h" |
diff --git a/drivers/mmc/host/davinci_mmc.c b/drivers/mmc/host/davinci_mmc.c new file mode 100644 index 000000000000..3bd0ba294e9d --- /dev/null +++ b/drivers/mmc/host/davinci_mmc.c | |||
@@ -0,0 +1,1374 @@ | |||
1 | /* | ||
2 | * davinci_mmc.c - TI DaVinci MMC/SD/SDIO driver | ||
3 | * | ||
4 | * Copyright (C) 2006 Texas Instruments. | ||
5 | * Original author: Purushotam Kumar | ||
6 | * Copyright (C) 2009 David Brownell | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License as published by | ||
10 | * the Free Software Foundation; either version 2 of the License, or | ||
11 | * (at your option) any later version. | ||
12 | * | ||
13 | * This program is distributed in the hope that it will be useful, | ||
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
16 | * GNU General Public License for more details. | ||
17 | * | ||
18 | * You should have received a copy of the GNU General Public License | ||
19 | * along with this program; if not, write to the Free Software | ||
20 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
21 | */ | ||
22 | |||
23 | #include <linux/module.h> | ||
24 | #include <linux/ioport.h> | ||
25 | #include <linux/platform_device.h> | ||
26 | #include <linux/clk.h> | ||
27 | #include <linux/err.h> | ||
28 | #include <linux/cpufreq.h> | ||
29 | #include <linux/mmc/host.h> | ||
30 | #include <linux/io.h> | ||
31 | #include <linux/irq.h> | ||
32 | #include <linux/delay.h> | ||
33 | #include <linux/dma-mapping.h> | ||
34 | #include <linux/mmc/mmc.h> | ||
35 | |||
36 | #include <mach/mmc.h> | ||
37 | #include <mach/edma.h> | ||
38 | |||
39 | /* | ||
40 | * Register Definitions | ||
41 | */ | ||
42 | #define DAVINCI_MMCCTL 0x00 /* Control Register */ | ||
43 | #define DAVINCI_MMCCLK 0x04 /* Memory Clock Control Register */ | ||
44 | #define DAVINCI_MMCST0 0x08 /* Status Register 0 */ | ||
45 | #define DAVINCI_MMCST1 0x0C /* Status Register 1 */ | ||
46 | #define DAVINCI_MMCIM 0x10 /* Interrupt Mask Register */ | ||
47 | #define DAVINCI_MMCTOR 0x14 /* Response Time-Out Register */ | ||
48 | #define DAVINCI_MMCTOD 0x18 /* Data Read Time-Out Register */ | ||
49 | #define DAVINCI_MMCBLEN 0x1C /* Block Length Register */ | ||
50 | #define DAVINCI_MMCNBLK 0x20 /* Number of Blocks Register */ | ||
51 | #define DAVINCI_MMCNBLC 0x24 /* Number of Blocks Counter Register */ | ||
52 | #define DAVINCI_MMCDRR 0x28 /* Data Receive Register */ | ||
53 | #define DAVINCI_MMCDXR 0x2C /* Data Transmit Register */ | ||
54 | #define DAVINCI_MMCCMD 0x30 /* Command Register */ | ||
55 | #define DAVINCI_MMCARGHL 0x34 /* Argument Register */ | ||
56 | #define DAVINCI_MMCRSP01 0x38 /* Response Register 0 and 1 */ | ||
57 | #define DAVINCI_MMCRSP23 0x3C /* Response Register 0 and 1 */ | ||
58 | #define DAVINCI_MMCRSP45 0x40 /* Response Register 0 and 1 */ | ||
59 | #define DAVINCI_MMCRSP67 0x44 /* Response Register 0 and 1 */ | ||
60 | #define DAVINCI_MMCDRSP 0x48 /* Data Response Register */ | ||
61 | #define DAVINCI_MMCETOK 0x4C | ||
62 | #define DAVINCI_MMCCIDX 0x50 /* Command Index Register */ | ||
63 | #define DAVINCI_MMCCKC 0x54 | ||
64 | #define DAVINCI_MMCTORC 0x58 | ||
65 | #define DAVINCI_MMCTODC 0x5C | ||
66 | #define DAVINCI_MMCBLNC 0x60 | ||
67 | #define DAVINCI_SDIOCTL 0x64 | ||
68 | #define DAVINCI_SDIOST0 0x68 | ||
69 | #define DAVINCI_SDIOEN 0x6C | ||
70 | #define DAVINCI_SDIOST 0x70 | ||
71 | #define DAVINCI_MMCFIFOCTL 0x74 /* FIFO Control Register */ | ||
72 | |||
73 | /* DAVINCI_MMCCTL definitions */ | ||
74 | #define MMCCTL_DATRST (1 << 0) | ||
75 | #define MMCCTL_CMDRST (1 << 1) | ||
76 | #define MMCCTL_WIDTH_8_BIT (1 << 8) | ||
77 | #define MMCCTL_WIDTH_4_BIT (1 << 2) | ||
78 | #define MMCCTL_DATEG_DISABLED (0 << 6) | ||
79 | #define MMCCTL_DATEG_RISING (1 << 6) | ||
80 | #define MMCCTL_DATEG_FALLING (2 << 6) | ||
81 | #define MMCCTL_DATEG_BOTH (3 << 6) | ||
82 | #define MMCCTL_PERMDR_LE (0 << 9) | ||
83 | #define MMCCTL_PERMDR_BE (1 << 9) | ||
84 | #define MMCCTL_PERMDX_LE (0 << 10) | ||
85 | #define MMCCTL_PERMDX_BE (1 << 10) | ||
86 | |||
87 | /* DAVINCI_MMCCLK definitions */ | ||
88 | #define MMCCLK_CLKEN (1 << 8) | ||
89 | #define MMCCLK_CLKRT_MASK (0xFF << 0) | ||
90 | |||
91 | /* IRQ bit definitions, for DAVINCI_MMCST0 and DAVINCI_MMCIM */ | ||
92 | #define MMCST0_DATDNE BIT(0) /* data done */ | ||
93 | #define MMCST0_BSYDNE BIT(1) /* busy done */ | ||
94 | #define MMCST0_RSPDNE BIT(2) /* command done */ | ||
95 | #define MMCST0_TOUTRD BIT(3) /* data read timeout */ | ||
96 | #define MMCST0_TOUTRS BIT(4) /* command response timeout */ | ||
97 | #define MMCST0_CRCWR BIT(5) /* data write CRC error */ | ||
98 | #define MMCST0_CRCRD BIT(6) /* data read CRC error */ | ||
99 | #define MMCST0_CRCRS BIT(7) /* command response CRC error */ | ||
100 | #define MMCST0_DXRDY BIT(9) /* data transmit ready (fifo empty) */ | ||
101 | #define MMCST0_DRRDY BIT(10) /* data receive ready (data in fifo)*/ | ||
102 | #define MMCST0_DATED BIT(11) /* DAT3 edge detect */ | ||
103 | #define MMCST0_TRNDNE BIT(12) /* transfer done */ | ||
104 | |||
105 | /* DAVINCI_MMCST1 definitions */ | ||
106 | #define MMCST1_BUSY (1 << 0) | ||
107 | |||
108 | /* DAVINCI_MMCCMD definitions */ | ||
109 | #define MMCCMD_CMD_MASK (0x3F << 0) | ||
110 | #define MMCCMD_PPLEN (1 << 7) | ||
111 | #define MMCCMD_BSYEXP (1 << 8) | ||
112 | #define MMCCMD_RSPFMT_MASK (3 << 9) | ||
113 | #define MMCCMD_RSPFMT_NONE (0 << 9) | ||
114 | #define MMCCMD_RSPFMT_R1456 (1 << 9) | ||
115 | #define MMCCMD_RSPFMT_R2 (2 << 9) | ||
116 | #define MMCCMD_RSPFMT_R3 (3 << 9) | ||
117 | #define MMCCMD_DTRW (1 << 11) | ||
118 | #define MMCCMD_STRMTP (1 << 12) | ||
119 | #define MMCCMD_WDATX (1 << 13) | ||
120 | #define MMCCMD_INITCK (1 << 14) | ||
121 | #define MMCCMD_DCLR (1 << 15) | ||
122 | #define MMCCMD_DMATRIG (1 << 16) | ||
123 | |||
124 | /* DAVINCI_MMCFIFOCTL definitions */ | ||
125 | #define MMCFIFOCTL_FIFORST (1 << 0) | ||
126 | #define MMCFIFOCTL_FIFODIR_WR (1 << 1) | ||
127 | #define MMCFIFOCTL_FIFODIR_RD (0 << 1) | ||
128 | #define MMCFIFOCTL_FIFOLEV (1 << 2) /* 0 = 128 bits, 1 = 256 bits */ | ||
129 | #define MMCFIFOCTL_ACCWD_4 (0 << 3) /* access width of 4 bytes */ | ||
130 | #define MMCFIFOCTL_ACCWD_3 (1 << 3) /* access width of 3 bytes */ | ||
131 | #define MMCFIFOCTL_ACCWD_2 (2 << 3) /* access width of 2 bytes */ | ||
132 | #define MMCFIFOCTL_ACCWD_1 (3 << 3) /* access width of 1 byte */ | ||
133 | |||
134 | |||
135 | /* MMCSD Init clock in Hz in opendrain mode */ | ||
136 | #define MMCSD_INIT_CLOCK 200000 | ||
137 | |||
138 | /* | ||
139 | * One scatterlist dma "segment" is at most MAX_CCNT rw_threshold units, | ||
140 | * and we handle up to NR_SG segments. MMC_BLOCK_BOUNCE kicks in only | ||
141 | * for drivers with max_hw_segs == 1, making the segments bigger (64KB) | ||
142 | * than the page or two that's otherwise typical. NR_SG == 16 gives at | ||
143 | * least the same throughput boost, using EDMA transfer linkage instead | ||
144 | * of spending CPU time copying pages. | ||
145 | */ | ||
146 | #define MAX_CCNT ((1 << 16) - 1) | ||
147 | |||
148 | #define NR_SG 16 | ||
149 | |||
150 | static unsigned rw_threshold = 32; | ||
151 | module_param(rw_threshold, uint, S_IRUGO); | ||
152 | MODULE_PARM_DESC(rw_threshold, | ||
153 | "Read/Write threshold. Default = 32"); | ||
154 | |||
155 | static unsigned __initdata use_dma = 1; | ||
156 | module_param(use_dma, uint, 0); | ||
157 | MODULE_PARM_DESC(use_dma, "Whether to use DMA or not. Default = 1"); | ||
158 | |||
159 | struct mmc_davinci_host { | ||
160 | struct mmc_command *cmd; | ||
161 | struct mmc_data *data; | ||
162 | struct mmc_host *mmc; | ||
163 | struct clk *clk; | ||
164 | unsigned int mmc_input_clk; | ||
165 | void __iomem *base; | ||
166 | struct resource *mem_res; | ||
167 | int irq; | ||
168 | unsigned char bus_mode; | ||
169 | |||
170 | #define DAVINCI_MMC_DATADIR_NONE 0 | ||
171 | #define DAVINCI_MMC_DATADIR_READ 1 | ||
172 | #define DAVINCI_MMC_DATADIR_WRITE 2 | ||
173 | unsigned char data_dir; | ||
174 | |||
175 | /* buffer is used during PIO of one scatterlist segment, and | ||
176 | * is updated along with buffer_bytes_left. bytes_left applies | ||
177 | * to all N blocks of the PIO transfer. | ||
178 | */ | ||
179 | u8 *buffer; | ||
180 | u32 buffer_bytes_left; | ||
181 | u32 bytes_left; | ||
182 | |||
183 | u32 rxdma, txdma; | ||
184 | bool use_dma; | ||
185 | bool do_dma; | ||
186 | |||
187 | /* Scatterlist DMA uses one or more parameter RAM entries: | ||
188 | * the main one (associated with rxdma or txdma) plus zero or | ||
189 | * more links. The entries for a given transfer differ only | ||
190 | * by memory buffer (address, length) and link field. | ||
191 | */ | ||
192 | struct edmacc_param tx_template; | ||
193 | struct edmacc_param rx_template; | ||
194 | unsigned n_link; | ||
195 | u32 links[NR_SG - 1]; | ||
196 | |||
197 | /* For PIO we walk scatterlists one segment at a time. */ | ||
198 | unsigned int sg_len; | ||
199 | struct scatterlist *sg; | ||
200 | |||
201 | /* Version of the MMC/SD controller */ | ||
202 | u8 version; | ||
203 | /* for ns in one cycle calculation */ | ||
204 | unsigned ns_in_one_cycle; | ||
205 | #ifdef CONFIG_CPU_FREQ | ||
206 | struct notifier_block freq_transition; | ||
207 | #endif | ||
208 | }; | ||
209 | |||
210 | |||
211 | /* PIO only */ | ||
212 | static void mmc_davinci_sg_to_buf(struct mmc_davinci_host *host) | ||
213 | { | ||
214 | host->buffer_bytes_left = sg_dma_len(host->sg); | ||
215 | host->buffer = sg_virt(host->sg); | ||
216 | if (host->buffer_bytes_left > host->bytes_left) | ||
217 | host->buffer_bytes_left = host->bytes_left; | ||
218 | } | ||
219 | |||
220 | static void davinci_fifo_data_trans(struct mmc_davinci_host *host, | ||
221 | unsigned int n) | ||
222 | { | ||
223 | u8 *p; | ||
224 | unsigned int i; | ||
225 | |||
226 | if (host->buffer_bytes_left == 0) { | ||
227 | host->sg = sg_next(host->data->sg); | ||
228 | mmc_davinci_sg_to_buf(host); | ||
229 | } | ||
230 | |||
231 | p = host->buffer; | ||
232 | if (n > host->buffer_bytes_left) | ||
233 | n = host->buffer_bytes_left; | ||
234 | host->buffer_bytes_left -= n; | ||
235 | host->bytes_left -= n; | ||
236 | |||
237 | /* NOTE: we never transfer more than rw_threshold bytes | ||
238 | * to/from the fifo here; there's no I/O overlap. | ||
239 | * This also assumes that access width( i.e. ACCWD) is 4 bytes | ||
240 | */ | ||
241 | if (host->data_dir == DAVINCI_MMC_DATADIR_WRITE) { | ||
242 | for (i = 0; i < (n >> 2); i++) { | ||
243 | writel(*((u32 *)p), host->base + DAVINCI_MMCDXR); | ||
244 | p = p + 4; | ||
245 | } | ||
246 | if (n & 3) { | ||
247 | iowrite8_rep(host->base + DAVINCI_MMCDXR, p, (n & 3)); | ||
248 | p = p + (n & 3); | ||
249 | } | ||
250 | } else { | ||
251 | for (i = 0; i < (n >> 2); i++) { | ||
252 | *((u32 *)p) = readl(host->base + DAVINCI_MMCDRR); | ||
253 | p = p + 4; | ||
254 | } | ||
255 | if (n & 3) { | ||
256 | ioread8_rep(host->base + DAVINCI_MMCDRR, p, (n & 3)); | ||
257 | p = p + (n & 3); | ||
258 | } | ||
259 | } | ||
260 | host->buffer = p; | ||
261 | } | ||
262 | |||
263 | static void mmc_davinci_start_command(struct mmc_davinci_host *host, | ||
264 | struct mmc_command *cmd) | ||
265 | { | ||
266 | u32 cmd_reg = 0; | ||
267 | u32 im_val; | ||
268 | |||
269 | dev_dbg(mmc_dev(host->mmc), "CMD%d, arg 0x%08x%s\n", | ||
270 | cmd->opcode, cmd->arg, | ||
271 | ({ char *s; | ||
272 | switch (mmc_resp_type(cmd)) { | ||
273 | case MMC_RSP_R1: | ||
274 | s = ", R1/R5/R6/R7 response"; | ||
275 | break; | ||
276 | case MMC_RSP_R1B: | ||
277 | s = ", R1b response"; | ||
278 | break; | ||
279 | case MMC_RSP_R2: | ||
280 | s = ", R2 response"; | ||
281 | break; | ||
282 | case MMC_RSP_R3: | ||
283 | s = ", R3/R4 response"; | ||
284 | break; | ||
285 | default: | ||
286 | s = ", (R? response)"; | ||
287 | break; | ||
288 | }; s; })); | ||
289 | host->cmd = cmd; | ||
290 | |||
291 | switch (mmc_resp_type(cmd)) { | ||
292 | case MMC_RSP_R1B: | ||
293 | /* There's some spec confusion about when R1B is | ||
294 | * allowed, but if the card doesn't issue a BUSY | ||
295 | * then it's harmless for us to allow it. | ||
296 | */ | ||
297 | cmd_reg |= MMCCMD_BSYEXP; | ||
298 | /* FALLTHROUGH */ | ||
299 | case MMC_RSP_R1: /* 48 bits, CRC */ | ||
300 | cmd_reg |= MMCCMD_RSPFMT_R1456; | ||
301 | break; | ||
302 | case MMC_RSP_R2: /* 136 bits, CRC */ | ||
303 | cmd_reg |= MMCCMD_RSPFMT_R2; | ||
304 | break; | ||
305 | case MMC_RSP_R3: /* 48 bits, no CRC */ | ||
306 | cmd_reg |= MMCCMD_RSPFMT_R3; | ||
307 | break; | ||
308 | default: | ||
309 | cmd_reg |= MMCCMD_RSPFMT_NONE; | ||
310 | dev_dbg(mmc_dev(host->mmc), "unknown resp_type %04x\n", | ||
311 | mmc_resp_type(cmd)); | ||
312 | break; | ||
313 | } | ||
314 | |||
315 | /* Set command index */ | ||
316 | cmd_reg |= cmd->opcode; | ||
317 | |||
318 | /* Enable EDMA transfer triggers */ | ||
319 | if (host->do_dma) | ||
320 | cmd_reg |= MMCCMD_DMATRIG; | ||
321 | |||
322 | if (host->version == MMC_CTLR_VERSION_2 && host->data != NULL && | ||
323 | host->data_dir == DAVINCI_MMC_DATADIR_READ) | ||
324 | cmd_reg |= MMCCMD_DMATRIG; | ||
325 | |||
326 | /* Setting whether command involves data transfer or not */ | ||
327 | if (cmd->data) | ||
328 | cmd_reg |= MMCCMD_WDATX; | ||
329 | |||
330 | /* Setting whether stream or block transfer */ | ||
331 | if (cmd->flags & MMC_DATA_STREAM) | ||
332 | cmd_reg |= MMCCMD_STRMTP; | ||
333 | |||
334 | /* Setting whether data read or write */ | ||
335 | if (host->data_dir == DAVINCI_MMC_DATADIR_WRITE) | ||
336 | cmd_reg |= MMCCMD_DTRW; | ||
337 | |||
338 | if (host->bus_mode == MMC_BUSMODE_PUSHPULL) | ||
339 | cmd_reg |= MMCCMD_PPLEN; | ||
340 | |||
341 | /* set Command timeout */ | ||
342 | writel(0x1FFF, host->base + DAVINCI_MMCTOR); | ||
343 | |||
344 | /* Enable interrupt (calculate here, defer until FIFO is stuffed). */ | ||
345 | im_val = MMCST0_RSPDNE | MMCST0_CRCRS | MMCST0_TOUTRS; | ||
346 | if (host->data_dir == DAVINCI_MMC_DATADIR_WRITE) { | ||
347 | im_val |= MMCST0_DATDNE | MMCST0_CRCWR; | ||
348 | |||
349 | if (!host->do_dma) | ||
350 | im_val |= MMCST0_DXRDY; | ||
351 | } else if (host->data_dir == DAVINCI_MMC_DATADIR_READ) { | ||
352 | im_val |= MMCST0_DATDNE | MMCST0_CRCRD | MMCST0_TOUTRD; | ||
353 | |||
354 | if (!host->do_dma) | ||
355 | im_val |= MMCST0_DRRDY; | ||
356 | } | ||
357 | |||
358 | /* | ||
359 | * Before non-DMA WRITE commands the controller needs priming: | ||
360 | * FIFO should be populated with 32 bytes i.e. whatever is the FIFO size | ||
361 | */ | ||
362 | if (!host->do_dma && (host->data_dir == DAVINCI_MMC_DATADIR_WRITE)) | ||
363 | davinci_fifo_data_trans(host, rw_threshold); | ||
364 | |||
365 | writel(cmd->arg, host->base + DAVINCI_MMCARGHL); | ||
366 | writel(cmd_reg, host->base + DAVINCI_MMCCMD); | ||
367 | writel(im_val, host->base + DAVINCI_MMCIM); | ||
368 | } | ||
369 | |||
370 | /*----------------------------------------------------------------------*/ | ||
371 | |||
372 | /* DMA infrastructure */ | ||
373 | |||
374 | static void davinci_abort_dma(struct mmc_davinci_host *host) | ||
375 | { | ||
376 | int sync_dev; | ||
377 | |||
378 | if (host->data_dir == DAVINCI_MMC_DATADIR_READ) | ||
379 | sync_dev = host->rxdma; | ||
380 | else | ||
381 | sync_dev = host->txdma; | ||
382 | |||
383 | edma_stop(sync_dev); | ||
384 | edma_clean_channel(sync_dev); | ||
385 | } | ||
386 | |||
387 | static void | ||
388 | mmc_davinci_xfer_done(struct mmc_davinci_host *host, struct mmc_data *data); | ||
389 | |||
390 | static void mmc_davinci_dma_cb(unsigned channel, u16 ch_status, void *data) | ||
391 | { | ||
392 | if (DMA_COMPLETE != ch_status) { | ||
393 | struct mmc_davinci_host *host = data; | ||
394 | |||
395 | /* Currently means: DMA Event Missed, or "null" transfer | ||
396 | * request was seen. In the future, TC errors (like bad | ||
397 | * addresses) might be presented too. | ||
398 | */ | ||
399 | dev_warn(mmc_dev(host->mmc), "DMA %s error\n", | ||
400 | (host->data->flags & MMC_DATA_WRITE) | ||
401 | ? "write" : "read"); | ||
402 | host->data->error = -EIO; | ||
403 | mmc_davinci_xfer_done(host, host->data); | ||
404 | } | ||
405 | } | ||
406 | |||
407 | /* Set up tx or rx template, to be modified and updated later */ | ||
408 | static void __init mmc_davinci_dma_setup(struct mmc_davinci_host *host, | ||
409 | bool tx, struct edmacc_param *template) | ||
410 | { | ||
411 | unsigned sync_dev; | ||
412 | const u16 acnt = 4; | ||
413 | const u16 bcnt = rw_threshold >> 2; | ||
414 | const u16 ccnt = 0; | ||
415 | u32 src_port = 0; | ||
416 | u32 dst_port = 0; | ||
417 | s16 src_bidx, dst_bidx; | ||
418 | s16 src_cidx, dst_cidx; | ||
419 | |||
420 | /* | ||
421 | * A-B Sync transfer: each DMA request is for one "frame" of | ||
422 | * rw_threshold bytes, broken into "acnt"-size chunks repeated | ||
423 | * "bcnt" times. Each segment needs "ccnt" such frames; since | ||
424 | * we tell the block layer our mmc->max_seg_size limit, we can | ||
425 | * trust (later) that it's within bounds. | ||
426 | * | ||
427 | * The FIFOs are read/written in 4-byte chunks (acnt == 4) and | ||
428 | * EDMA will optimize memory operations to use larger bursts. | ||
429 | */ | ||
430 | if (tx) { | ||
431 | sync_dev = host->txdma; | ||
432 | |||
433 | /* src_prt, ccnt, and link to be set up later */ | ||
434 | src_bidx = acnt; | ||
435 | src_cidx = acnt * bcnt; | ||
436 | |||
437 | dst_port = host->mem_res->start + DAVINCI_MMCDXR; | ||
438 | dst_bidx = 0; | ||
439 | dst_cidx = 0; | ||
440 | } else { | ||
441 | sync_dev = host->rxdma; | ||
442 | |||
443 | src_port = host->mem_res->start + DAVINCI_MMCDRR; | ||
444 | src_bidx = 0; | ||
445 | src_cidx = 0; | ||
446 | |||
447 | /* dst_prt, ccnt, and link to be set up later */ | ||
448 | dst_bidx = acnt; | ||
449 | dst_cidx = acnt * bcnt; | ||
450 | } | ||
451 | |||
452 | /* | ||
453 | * We can't use FIFO mode for the FIFOs because MMC FIFO addresses | ||
454 | * are not 256-bit (32-byte) aligned. So we use INCR, and the W8BIT | ||
455 | * parameter is ignored. | ||
456 | */ | ||
457 | edma_set_src(sync_dev, src_port, INCR, W8BIT); | ||
458 | edma_set_dest(sync_dev, dst_port, INCR, W8BIT); | ||
459 | |||
460 | edma_set_src_index(sync_dev, src_bidx, src_cidx); | ||
461 | edma_set_dest_index(sync_dev, dst_bidx, dst_cidx); | ||
462 | |||
463 | edma_set_transfer_params(sync_dev, acnt, bcnt, ccnt, 8, ABSYNC); | ||
464 | |||
465 | edma_read_slot(sync_dev, template); | ||
466 | |||
467 | /* don't bother with irqs or chaining */ | ||
468 | template->opt |= EDMA_CHAN_SLOT(sync_dev) << 12; | ||
469 | } | ||
470 | |||
471 | static void mmc_davinci_send_dma_request(struct mmc_davinci_host *host, | ||
472 | struct mmc_data *data) | ||
473 | { | ||
474 | struct edmacc_param *template; | ||
475 | int channel, slot; | ||
476 | unsigned link; | ||
477 | struct scatterlist *sg; | ||
478 | unsigned sg_len; | ||
479 | unsigned bytes_left = host->bytes_left; | ||
480 | const unsigned shift = ffs(rw_threshold) - 1;; | ||
481 | |||
482 | if (host->data_dir == DAVINCI_MMC_DATADIR_WRITE) { | ||
483 | template = &host->tx_template; | ||
484 | channel = host->txdma; | ||
485 | } else { | ||
486 | template = &host->rx_template; | ||
487 | channel = host->rxdma; | ||
488 | } | ||
489 | |||
490 | /* We know sg_len and ccnt will never be out of range because | ||
491 | * we told the mmc layer which in turn tells the block layer | ||
492 | * to ensure that it only hands us one scatterlist segment | ||
493 | * per EDMA PARAM entry. Update the PARAM | ||
494 | * entries needed for each segment of this scatterlist. | ||
495 | */ | ||
496 | for (slot = channel, link = 0, sg = data->sg, sg_len = host->sg_len; | ||
497 | sg_len-- != 0 && bytes_left; | ||
498 | sg = sg_next(sg), slot = host->links[link++]) { | ||
499 | u32 buf = sg_dma_address(sg); | ||
500 | unsigned count = sg_dma_len(sg); | ||
501 | |||
502 | template->link_bcntrld = sg_len | ||
503 | ? (EDMA_CHAN_SLOT(host->links[link]) << 5) | ||
504 | : 0xffff; | ||
505 | |||
506 | if (count > bytes_left) | ||
507 | count = bytes_left; | ||
508 | bytes_left -= count; | ||
509 | |||
510 | if (host->data_dir == DAVINCI_MMC_DATADIR_WRITE) | ||
511 | template->src = buf; | ||
512 | else | ||
513 | template->dst = buf; | ||
514 | template->ccnt = count >> shift; | ||
515 | |||
516 | edma_write_slot(slot, template); | ||
517 | } | ||
518 | |||
519 | if (host->version == MMC_CTLR_VERSION_2) | ||
520 | edma_clear_event(channel); | ||
521 | |||
522 | edma_start(channel); | ||
523 | } | ||
524 | |||
525 | static int mmc_davinci_start_dma_transfer(struct mmc_davinci_host *host, | ||
526 | struct mmc_data *data) | ||
527 | { | ||
528 | int i; | ||
529 | int mask = rw_threshold - 1; | ||
530 | |||
531 | host->sg_len = dma_map_sg(mmc_dev(host->mmc), data->sg, data->sg_len, | ||
532 | ((data->flags & MMC_DATA_WRITE) | ||
533 | ? DMA_TO_DEVICE | ||
534 | : DMA_FROM_DEVICE)); | ||
535 | |||
536 | /* no individual DMA segment should need a partial FIFO */ | ||
537 | for (i = 0; i < host->sg_len; i++) { | ||
538 | if (sg_dma_len(data->sg + i) & mask) { | ||
539 | dma_unmap_sg(mmc_dev(host->mmc), | ||
540 | data->sg, data->sg_len, | ||
541 | (data->flags & MMC_DATA_WRITE) | ||
542 | ? DMA_TO_DEVICE | ||
543 | : DMA_FROM_DEVICE); | ||
544 | return -1; | ||
545 | } | ||
546 | } | ||
547 | |||
548 | host->do_dma = 1; | ||
549 | mmc_davinci_send_dma_request(host, data); | ||
550 | |||
551 | return 0; | ||
552 | } | ||
553 | |||
554 | static void __init_or_module | ||
555 | davinci_release_dma_channels(struct mmc_davinci_host *host) | ||
556 | { | ||
557 | unsigned i; | ||
558 | |||
559 | if (!host->use_dma) | ||
560 | return; | ||
561 | |||
562 | for (i = 0; i < host->n_link; i++) | ||
563 | edma_free_slot(host->links[i]); | ||
564 | |||
565 | edma_free_channel(host->txdma); | ||
566 | edma_free_channel(host->rxdma); | ||
567 | } | ||
568 | |||
569 | static int __init davinci_acquire_dma_channels(struct mmc_davinci_host *host) | ||
570 | { | ||
571 | int r, i; | ||
572 | |||
573 | /* Acquire master DMA write channel */ | ||
574 | r = edma_alloc_channel(host->txdma, mmc_davinci_dma_cb, host, | ||
575 | EVENTQ_DEFAULT); | ||
576 | if (r < 0) { | ||
577 | dev_warn(mmc_dev(host->mmc), "alloc %s channel err %d\n", | ||
578 | "tx", r); | ||
579 | return r; | ||
580 | } | ||
581 | mmc_davinci_dma_setup(host, true, &host->tx_template); | ||
582 | |||
583 | /* Acquire master DMA read channel */ | ||
584 | r = edma_alloc_channel(host->rxdma, mmc_davinci_dma_cb, host, | ||
585 | EVENTQ_DEFAULT); | ||
586 | if (r < 0) { | ||
587 | dev_warn(mmc_dev(host->mmc), "alloc %s channel err %d\n", | ||
588 | "rx", r); | ||
589 | goto free_master_write; | ||
590 | } | ||
591 | mmc_davinci_dma_setup(host, false, &host->rx_template); | ||
592 | |||
593 | /* Allocate parameter RAM slots, which will later be bound to a | ||
594 | * channel as needed to handle a scatterlist. | ||
595 | */ | ||
596 | for (i = 0; i < ARRAY_SIZE(host->links); i++) { | ||
597 | r = edma_alloc_slot(EDMA_CTLR(host->txdma), EDMA_SLOT_ANY); | ||
598 | if (r < 0) { | ||
599 | dev_dbg(mmc_dev(host->mmc), "dma PaRAM alloc --> %d\n", | ||
600 | r); | ||
601 | break; | ||
602 | } | ||
603 | host->links[i] = r; | ||
604 | } | ||
605 | host->n_link = i; | ||
606 | |||
607 | return 0; | ||
608 | |||
609 | free_master_write: | ||
610 | edma_free_channel(host->txdma); | ||
611 | |||
612 | return r; | ||
613 | } | ||
614 | |||
615 | /*----------------------------------------------------------------------*/ | ||
616 | |||
617 | static void | ||
618 | mmc_davinci_prepare_data(struct mmc_davinci_host *host, struct mmc_request *req) | ||
619 | { | ||
620 | int fifo_lev = (rw_threshold == 32) ? MMCFIFOCTL_FIFOLEV : 0; | ||
621 | int timeout; | ||
622 | struct mmc_data *data = req->data; | ||
623 | |||
624 | if (host->version == MMC_CTLR_VERSION_2) | ||
625 | fifo_lev = (rw_threshold == 64) ? MMCFIFOCTL_FIFOLEV : 0; | ||
626 | |||
627 | host->data = data; | ||
628 | if (data == NULL) { | ||
629 | host->data_dir = DAVINCI_MMC_DATADIR_NONE; | ||
630 | writel(0, host->base + DAVINCI_MMCBLEN); | ||
631 | writel(0, host->base + DAVINCI_MMCNBLK); | ||
632 | return; | ||
633 | } | ||
634 | |||
635 | dev_dbg(mmc_dev(host->mmc), "%s %s, %d blocks of %d bytes\n", | ||
636 | (data->flags & MMC_DATA_STREAM) ? "stream" : "block", | ||
637 | (data->flags & MMC_DATA_WRITE) ? "write" : "read", | ||
638 | data->blocks, data->blksz); | ||
639 | dev_dbg(mmc_dev(host->mmc), " DTO %d cycles + %d ns\n", | ||
640 | data->timeout_clks, data->timeout_ns); | ||
641 | timeout = data->timeout_clks + | ||
642 | (data->timeout_ns / host->ns_in_one_cycle); | ||
643 | if (timeout > 0xffff) | ||
644 | timeout = 0xffff; | ||
645 | |||
646 | writel(timeout, host->base + DAVINCI_MMCTOD); | ||
647 | writel(data->blocks, host->base + DAVINCI_MMCNBLK); | ||
648 | writel(data->blksz, host->base + DAVINCI_MMCBLEN); | ||
649 | |||
650 | /* Configure the FIFO */ | ||
651 | switch (data->flags & MMC_DATA_WRITE) { | ||
652 | case MMC_DATA_WRITE: | ||
653 | host->data_dir = DAVINCI_MMC_DATADIR_WRITE; | ||
654 | writel(fifo_lev | MMCFIFOCTL_FIFODIR_WR | MMCFIFOCTL_FIFORST, | ||
655 | host->base + DAVINCI_MMCFIFOCTL); | ||
656 | writel(fifo_lev | MMCFIFOCTL_FIFODIR_WR, | ||
657 | host->base + DAVINCI_MMCFIFOCTL); | ||
658 | break; | ||
659 | |||
660 | default: | ||
661 | host->data_dir = DAVINCI_MMC_DATADIR_READ; | ||
662 | writel(fifo_lev | MMCFIFOCTL_FIFODIR_RD | MMCFIFOCTL_FIFORST, | ||
663 | host->base + DAVINCI_MMCFIFOCTL); | ||
664 | writel(fifo_lev | MMCFIFOCTL_FIFODIR_RD, | ||
665 | host->base + DAVINCI_MMCFIFOCTL); | ||
666 | break; | ||
667 | } | ||
668 | |||
669 | host->buffer = NULL; | ||
670 | host->bytes_left = data->blocks * data->blksz; | ||
671 | |||
672 | /* For now we try to use DMA whenever we won't need partial FIFO | ||
673 | * reads or writes, either for the whole transfer (as tested here) | ||
674 | * or for any individual scatterlist segment (tested when we call | ||
675 | * start_dma_transfer). | ||
676 | * | ||
677 | * While we *could* change that, unusual block sizes are rarely | ||
678 | * used. The occasional fallback to PIO should't hurt. | ||
679 | */ | ||
680 | if (host->use_dma && (host->bytes_left & (rw_threshold - 1)) == 0 | ||
681 | && mmc_davinci_start_dma_transfer(host, data) == 0) { | ||
682 | /* zero this to ensure we take no PIO paths */ | ||
683 | host->bytes_left = 0; | ||
684 | } else { | ||
685 | /* Revert to CPU Copy */ | ||
686 | host->sg_len = data->sg_len; | ||
687 | host->sg = host->data->sg; | ||
688 | mmc_davinci_sg_to_buf(host); | ||
689 | } | ||
690 | } | ||
691 | |||
692 | static void mmc_davinci_request(struct mmc_host *mmc, struct mmc_request *req) | ||
693 | { | ||
694 | struct mmc_davinci_host *host = mmc_priv(mmc); | ||
695 | unsigned long timeout = jiffies + msecs_to_jiffies(900); | ||
696 | u32 mmcst1 = 0; | ||
697 | |||
698 | /* Card may still be sending BUSY after a previous operation, | ||
699 | * typically some kind of write. If so, we can't proceed yet. | ||
700 | */ | ||
701 | while (time_before(jiffies, timeout)) { | ||
702 | mmcst1 = readl(host->base + DAVINCI_MMCST1); | ||
703 | if (!(mmcst1 & MMCST1_BUSY)) | ||
704 | break; | ||
705 | cpu_relax(); | ||
706 | } | ||
707 | if (mmcst1 & MMCST1_BUSY) { | ||
708 | dev_err(mmc_dev(host->mmc), "still BUSY? bad ... \n"); | ||
709 | req->cmd->error = -ETIMEDOUT; | ||
710 | mmc_request_done(mmc, req); | ||
711 | return; | ||
712 | } | ||
713 | |||
714 | host->do_dma = 0; | ||
715 | mmc_davinci_prepare_data(host, req); | ||
716 | mmc_davinci_start_command(host, req->cmd); | ||
717 | } | ||
718 | |||
719 | static unsigned int calculate_freq_for_card(struct mmc_davinci_host *host, | ||
720 | unsigned int mmc_req_freq) | ||
721 | { | ||
722 | unsigned int mmc_freq = 0, mmc_pclk = 0, mmc_push_pull_divisor = 0; | ||
723 | |||
724 | mmc_pclk = host->mmc_input_clk; | ||
725 | if (mmc_req_freq && mmc_pclk > (2 * mmc_req_freq)) | ||
726 | mmc_push_pull_divisor = ((unsigned int)mmc_pclk | ||
727 | / (2 * mmc_req_freq)) - 1; | ||
728 | else | ||
729 | mmc_push_pull_divisor = 0; | ||
730 | |||
731 | mmc_freq = (unsigned int)mmc_pclk | ||
732 | / (2 * (mmc_push_pull_divisor + 1)); | ||
733 | |||
734 | if (mmc_freq > mmc_req_freq) | ||
735 | mmc_push_pull_divisor = mmc_push_pull_divisor + 1; | ||
736 | /* Convert ns to clock cycles */ | ||
737 | if (mmc_req_freq <= 400000) | ||
738 | host->ns_in_one_cycle = (1000000) / (((mmc_pclk | ||
739 | / (2 * (mmc_push_pull_divisor + 1)))/1000)); | ||
740 | else | ||
741 | host->ns_in_one_cycle = (1000000) / (((mmc_pclk | ||
742 | / (2 * (mmc_push_pull_divisor + 1)))/1000000)); | ||
743 | |||
744 | return mmc_push_pull_divisor; | ||
745 | } | ||
746 | |||
747 | static void calculate_clk_divider(struct mmc_host *mmc, struct mmc_ios *ios) | ||
748 | { | ||
749 | unsigned int open_drain_freq = 0, mmc_pclk = 0; | ||
750 | unsigned int mmc_push_pull_freq = 0; | ||
751 | struct mmc_davinci_host *host = mmc_priv(mmc); | ||
752 | |||
753 | if (ios->bus_mode == MMC_BUSMODE_OPENDRAIN) { | ||
754 | u32 temp; | ||
755 | |||
756 | /* Ignoring the init clock value passed for fixing the inter | ||
757 | * operability with different cards. | ||
758 | */ | ||
759 | open_drain_freq = ((unsigned int)mmc_pclk | ||
760 | / (2 * MMCSD_INIT_CLOCK)) - 1; | ||
761 | |||
762 | if (open_drain_freq > 0xFF) | ||
763 | open_drain_freq = 0xFF; | ||
764 | |||
765 | temp = readl(host->base + DAVINCI_MMCCLK) & ~MMCCLK_CLKRT_MASK; | ||
766 | temp |= open_drain_freq; | ||
767 | writel(temp, host->base + DAVINCI_MMCCLK); | ||
768 | |||
769 | /* Convert ns to clock cycles */ | ||
770 | host->ns_in_one_cycle = (1000000) / (MMCSD_INIT_CLOCK/1000); | ||
771 | } else { | ||
772 | u32 temp; | ||
773 | mmc_push_pull_freq = calculate_freq_for_card(host, ios->clock); | ||
774 | |||
775 | if (mmc_push_pull_freq > 0xFF) | ||
776 | mmc_push_pull_freq = 0xFF; | ||
777 | |||
778 | temp = readl(host->base + DAVINCI_MMCCLK) & ~MMCCLK_CLKEN; | ||
779 | writel(temp, host->base + DAVINCI_MMCCLK); | ||
780 | |||
781 | udelay(10); | ||
782 | |||
783 | temp = readl(host->base + DAVINCI_MMCCLK) & ~MMCCLK_CLKRT_MASK; | ||
784 | temp |= mmc_push_pull_freq; | ||
785 | writel(temp, host->base + DAVINCI_MMCCLK); | ||
786 | |||
787 | writel(temp | MMCCLK_CLKEN, host->base + DAVINCI_MMCCLK); | ||
788 | |||
789 | udelay(10); | ||
790 | } | ||
791 | } | ||
792 | |||
793 | static void mmc_davinci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) | ||
794 | { | ||
795 | struct mmc_davinci_host *host = mmc_priv(mmc); | ||
796 | |||
797 | dev_dbg(mmc_dev(host->mmc), | ||
798 | "clock %dHz busmode %d powermode %d Vdd %04x\n", | ||
799 | ios->clock, ios->bus_mode, ios->power_mode, | ||
800 | ios->vdd); | ||
801 | |||
802 | switch (ios->bus_width) { | ||
803 | case MMC_BUS_WIDTH_8: | ||
804 | dev_dbg(mmc_dev(host->mmc), "Enabling 8 bit mode\n"); | ||
805 | writel((readl(host->base + DAVINCI_MMCCTL) & | ||
806 | ~MMCCTL_WIDTH_4_BIT) | MMCCTL_WIDTH_8_BIT, | ||
807 | host->base + DAVINCI_MMCCTL); | ||
808 | break; | ||
809 | case MMC_BUS_WIDTH_4: | ||
810 | dev_dbg(mmc_dev(host->mmc), "Enabling 4 bit mode\n"); | ||
811 | if (host->version == MMC_CTLR_VERSION_2) | ||
812 | writel((readl(host->base + DAVINCI_MMCCTL) & | ||
813 | ~MMCCTL_WIDTH_8_BIT) | MMCCTL_WIDTH_4_BIT, | ||
814 | host->base + DAVINCI_MMCCTL); | ||
815 | else | ||
816 | writel(readl(host->base + DAVINCI_MMCCTL) | | ||
817 | MMCCTL_WIDTH_4_BIT, | ||
818 | host->base + DAVINCI_MMCCTL); | ||
819 | break; | ||
820 | case MMC_BUS_WIDTH_1: | ||
821 | dev_dbg(mmc_dev(host->mmc), "Enabling 1 bit mode\n"); | ||
822 | if (host->version == MMC_CTLR_VERSION_2) | ||
823 | writel(readl(host->base + DAVINCI_MMCCTL) & | ||
824 | ~(MMCCTL_WIDTH_8_BIT | MMCCTL_WIDTH_4_BIT), | ||
825 | host->base + DAVINCI_MMCCTL); | ||
826 | else | ||
827 | writel(readl(host->base + DAVINCI_MMCCTL) & | ||
828 | ~MMCCTL_WIDTH_4_BIT, | ||
829 | host->base + DAVINCI_MMCCTL); | ||
830 | break; | ||
831 | } | ||
832 | |||
833 | calculate_clk_divider(mmc, ios); | ||
834 | |||
835 | host->bus_mode = ios->bus_mode; | ||
836 | if (ios->power_mode == MMC_POWER_UP) { | ||
837 | unsigned long timeout = jiffies + msecs_to_jiffies(50); | ||
838 | bool lose = true; | ||
839 | |||
840 | /* Send clock cycles, poll completion */ | ||
841 | writel(0, host->base + DAVINCI_MMCARGHL); | ||
842 | writel(MMCCMD_INITCK, host->base + DAVINCI_MMCCMD); | ||
843 | while (time_before(jiffies, timeout)) { | ||
844 | u32 tmp = readl(host->base + DAVINCI_MMCST0); | ||
845 | |||
846 | if (tmp & MMCST0_RSPDNE) { | ||
847 | lose = false; | ||
848 | break; | ||
849 | } | ||
850 | cpu_relax(); | ||
851 | } | ||
852 | if (lose) | ||
853 | dev_warn(mmc_dev(host->mmc), "powerup timeout\n"); | ||
854 | } | ||
855 | |||
856 | /* FIXME on power OFF, reset things ... */ | ||
857 | } | ||
858 | |||
859 | static void | ||
860 | mmc_davinci_xfer_done(struct mmc_davinci_host *host, struct mmc_data *data) | ||
861 | { | ||
862 | host->data = NULL; | ||
863 | |||
864 | if (host->do_dma) { | ||
865 | davinci_abort_dma(host); | ||
866 | |||
867 | dma_unmap_sg(mmc_dev(host->mmc), data->sg, data->sg_len, | ||
868 | (data->flags & MMC_DATA_WRITE) | ||
869 | ? DMA_TO_DEVICE | ||
870 | : DMA_FROM_DEVICE); | ||
871 | host->do_dma = false; | ||
872 | } | ||
873 | host->data_dir = DAVINCI_MMC_DATADIR_NONE; | ||
874 | |||
875 | if (!data->stop || (host->cmd && host->cmd->error)) { | ||
876 | mmc_request_done(host->mmc, data->mrq); | ||
877 | writel(0, host->base + DAVINCI_MMCIM); | ||
878 | } else | ||
879 | mmc_davinci_start_command(host, data->stop); | ||
880 | } | ||
881 | |||
882 | static void mmc_davinci_cmd_done(struct mmc_davinci_host *host, | ||
883 | struct mmc_command *cmd) | ||
884 | { | ||
885 | host->cmd = NULL; | ||
886 | |||
887 | if (cmd->flags & MMC_RSP_PRESENT) { | ||
888 | if (cmd->flags & MMC_RSP_136) { | ||
889 | /* response type 2 */ | ||
890 | cmd->resp[3] = readl(host->base + DAVINCI_MMCRSP01); | ||
891 | cmd->resp[2] = readl(host->base + DAVINCI_MMCRSP23); | ||
892 | cmd->resp[1] = readl(host->base + DAVINCI_MMCRSP45); | ||
893 | cmd->resp[0] = readl(host->base + DAVINCI_MMCRSP67); | ||
894 | } else { | ||
895 | /* response types 1, 1b, 3, 4, 5, 6 */ | ||
896 | cmd->resp[0] = readl(host->base + DAVINCI_MMCRSP67); | ||
897 | } | ||
898 | } | ||
899 | |||
900 | if (host->data == NULL || cmd->error) { | ||
901 | if (cmd->error == -ETIMEDOUT) | ||
902 | cmd->mrq->cmd->retries = 0; | ||
903 | mmc_request_done(host->mmc, cmd->mrq); | ||
904 | writel(0, host->base + DAVINCI_MMCIM); | ||
905 | } | ||
906 | } | ||
907 | |||
908 | static void | ||
909 | davinci_abort_data(struct mmc_davinci_host *host, struct mmc_data *data) | ||
910 | { | ||
911 | u32 temp; | ||
912 | |||
913 | /* reset command and data state machines */ | ||
914 | temp = readl(host->base + DAVINCI_MMCCTL); | ||
915 | writel(temp | MMCCTL_CMDRST | MMCCTL_DATRST, | ||
916 | host->base + DAVINCI_MMCCTL); | ||
917 | |||
918 | temp &= ~(MMCCTL_CMDRST | MMCCTL_DATRST); | ||
919 | udelay(10); | ||
920 | writel(temp, host->base + DAVINCI_MMCCTL); | ||
921 | } | ||
922 | |||
923 | static irqreturn_t mmc_davinci_irq(int irq, void *dev_id) | ||
924 | { | ||
925 | struct mmc_davinci_host *host = (struct mmc_davinci_host *)dev_id; | ||
926 | unsigned int status, qstatus; | ||
927 | int end_command = 0; | ||
928 | int end_transfer = 0; | ||
929 | struct mmc_data *data = host->data; | ||
930 | |||
931 | if (host->cmd == NULL && host->data == NULL) { | ||
932 | status = readl(host->base + DAVINCI_MMCST0); | ||
933 | dev_dbg(mmc_dev(host->mmc), | ||
934 | "Spurious interrupt 0x%04x\n", status); | ||
935 | /* Disable the interrupt from mmcsd */ | ||
936 | writel(0, host->base + DAVINCI_MMCIM); | ||
937 | return IRQ_NONE; | ||
938 | } | ||
939 | |||
940 | status = readl(host->base + DAVINCI_MMCST0); | ||
941 | qstatus = status; | ||
942 | |||
943 | /* handle FIFO first when using PIO for data. | ||
944 | * bytes_left will decrease to zero as I/O progress and status will | ||
945 | * read zero over iteration because this controller status | ||
946 | * register(MMCST0) reports any status only once and it is cleared | ||
947 | * by read. So, it is not unbouned loop even in the case of | ||
948 | * non-dma. | ||
949 | */ | ||
950 | while (host->bytes_left && (status & (MMCST0_DXRDY | MMCST0_DRRDY))) { | ||
951 | davinci_fifo_data_trans(host, rw_threshold); | ||
952 | status = readl(host->base + DAVINCI_MMCST0); | ||
953 | if (!status) | ||
954 | break; | ||
955 | qstatus |= status; | ||
956 | } | ||
957 | |||
958 | if (qstatus & MMCST0_DATDNE) { | ||
959 | /* All blocks sent/received, and CRC checks passed */ | ||
960 | if (data != NULL) { | ||
961 | if ((host->do_dma == 0) && (host->bytes_left > 0)) { | ||
962 | /* if datasize < rw_threshold | ||
963 | * no RX ints are generated | ||
964 | */ | ||
965 | davinci_fifo_data_trans(host, host->bytes_left); | ||
966 | } | ||
967 | end_transfer = 1; | ||
968 | data->bytes_xfered = data->blocks * data->blksz; | ||
969 | } else { | ||
970 | dev_err(mmc_dev(host->mmc), | ||
971 | "DATDNE with no host->data\n"); | ||
972 | } | ||
973 | } | ||
974 | |||
975 | if (qstatus & MMCST0_TOUTRD) { | ||
976 | /* Read data timeout */ | ||
977 | data->error = -ETIMEDOUT; | ||
978 | end_transfer = 1; | ||
979 | |||
980 | dev_dbg(mmc_dev(host->mmc), | ||
981 | "read data timeout, status %x\n", | ||
982 | qstatus); | ||
983 | |||
984 | davinci_abort_data(host, data); | ||
985 | } | ||
986 | |||
987 | if (qstatus & (MMCST0_CRCWR | MMCST0_CRCRD)) { | ||
988 | /* Data CRC error */ | ||
989 | data->error = -EILSEQ; | ||
990 | end_transfer = 1; | ||
991 | |||
992 | /* NOTE: this controller uses CRCWR to report both CRC | ||
993 | * errors and timeouts (on writes). MMCDRSP values are | ||
994 | * only weakly documented, but 0x9f was clearly a timeout | ||
995 | * case and the two three-bit patterns in various SD specs | ||
996 | * (101, 010) aren't part of it ... | ||
997 | */ | ||
998 | if (qstatus & MMCST0_CRCWR) { | ||
999 | u32 temp = readb(host->base + DAVINCI_MMCDRSP); | ||
1000 | |||
1001 | if (temp == 0x9f) | ||
1002 | data->error = -ETIMEDOUT; | ||
1003 | } | ||
1004 | dev_dbg(mmc_dev(host->mmc), "data %s %s error\n", | ||
1005 | (qstatus & MMCST0_CRCWR) ? "write" : "read", | ||
1006 | (data->error == -ETIMEDOUT) ? "timeout" : "CRC"); | ||
1007 | |||
1008 | davinci_abort_data(host, data); | ||
1009 | } | ||
1010 | |||
1011 | if (qstatus & MMCST0_TOUTRS) { | ||
1012 | /* Command timeout */ | ||
1013 | if (host->cmd) { | ||
1014 | dev_dbg(mmc_dev(host->mmc), | ||
1015 | "CMD%d timeout, status %x\n", | ||
1016 | host->cmd->opcode, qstatus); | ||
1017 | host->cmd->error = -ETIMEDOUT; | ||
1018 | if (data) { | ||
1019 | end_transfer = 1; | ||
1020 | davinci_abort_data(host, data); | ||
1021 | } else | ||
1022 | end_command = 1; | ||
1023 | } | ||
1024 | } | ||
1025 | |||
1026 | if (qstatus & MMCST0_CRCRS) { | ||
1027 | /* Command CRC error */ | ||
1028 | dev_dbg(mmc_dev(host->mmc), "Command CRC error\n"); | ||
1029 | if (host->cmd) { | ||
1030 | host->cmd->error = -EILSEQ; | ||
1031 | end_command = 1; | ||
1032 | } | ||
1033 | } | ||
1034 | |||
1035 | if (qstatus & MMCST0_RSPDNE) { | ||
1036 | /* End of command phase */ | ||
1037 | end_command = (int) host->cmd; | ||
1038 | } | ||
1039 | |||
1040 | if (end_command) | ||
1041 | mmc_davinci_cmd_done(host, host->cmd); | ||
1042 | if (end_transfer) | ||
1043 | mmc_davinci_xfer_done(host, data); | ||
1044 | return IRQ_HANDLED; | ||
1045 | } | ||
1046 | |||
1047 | static int mmc_davinci_get_cd(struct mmc_host *mmc) | ||
1048 | { | ||
1049 | struct platform_device *pdev = to_platform_device(mmc->parent); | ||
1050 | struct davinci_mmc_config *config = pdev->dev.platform_data; | ||
1051 | |||
1052 | if (!config || !config->get_cd) | ||
1053 | return -ENOSYS; | ||
1054 | return config->get_cd(pdev->id); | ||
1055 | } | ||
1056 | |||
1057 | static int mmc_davinci_get_ro(struct mmc_host *mmc) | ||
1058 | { | ||
1059 | struct platform_device *pdev = to_platform_device(mmc->parent); | ||
1060 | struct davinci_mmc_config *config = pdev->dev.platform_data; | ||
1061 | |||
1062 | if (!config || !config->get_ro) | ||
1063 | return -ENOSYS; | ||
1064 | return config->get_ro(pdev->id); | ||
1065 | } | ||
1066 | |||
1067 | static struct mmc_host_ops mmc_davinci_ops = { | ||
1068 | .request = mmc_davinci_request, | ||
1069 | .set_ios = mmc_davinci_set_ios, | ||
1070 | .get_cd = mmc_davinci_get_cd, | ||
1071 | .get_ro = mmc_davinci_get_ro, | ||
1072 | }; | ||
1073 | |||
1074 | /*----------------------------------------------------------------------*/ | ||
1075 | |||
1076 | #ifdef CONFIG_CPU_FREQ | ||
1077 | static int mmc_davinci_cpufreq_transition(struct notifier_block *nb, | ||
1078 | unsigned long val, void *data) | ||
1079 | { | ||
1080 | struct mmc_davinci_host *host; | ||
1081 | unsigned int mmc_pclk; | ||
1082 | struct mmc_host *mmc; | ||
1083 | unsigned long flags; | ||
1084 | |||
1085 | host = container_of(nb, struct mmc_davinci_host, freq_transition); | ||
1086 | mmc = host->mmc; | ||
1087 | mmc_pclk = clk_get_rate(host->clk); | ||
1088 | |||
1089 | if (val == CPUFREQ_POSTCHANGE) { | ||
1090 | spin_lock_irqsave(&mmc->lock, flags); | ||
1091 | host->mmc_input_clk = mmc_pclk; | ||
1092 | calculate_clk_divider(mmc, &mmc->ios); | ||
1093 | spin_unlock_irqrestore(&mmc->lock, flags); | ||
1094 | } | ||
1095 | |||
1096 | return 0; | ||
1097 | } | ||
1098 | |||
1099 | static inline int mmc_davinci_cpufreq_register(struct mmc_davinci_host *host) | ||
1100 | { | ||
1101 | host->freq_transition.notifier_call = mmc_davinci_cpufreq_transition; | ||
1102 | |||
1103 | return cpufreq_register_notifier(&host->freq_transition, | ||
1104 | CPUFREQ_TRANSITION_NOTIFIER); | ||
1105 | } | ||
1106 | |||
1107 | static inline void mmc_davinci_cpufreq_deregister(struct mmc_davinci_host *host) | ||
1108 | { | ||
1109 | cpufreq_unregister_notifier(&host->freq_transition, | ||
1110 | CPUFREQ_TRANSITION_NOTIFIER); | ||
1111 | } | ||
1112 | #else | ||
1113 | static inline int mmc_davinci_cpufreq_register(struct mmc_davinci_host *host) | ||
1114 | { | ||
1115 | return 0; | ||
1116 | } | ||
1117 | |||
1118 | static inline void mmc_davinci_cpufreq_deregister(struct mmc_davinci_host *host) | ||
1119 | { | ||
1120 | } | ||
1121 | #endif | ||
1122 | static void __init init_mmcsd_host(struct mmc_davinci_host *host) | ||
1123 | { | ||
1124 | /* DAT line portion is diabled and in reset state */ | ||
1125 | writel(readl(host->base + DAVINCI_MMCCTL) | MMCCTL_DATRST, | ||
1126 | host->base + DAVINCI_MMCCTL); | ||
1127 | |||
1128 | /* CMD line portion is diabled and in reset state */ | ||
1129 | writel(readl(host->base + DAVINCI_MMCCTL) | MMCCTL_CMDRST, | ||
1130 | host->base + DAVINCI_MMCCTL); | ||
1131 | |||
1132 | udelay(10); | ||
1133 | |||
1134 | writel(0, host->base + DAVINCI_MMCCLK); | ||
1135 | writel(MMCCLK_CLKEN, host->base + DAVINCI_MMCCLK); | ||
1136 | |||
1137 | writel(0x1FFF, host->base + DAVINCI_MMCTOR); | ||
1138 | writel(0xFFFF, host->base + DAVINCI_MMCTOD); | ||
1139 | |||
1140 | writel(readl(host->base + DAVINCI_MMCCTL) & ~MMCCTL_DATRST, | ||
1141 | host->base + DAVINCI_MMCCTL); | ||
1142 | writel(readl(host->base + DAVINCI_MMCCTL) & ~MMCCTL_CMDRST, | ||
1143 | host->base + DAVINCI_MMCCTL); | ||
1144 | |||
1145 | udelay(10); | ||
1146 | } | ||
1147 | |||
1148 | static int __init davinci_mmcsd_probe(struct platform_device *pdev) | ||
1149 | { | ||
1150 | struct davinci_mmc_config *pdata = pdev->dev.platform_data; | ||
1151 | struct mmc_davinci_host *host = NULL; | ||
1152 | struct mmc_host *mmc = NULL; | ||
1153 | struct resource *r, *mem = NULL; | ||
1154 | int ret = 0, irq = 0; | ||
1155 | size_t mem_size; | ||
1156 | |||
1157 | /* REVISIT: when we're fully converted, fail if pdata is NULL */ | ||
1158 | |||
1159 | ret = -ENODEV; | ||
1160 | r = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
1161 | irq = platform_get_irq(pdev, 0); | ||
1162 | if (!r || irq == NO_IRQ) | ||
1163 | goto out; | ||
1164 | |||
1165 | ret = -EBUSY; | ||
1166 | mem_size = resource_size(r); | ||
1167 | mem = request_mem_region(r->start, mem_size, pdev->name); | ||
1168 | if (!mem) | ||
1169 | goto out; | ||
1170 | |||
1171 | ret = -ENOMEM; | ||
1172 | mmc = mmc_alloc_host(sizeof(struct mmc_davinci_host), &pdev->dev); | ||
1173 | if (!mmc) | ||
1174 | goto out; | ||
1175 | |||
1176 | host = mmc_priv(mmc); | ||
1177 | host->mmc = mmc; /* Important */ | ||
1178 | |||
1179 | r = platform_get_resource(pdev, IORESOURCE_DMA, 0); | ||
1180 | if (!r) | ||
1181 | goto out; | ||
1182 | host->rxdma = r->start; | ||
1183 | |||
1184 | r = platform_get_resource(pdev, IORESOURCE_DMA, 1); | ||
1185 | if (!r) | ||
1186 | goto out; | ||
1187 | host->txdma = r->start; | ||
1188 | |||
1189 | host->mem_res = mem; | ||
1190 | host->base = ioremap(mem->start, mem_size); | ||
1191 | if (!host->base) | ||
1192 | goto out; | ||
1193 | |||
1194 | ret = -ENXIO; | ||
1195 | host->clk = clk_get(&pdev->dev, "MMCSDCLK"); | ||
1196 | if (IS_ERR(host->clk)) { | ||
1197 | ret = PTR_ERR(host->clk); | ||
1198 | goto out; | ||
1199 | } | ||
1200 | clk_enable(host->clk); | ||
1201 | host->mmc_input_clk = clk_get_rate(host->clk); | ||
1202 | |||
1203 | init_mmcsd_host(host); | ||
1204 | |||
1205 | host->use_dma = use_dma; | ||
1206 | host->irq = irq; | ||
1207 | |||
1208 | if (host->use_dma && davinci_acquire_dma_channels(host) != 0) | ||
1209 | host->use_dma = 0; | ||
1210 | |||
1211 | /* REVISIT: someday, support IRQ-driven card detection. */ | ||
1212 | mmc->caps |= MMC_CAP_NEEDS_POLL; | ||
1213 | mmc->caps |= MMC_CAP_WAIT_WHILE_BUSY; | ||
1214 | |||
1215 | if (pdata && (pdata->wires == 4 || pdata->wires == 0)) | ||
1216 | mmc->caps |= MMC_CAP_4_BIT_DATA; | ||
1217 | |||
1218 | if (pdata && (pdata->wires == 8)) | ||
1219 | mmc->caps |= (MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA); | ||
1220 | |||
1221 | host->version = pdata->version; | ||
1222 | |||
1223 | mmc->ops = &mmc_davinci_ops; | ||
1224 | mmc->f_min = 312500; | ||
1225 | mmc->f_max = 25000000; | ||
1226 | if (pdata && pdata->max_freq) | ||
1227 | mmc->f_max = pdata->max_freq; | ||
1228 | if (pdata && pdata->caps) | ||
1229 | mmc->caps |= pdata->caps; | ||
1230 | mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34; | ||
1231 | |||
1232 | /* With no iommu coalescing pages, each phys_seg is a hw_seg. | ||
1233 | * Each hw_seg uses one EDMA parameter RAM slot, always one | ||
1234 | * channel and then usually some linked slots. | ||
1235 | */ | ||
1236 | mmc->max_hw_segs = 1 + host->n_link; | ||
1237 | mmc->max_phys_segs = mmc->max_hw_segs; | ||
1238 | |||
1239 | /* EDMA limit per hw segment (one or two MBytes) */ | ||
1240 | mmc->max_seg_size = MAX_CCNT * rw_threshold; | ||
1241 | |||
1242 | /* MMC/SD controller limits for multiblock requests */ | ||
1243 | mmc->max_blk_size = 4095; /* BLEN is 12 bits */ | ||
1244 | mmc->max_blk_count = 65535; /* NBLK is 16 bits */ | ||
1245 | mmc->max_req_size = mmc->max_blk_size * mmc->max_blk_count; | ||
1246 | |||
1247 | dev_dbg(mmc_dev(host->mmc), "max_phys_segs=%d\n", mmc->max_phys_segs); | ||
1248 | dev_dbg(mmc_dev(host->mmc), "max_hw_segs=%d\n", mmc->max_hw_segs); | ||
1249 | dev_dbg(mmc_dev(host->mmc), "max_blk_size=%d\n", mmc->max_blk_size); | ||
1250 | dev_dbg(mmc_dev(host->mmc), "max_req_size=%d\n", mmc->max_req_size); | ||
1251 | dev_dbg(mmc_dev(host->mmc), "max_seg_size=%d\n", mmc->max_seg_size); | ||
1252 | |||
1253 | platform_set_drvdata(pdev, host); | ||
1254 | |||
1255 | ret = mmc_davinci_cpufreq_register(host); | ||
1256 | if (ret) { | ||
1257 | dev_err(&pdev->dev, "failed to register cpufreq\n"); | ||
1258 | goto cpu_freq_fail; | ||
1259 | } | ||
1260 | |||
1261 | ret = mmc_add_host(mmc); | ||
1262 | if (ret < 0) | ||
1263 | goto out; | ||
1264 | |||
1265 | ret = request_irq(irq, mmc_davinci_irq, 0, mmc_hostname(mmc), host); | ||
1266 | if (ret) | ||
1267 | goto out; | ||
1268 | |||
1269 | rename_region(mem, mmc_hostname(mmc)); | ||
1270 | |||
1271 | dev_info(mmc_dev(host->mmc), "Using %s, %d-bit mode\n", | ||
1272 | host->use_dma ? "DMA" : "PIO", | ||
1273 | (mmc->caps & MMC_CAP_4_BIT_DATA) ? 4 : 1); | ||
1274 | |||
1275 | return 0; | ||
1276 | |||
1277 | out: | ||
1278 | mmc_davinci_cpufreq_deregister(host); | ||
1279 | cpu_freq_fail: | ||
1280 | if (host) { | ||
1281 | davinci_release_dma_channels(host); | ||
1282 | |||
1283 | if (host->clk) { | ||
1284 | clk_disable(host->clk); | ||
1285 | clk_put(host->clk); | ||
1286 | } | ||
1287 | |||
1288 | if (host->base) | ||
1289 | iounmap(host->base); | ||
1290 | } | ||
1291 | |||
1292 | if (mmc) | ||
1293 | mmc_free_host(mmc); | ||
1294 | |||
1295 | if (mem) | ||
1296 | release_resource(mem); | ||
1297 | |||
1298 | dev_dbg(&pdev->dev, "probe err %d\n", ret); | ||
1299 | |||
1300 | return ret; | ||
1301 | } | ||
1302 | |||
1303 | static int __exit davinci_mmcsd_remove(struct platform_device *pdev) | ||
1304 | { | ||
1305 | struct mmc_davinci_host *host = platform_get_drvdata(pdev); | ||
1306 | |||
1307 | platform_set_drvdata(pdev, NULL); | ||
1308 | if (host) { | ||
1309 | mmc_davinci_cpufreq_deregister(host); | ||
1310 | |||
1311 | mmc_remove_host(host->mmc); | ||
1312 | free_irq(host->irq, host); | ||
1313 | |||
1314 | davinci_release_dma_channels(host); | ||
1315 | |||
1316 | clk_disable(host->clk); | ||
1317 | clk_put(host->clk); | ||
1318 | |||
1319 | iounmap(host->base); | ||
1320 | |||
1321 | release_resource(host->mem_res); | ||
1322 | |||
1323 | mmc_free_host(host->mmc); | ||
1324 | } | ||
1325 | |||
1326 | return 0; | ||
1327 | } | ||
1328 | |||
1329 | #ifdef CONFIG_PM | ||
1330 | static int davinci_mmcsd_suspend(struct platform_device *pdev, pm_message_t msg) | ||
1331 | { | ||
1332 | struct mmc_davinci_host *host = platform_get_drvdata(pdev); | ||
1333 | |||
1334 | return mmc_suspend_host(host->mmc, msg); | ||
1335 | } | ||
1336 | |||
1337 | static int davinci_mmcsd_resume(struct platform_device *pdev) | ||
1338 | { | ||
1339 | struct mmc_davinci_host *host = platform_get_drvdata(pdev); | ||
1340 | |||
1341 | return mmc_resume_host(host->mmc); | ||
1342 | } | ||
1343 | #else | ||
1344 | #define davinci_mmcsd_suspend NULL | ||
1345 | #define davinci_mmcsd_resume NULL | ||
1346 | #endif | ||
1347 | |||
1348 | static struct platform_driver davinci_mmcsd_driver = { | ||
1349 | .driver = { | ||
1350 | .name = "davinci_mmc", | ||
1351 | .owner = THIS_MODULE, | ||
1352 | }, | ||
1353 | .remove = __exit_p(davinci_mmcsd_remove), | ||
1354 | .suspend = davinci_mmcsd_suspend, | ||
1355 | .resume = davinci_mmcsd_resume, | ||
1356 | }; | ||
1357 | |||
1358 | static int __init davinci_mmcsd_init(void) | ||
1359 | { | ||
1360 | return platform_driver_probe(&davinci_mmcsd_driver, | ||
1361 | davinci_mmcsd_probe); | ||
1362 | } | ||
1363 | module_init(davinci_mmcsd_init); | ||
1364 | |||
1365 | static void __exit davinci_mmcsd_exit(void) | ||
1366 | { | ||
1367 | platform_driver_unregister(&davinci_mmcsd_driver); | ||
1368 | } | ||
1369 | module_exit(davinci_mmcsd_exit); | ||
1370 | |||
1371 | MODULE_AUTHOR("Texas Instruments India"); | ||
1372 | MODULE_LICENSE("GPL"); | ||
1373 | MODULE_DESCRIPTION("MMC/SD driver for Davinci MMC controller"); | ||
1374 | |||
diff --git a/drivers/mmc/host/mmc_spi.c b/drivers/mmc/host/mmc_spi.c index d55fe4fb7935..ad847a24a675 100644 --- a/drivers/mmc/host/mmc_spi.c +++ b/drivers/mmc/host/mmc_spi.c | |||
@@ -26,6 +26,7 @@ | |||
26 | */ | 26 | */ |
27 | #include <linux/sched.h> | 27 | #include <linux/sched.h> |
28 | #include <linux/delay.h> | 28 | #include <linux/delay.h> |
29 | #include <linux/slab.h> | ||
29 | #include <linux/bio.h> | 30 | #include <linux/bio.h> |
30 | #include <linux/dma-mapping.h> | 31 | #include <linux/dma-mapping.h> |
31 | #include <linux/crc7.h> | 32 | #include <linux/crc7.h> |
diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c index 705a5894a6bb..84c103a7ee13 100644 --- a/drivers/mmc/host/mmci.c +++ b/drivers/mmc/host/mmci.c | |||
@@ -2,6 +2,7 @@ | |||
2 | * linux/drivers/mmc/host/mmci.c - ARM PrimeCell MMCI PL180/1 driver | 2 | * linux/drivers/mmc/host/mmci.c - ARM PrimeCell MMCI PL180/1 driver |
3 | * | 3 | * |
4 | * Copyright (C) 2003 Deep Blue Solutions, Ltd, All Rights Reserved. | 4 | * Copyright (C) 2003 Deep Blue Solutions, Ltd, All Rights Reserved. |
5 | * Copyright (C) 2010 ST-Ericsson AB. | ||
5 | * | 6 | * |
6 | * This program is free software; you can redistribute it and/or modify | 7 | * 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 | * it under the terms of the GNU General Public License version 2 as |
@@ -34,9 +35,6 @@ | |||
34 | 35 | ||
35 | #define DRIVER_NAME "mmci-pl18x" | 36 | #define DRIVER_NAME "mmci-pl18x" |
36 | 37 | ||
37 | #define DBG(host,fmt,args...) \ | ||
38 | pr_debug("%s: %s: " fmt, mmc_hostname(host->mmc), __func__ , args) | ||
39 | |||
40 | static unsigned int fmax = 515633; | 38 | static unsigned int fmax = 515633; |
41 | 39 | ||
42 | /* | 40 | /* |
@@ -56,7 +54,7 @@ static void mmci_set_clkreg(struct mmci_host *host, unsigned int desired) | |||
56 | clk = 255; | 54 | clk = 255; |
57 | host->cclk = host->mclk / (2 * (clk + 1)); | 55 | host->cclk = host->mclk / (2 * (clk + 1)); |
58 | } | 56 | } |
59 | if (host->hw_designer == 0x80) | 57 | if (host->hw_designer == AMBA_VENDOR_ST) |
60 | clk |= MCI_FCEN; /* Bug fix in ST IP block */ | 58 | clk |= MCI_FCEN; /* Bug fix in ST IP block */ |
61 | clk |= MCI_CLK_ENABLE; | 59 | clk |= MCI_CLK_ENABLE; |
62 | /* This hasn't proven to be worthwhile */ | 60 | /* This hasn't proven to be worthwhile */ |
@@ -105,8 +103,8 @@ static void mmci_start_data(struct mmci_host *host, struct mmc_data *data) | |||
105 | void __iomem *base; | 103 | void __iomem *base; |
106 | int blksz_bits; | 104 | int blksz_bits; |
107 | 105 | ||
108 | DBG(host, "blksz %04x blks %04x flags %08x\n", | 106 | dev_dbg(mmc_dev(host->mmc), "blksz %04x blks %04x flags %08x\n", |
109 | data->blksz, data->blocks, data->flags); | 107 | data->blksz, data->blocks, data->flags); |
110 | 108 | ||
111 | host->data = data; | 109 | host->data = data; |
112 | host->size = data->blksz; | 110 | host->size = data->blksz; |
@@ -155,7 +153,7 @@ mmci_start_command(struct mmci_host *host, struct mmc_command *cmd, u32 c) | |||
155 | { | 153 | { |
156 | void __iomem *base = host->base; | 154 | void __iomem *base = host->base; |
157 | 155 | ||
158 | DBG(host, "op %02x arg %08x flags %08x\n", | 156 | dev_dbg(mmc_dev(host->mmc), "op %02x arg %08x flags %08x\n", |
159 | cmd->opcode, cmd->arg, cmd->flags); | 157 | cmd->opcode, cmd->arg, cmd->flags); |
160 | 158 | ||
161 | if (readl(base + MMCICOMMAND) & MCI_CPSM_ENABLE) { | 159 | if (readl(base + MMCICOMMAND) & MCI_CPSM_ENABLE) { |
@@ -184,8 +182,20 @@ mmci_data_irq(struct mmci_host *host, struct mmc_data *data, | |||
184 | { | 182 | { |
185 | if (status & MCI_DATABLOCKEND) { | 183 | if (status & MCI_DATABLOCKEND) { |
186 | host->data_xfered += data->blksz; | 184 | host->data_xfered += data->blksz; |
185 | #ifdef CONFIG_ARCH_U300 | ||
186 | /* | ||
187 | * On the U300 some signal or other is | ||
188 | * badly routed so that a data write does | ||
189 | * not properly terminate with a MCI_DATAEND | ||
190 | * status flag. This quirk will make writes | ||
191 | * work again. | ||
192 | */ | ||
193 | if (data->flags & MMC_DATA_WRITE) | ||
194 | status |= MCI_DATAEND; | ||
195 | #endif | ||
187 | } | 196 | } |
188 | if (status & (MCI_DATACRCFAIL|MCI_DATATIMEOUT|MCI_TXUNDERRUN|MCI_RXOVERRUN)) { | 197 | if (status & (MCI_DATACRCFAIL|MCI_DATATIMEOUT|MCI_TXUNDERRUN|MCI_RXOVERRUN)) { |
198 | dev_dbg(mmc_dev(host->mmc), "MCI ERROR IRQ (status %08x)\n", status); | ||
189 | if (status & MCI_DATACRCFAIL) | 199 | if (status & MCI_DATACRCFAIL) |
190 | data->error = -EILSEQ; | 200 | data->error = -EILSEQ; |
191 | else if (status & MCI_DATATIMEOUT) | 201 | else if (status & MCI_DATATIMEOUT) |
@@ -307,7 +317,7 @@ static irqreturn_t mmci_pio_irq(int irq, void *dev_id) | |||
307 | 317 | ||
308 | status = readl(base + MMCISTATUS); | 318 | status = readl(base + MMCISTATUS); |
309 | 319 | ||
310 | DBG(host, "irq1 %08x\n", status); | 320 | dev_dbg(mmc_dev(host->mmc), "irq1 (pio) %08x\n", status); |
311 | 321 | ||
312 | do { | 322 | do { |
313 | unsigned long flags; | 323 | unsigned long flags; |
@@ -401,7 +411,7 @@ static irqreturn_t mmci_irq(int irq, void *dev_id) | |||
401 | status &= readl(host->base + MMCIMASK0); | 411 | status &= readl(host->base + MMCIMASK0); |
402 | writel(status, host->base + MMCICLEAR); | 412 | writel(status, host->base + MMCICLEAR); |
403 | 413 | ||
404 | DBG(host, "irq0 %08x\n", status); | 414 | dev_dbg(mmc_dev(host->mmc), "irq0 (data+cmd) %08x\n", status); |
405 | 415 | ||
406 | data = host->data; | 416 | data = host->data; |
407 | if (status & (MCI_DATACRCFAIL|MCI_DATATIMEOUT|MCI_TXUNDERRUN| | 417 | if (status & (MCI_DATACRCFAIL|MCI_DATATIMEOUT|MCI_TXUNDERRUN| |
@@ -428,8 +438,8 @@ static void mmci_request(struct mmc_host *mmc, struct mmc_request *mrq) | |||
428 | WARN_ON(host->mrq != NULL); | 438 | WARN_ON(host->mrq != NULL); |
429 | 439 | ||
430 | if (mrq->data && !is_power_of_2(mrq->data->blksz)) { | 440 | if (mrq->data && !is_power_of_2(mrq->data->blksz)) { |
431 | printk(KERN_ERR "%s: Unsupported block size (%d bytes)\n", | 441 | dev_err(mmc_dev(mmc), "unsupported block size (%d bytes)\n", |
432 | mmc_hostname(mmc), mrq->data->blksz); | 442 | mrq->data->blksz); |
433 | mrq->cmd->error = -EINVAL; | 443 | mrq->cmd->error = -EINVAL; |
434 | mmc_request_done(mmc, mrq); | 444 | mmc_request_done(mmc, mrq); |
435 | return; | 445 | return; |
@@ -582,8 +592,8 @@ static int __devinit mmci_probe(struct amba_device *dev, struct amba_id *id) | |||
582 | 592 | ||
583 | host->hw_designer = amba_manf(dev); | 593 | host->hw_designer = amba_manf(dev); |
584 | host->hw_revision = amba_rev(dev); | 594 | host->hw_revision = amba_rev(dev); |
585 | DBG(host, "designer ID = 0x%02x\n", host->hw_designer); | 595 | dev_dbg(mmc_dev(mmc), "designer ID = 0x%02x\n", host->hw_designer); |
586 | DBG(host, "revision = 0x%01x\n", host->hw_revision); | 596 | dev_dbg(mmc_dev(mmc), "revision = 0x%01x\n", host->hw_revision); |
587 | 597 | ||
588 | host->clk = clk_get(&dev->dev, NULL); | 598 | host->clk = clk_get(&dev->dev, NULL); |
589 | if (IS_ERR(host->clk)) { | 599 | if (IS_ERR(host->clk)) { |
@@ -608,7 +618,8 @@ static int __devinit mmci_probe(struct amba_device *dev, struct amba_id *id) | |||
608 | if (ret < 0) | 618 | if (ret < 0) |
609 | goto clk_disable; | 619 | goto clk_disable; |
610 | host->mclk = clk_get_rate(host->clk); | 620 | host->mclk = clk_get_rate(host->clk); |
611 | DBG(host, "eventual mclk rate: %u Hz\n", host->mclk); | 621 | dev_dbg(mmc_dev(mmc), "eventual mclk rate: %u Hz\n", |
622 | host->mclk); | ||
612 | } | 623 | } |
613 | host->base = ioremap(dev->res.start, resource_size(&dev->res)); | 624 | host->base = ioremap(dev->res.start, resource_size(&dev->res)); |
614 | if (!host->base) { | 625 | if (!host->base) { |
@@ -619,6 +630,8 @@ static int __devinit mmci_probe(struct amba_device *dev, struct amba_id *id) | |||
619 | mmc->ops = &mmci_ops; | 630 | mmc->ops = &mmci_ops; |
620 | mmc->f_min = (host->mclk + 511) / 512; | 631 | mmc->f_min = (host->mclk + 511) / 512; |
621 | mmc->f_max = min(host->mclk, fmax); | 632 | mmc->f_max = min(host->mclk, fmax); |
633 | dev_dbg(mmc_dev(mmc), "clocking block at %u Hz\n", mmc->f_max); | ||
634 | |||
622 | #ifdef CONFIG_REGULATOR | 635 | #ifdef CONFIG_REGULATOR |
623 | /* If we're using the regulator framework, try to fetch a regulator */ | 636 | /* If we're using the regulator framework, try to fetch a regulator */ |
624 | host->vcc = regulator_get(&dev->dev, "vmmc"); | 637 | host->vcc = regulator_get(&dev->dev, "vmmc"); |
@@ -712,7 +725,7 @@ static int __devinit mmci_probe(struct amba_device *dev, struct amba_id *id) | |||
712 | 725 | ||
713 | mmc_add_host(mmc); | 726 | mmc_add_host(mmc); |
714 | 727 | ||
715 | printk(KERN_INFO "%s: MMCI rev %x cfg %02x at 0x%016llx irq %d,%d\n", | 728 | dev_info(&dev->dev, "%s: MMCI rev %x cfg %02x at 0x%016llx irq %d,%d\n", |
716 | mmc_hostname(mmc), amba_rev(dev), amba_config(dev), | 729 | mmc_hostname(mmc), amba_rev(dev), amba_config(dev), |
717 | (unsigned long long)dev->res.start, dev->irq[0], dev->irq[1]); | 730 | (unsigned long long)dev->res.start, dev->irq[0], dev->irq[1]); |
718 | 731 | ||
diff --git a/drivers/mmc/host/msm_sdcc.c b/drivers/mmc/host/msm_sdcc.c index dba4600bcdb4..04ae884383f6 100644 --- a/drivers/mmc/host/msm_sdcc.c +++ b/drivers/mmc/host/msm_sdcc.c | |||
@@ -33,15 +33,15 @@ | |||
33 | #include <linux/debugfs.h> | 33 | #include <linux/debugfs.h> |
34 | #include <linux/io.h> | 34 | #include <linux/io.h> |
35 | #include <linux/memory.h> | 35 | #include <linux/memory.h> |
36 | #include <linux/gfp.h> | ||
36 | 37 | ||
37 | #include <asm/cacheflush.h> | 38 | #include <asm/cacheflush.h> |
38 | #include <asm/div64.h> | 39 | #include <asm/div64.h> |
39 | #include <asm/sizes.h> | 40 | #include <asm/sizes.h> |
40 | 41 | ||
41 | #include <asm/mach/mmc.h> | 42 | #include <mach/mmc.h> |
42 | #include <mach/msm_iomap.h> | 43 | #include <mach/msm_iomap.h> |
43 | #include <mach/dma.h> | 44 | #include <mach/dma.h> |
44 | #include <mach/htc_pwrsink.h> | ||
45 | 45 | ||
46 | #include "msm_sdcc.h" | 46 | #include "msm_sdcc.h" |
47 | 47 | ||
@@ -775,13 +775,11 @@ msmsdcc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) | |||
775 | 775 | ||
776 | switch (ios->power_mode) { | 776 | switch (ios->power_mode) { |
777 | case MMC_POWER_OFF: | 777 | case MMC_POWER_OFF: |
778 | htc_pwrsink_set(PWRSINK_SDCARD, 0); | ||
779 | break; | 778 | break; |
780 | case MMC_POWER_UP: | 779 | case MMC_POWER_UP: |
781 | pwr |= MCI_PWR_UP; | 780 | pwr |= MCI_PWR_UP; |
782 | break; | 781 | break; |
783 | case MMC_POWER_ON: | 782 | case MMC_POWER_ON: |
784 | htc_pwrsink_set(PWRSINK_SDCARD, 100); | ||
785 | pwr |= MCI_PWR_ON; | 783 | pwr |= MCI_PWR_ON; |
786 | break; | 784 | break; |
787 | } | 785 | } |
@@ -1253,9 +1251,7 @@ msmsdcc_resume(struct platform_device *dev) | |||
1253 | 1251 | ||
1254 | if (mmc->card && mmc->card->type != MMC_TYPE_SDIO) | 1252 | if (mmc->card && mmc->card->type != MMC_TYPE_SDIO) |
1255 | mmc_resume_host(mmc); | 1253 | mmc_resume_host(mmc); |
1256 | if (host->stat_irq) | 1254 | if (host->stat_irq) |
1257 | enable_irq(host->stat_irq); | ||
1258 | else if (host->stat_irq) | ||
1259 | enable_irq(host->stat_irq); | 1255 | enable_irq(host->stat_irq); |
1260 | } | 1256 | } |
1261 | return 0; | 1257 | return 0; |
diff --git a/drivers/mmc/host/mxcmmc.c b/drivers/mmc/host/mxcmmc.c index 88671529c45d..2df90412abb5 100644 --- a/drivers/mmc/host/mxcmmc.c +++ b/drivers/mmc/host/mxcmmc.c | |||
@@ -4,7 +4,7 @@ | |||
4 | * This is a driver for the SDHC controller found in Freescale MX2/MX3 | 4 | * This is a driver for the SDHC controller found in Freescale MX2/MX3 |
5 | * SoCs. It is basically the same hardware as found on MX1 (imxmmc.c). | 5 | * SoCs. It is basically the same hardware as found on MX1 (imxmmc.c). |
6 | * Unlike the hardware found on MX1, this hardware just works and does | 6 | * Unlike the hardware found on MX1, this hardware just works and does |
7 | * not need all the quirks found in imxmmc.c, hence the seperate driver. | 7 | * not need all the quirks found in imxmmc.c, hence the separate driver. |
8 | * | 8 | * |
9 | * Copyright (C) 2008 Sascha Hauer, Pengutronix <s.hauer@pengutronix.de> | 9 | * Copyright (C) 2008 Sascha Hauer, Pengutronix <s.hauer@pengutronix.de> |
10 | * Copyright (C) 2006 Pavel Pisa, PiKRON <ppisa@pikron.com> | 10 | * Copyright (C) 2006 Pavel Pisa, PiKRON <ppisa@pikron.com> |
@@ -679,17 +679,17 @@ static int mxcmci_probe(struct platform_device *pdev) | |||
679 | { | 679 | { |
680 | struct mmc_host *mmc; | 680 | struct mmc_host *mmc; |
681 | struct mxcmci_host *host = NULL; | 681 | struct mxcmci_host *host = NULL; |
682 | struct resource *r; | 682 | struct resource *iores, *r; |
683 | int ret = 0, irq; | 683 | int ret = 0, irq; |
684 | 684 | ||
685 | printk(KERN_INFO "i.MX SDHC driver\n"); | 685 | printk(KERN_INFO "i.MX SDHC driver\n"); |
686 | 686 | ||
687 | r = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 687 | iores = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
688 | irq = platform_get_irq(pdev, 0); | 688 | irq = platform_get_irq(pdev, 0); |
689 | if (!r || irq < 0) | 689 | if (!iores || irq < 0) |
690 | return -EINVAL; | 690 | return -EINVAL; |
691 | 691 | ||
692 | r = request_mem_region(r->start, resource_size(r), pdev->name); | 692 | r = request_mem_region(iores->start, resource_size(iores), pdev->name); |
693 | if (!r) | 693 | if (!r) |
694 | return -EBUSY; | 694 | return -EBUSY; |
695 | 695 | ||
@@ -708,7 +708,7 @@ static int mxcmci_probe(struct platform_device *pdev) | |||
708 | mmc->max_blk_size = 2048; | 708 | mmc->max_blk_size = 2048; |
709 | mmc->max_blk_count = 65535; | 709 | mmc->max_blk_count = 65535; |
710 | mmc->max_req_size = mmc->max_blk_size * mmc->max_blk_count; | 710 | mmc->max_req_size = mmc->max_blk_size * mmc->max_blk_count; |
711 | mmc->max_seg_size = mmc->max_seg_size; | 711 | mmc->max_seg_size = mmc->max_req_size; |
712 | 712 | ||
713 | host = mmc_priv(mmc); | 713 | host = mmc_priv(mmc); |
714 | host->base = ioremap(r->start, resource_size(r)); | 714 | host->base = ioremap(r->start, resource_size(r)); |
@@ -809,7 +809,7 @@ out_iounmap: | |||
809 | out_free: | 809 | out_free: |
810 | mmc_free_host(mmc); | 810 | mmc_free_host(mmc); |
811 | out_release_mem: | 811 | out_release_mem: |
812 | release_mem_region(host->res->start, resource_size(host->res)); | 812 | release_mem_region(iores->start, resource_size(iores)); |
813 | return ret; | 813 | return ret; |
814 | } | 814 | } |
815 | 815 | ||
diff --git a/drivers/mmc/host/of_mmc_spi.c b/drivers/mmc/host/of_mmc_spi.c index 0c44d560bf1a..bb6cc54b558e 100644 --- a/drivers/mmc/host/of_mmc_spi.c +++ b/drivers/mmc/host/of_mmc_spi.c | |||
@@ -14,6 +14,7 @@ | |||
14 | #include <linux/kernel.h> | 14 | #include <linux/kernel.h> |
15 | #include <linux/module.h> | 15 | #include <linux/module.h> |
16 | #include <linux/device.h> | 16 | #include <linux/device.h> |
17 | #include <linux/slab.h> | ||
17 | #include <linux/gpio.h> | 18 | #include <linux/gpio.h> |
18 | #include <linux/of.h> | 19 | #include <linux/of.h> |
19 | #include <linux/of_gpio.h> | 20 | #include <linux/of_gpio.h> |
@@ -22,6 +23,8 @@ | |||
22 | #include <linux/mmc/core.h> | 23 | #include <linux/mmc/core.h> |
23 | #include <linux/mmc/host.h> | 24 | #include <linux/mmc/host.h> |
24 | 25 | ||
26 | MODULE_LICENSE("GPL"); | ||
27 | |||
25 | enum { | 28 | enum { |
26 | CD_GPIO = 0, | 29 | CD_GPIO = 0, |
27 | WP_GPIO, | 30 | WP_GPIO, |
diff --git a/drivers/mmc/host/omap.c b/drivers/mmc/host/omap.c index b8fd7af1ceeb..84d280406341 100644 --- a/drivers/mmc/host/omap.c +++ b/drivers/mmc/host/omap.c | |||
@@ -26,16 +26,17 @@ | |||
26 | #include <linux/clk.h> | 26 | #include <linux/clk.h> |
27 | #include <linux/scatterlist.h> | 27 | #include <linux/scatterlist.h> |
28 | #include <linux/i2c/tps65010.h> | 28 | #include <linux/i2c/tps65010.h> |
29 | #include <linux/slab.h> | ||
29 | 30 | ||
30 | #include <asm/io.h> | 31 | #include <asm/io.h> |
31 | #include <asm/irq.h> | 32 | #include <asm/irq.h> |
32 | 33 | ||
33 | #include <mach/board.h> | 34 | #include <plat/board.h> |
34 | #include <mach/mmc.h> | 35 | #include <plat/mmc.h> |
35 | #include <mach/gpio.h> | 36 | #include <mach/gpio.h> |
36 | #include <mach/dma.h> | 37 | #include <plat/dma.h> |
37 | #include <mach/mux.h> | 38 | #include <plat/mux.h> |
38 | #include <mach/fpga.h> | 39 | #include <plat/fpga.h> |
39 | 40 | ||
40 | #define OMAP_MMC_REG_CMD 0x00 | 41 | #define OMAP_MMC_REG_CMD 0x00 |
41 | #define OMAP_MMC_REG_ARGL 0x04 | 42 | #define OMAP_MMC_REG_ARGL 0x04 |
@@ -1459,8 +1460,10 @@ static int __init mmc_omap_probe(struct platform_device *pdev) | |||
1459 | goto err_ioremap; | 1460 | goto err_ioremap; |
1460 | 1461 | ||
1461 | host->iclk = clk_get(&pdev->dev, "ick"); | 1462 | host->iclk = clk_get(&pdev->dev, "ick"); |
1462 | if (IS_ERR(host->iclk)) | 1463 | if (IS_ERR(host->iclk)) { |
1464 | ret = PTR_ERR(host->iclk); | ||
1463 | goto err_free_mmc_host; | 1465 | goto err_free_mmc_host; |
1466 | } | ||
1464 | clk_enable(host->iclk); | 1467 | clk_enable(host->iclk); |
1465 | 1468 | ||
1466 | host->fclk = clk_get(&pdev->dev, "fck"); | 1469 | host->fclk = clk_get(&pdev->dev, "fck"); |
@@ -1500,10 +1503,8 @@ err_free_irq: | |||
1500 | err_free_fclk: | 1503 | err_free_fclk: |
1501 | clk_put(host->fclk); | 1504 | clk_put(host->fclk); |
1502 | err_free_iclk: | 1505 | err_free_iclk: |
1503 | if (host->iclk != NULL) { | 1506 | clk_disable(host->iclk); |
1504 | clk_disable(host->iclk); | 1507 | clk_put(host->iclk); |
1505 | clk_put(host->iclk); | ||
1506 | } | ||
1507 | err_free_mmc_host: | 1508 | err_free_mmc_host: |
1508 | iounmap(host->virt_base); | 1509 | iounmap(host->virt_base); |
1509 | err_ioremap: | 1510 | err_ioremap: |
diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c index 0aecaaebef3d..e9caf694c59e 100644 --- a/drivers/mmc/host/omap_hsmmc.c +++ b/drivers/mmc/host/omap_hsmmc.c | |||
@@ -30,11 +30,13 @@ | |||
30 | #include <linux/mmc/core.h> | 30 | #include <linux/mmc/core.h> |
31 | #include <linux/io.h> | 31 | #include <linux/io.h> |
32 | #include <linux/semaphore.h> | 32 | #include <linux/semaphore.h> |
33 | #include <mach/dma.h> | 33 | #include <linux/gpio.h> |
34 | #include <linux/regulator/consumer.h> | ||
35 | #include <plat/dma.h> | ||
34 | #include <mach/hardware.h> | 36 | #include <mach/hardware.h> |
35 | #include <mach/board.h> | 37 | #include <plat/board.h> |
36 | #include <mach/mmc.h> | 38 | #include <plat/mmc.h> |
37 | #include <mach/cpu.h> | 39 | #include <plat/cpu.h> |
38 | 40 | ||
39 | /* OMAP HSMMC Host Controller Registers */ | 41 | /* OMAP HSMMC Host Controller Registers */ |
40 | #define OMAP_HSMMC_SYSCONFIG 0x0010 | 42 | #define OMAP_HSMMC_SYSCONFIG 0x0010 |
@@ -146,6 +148,15 @@ struct omap_hsmmc_host { | |||
146 | struct clk *fclk; | 148 | struct clk *fclk; |
147 | struct clk *iclk; | 149 | struct clk *iclk; |
148 | struct clk *dbclk; | 150 | struct clk *dbclk; |
151 | /* | ||
152 | * vcc == configured supply | ||
153 | * vcc_aux == optional | ||
154 | * - MMC1, supply for DAT4..DAT7 | ||
155 | * - MMC2/MMC2, external level shifter voltage supply, for | ||
156 | * chip (SDIO, eMMC, etc) or transceiver (MMC2 only) | ||
157 | */ | ||
158 | struct regulator *vcc; | ||
159 | struct regulator *vcc_aux; | ||
149 | struct semaphore sem; | 160 | struct semaphore sem; |
150 | struct work_struct mmc_carddetect_work; | 161 | struct work_struct mmc_carddetect_work; |
151 | void __iomem *base; | 162 | void __iomem *base; |
@@ -171,10 +182,337 @@ struct omap_hsmmc_host { | |||
171 | int vdd; | 182 | int vdd; |
172 | int protect_card; | 183 | int protect_card; |
173 | int reqs_blocked; | 184 | int reqs_blocked; |
185 | int use_reg; | ||
174 | 186 | ||
175 | struct omap_mmc_platform_data *pdata; | 187 | struct omap_mmc_platform_data *pdata; |
176 | }; | 188 | }; |
177 | 189 | ||
190 | static int omap_hsmmc_card_detect(struct device *dev, int slot) | ||
191 | { | ||
192 | struct omap_mmc_platform_data *mmc = dev->platform_data; | ||
193 | |||
194 | /* NOTE: assumes card detect signal is active-low */ | ||
195 | return !gpio_get_value_cansleep(mmc->slots[0].switch_pin); | ||
196 | } | ||
197 | |||
198 | static int omap_hsmmc_get_wp(struct device *dev, int slot) | ||
199 | { | ||
200 | struct omap_mmc_platform_data *mmc = dev->platform_data; | ||
201 | |||
202 | /* NOTE: assumes write protect signal is active-high */ | ||
203 | return gpio_get_value_cansleep(mmc->slots[0].gpio_wp); | ||
204 | } | ||
205 | |||
206 | static int omap_hsmmc_get_cover_state(struct device *dev, int slot) | ||
207 | { | ||
208 | struct omap_mmc_platform_data *mmc = dev->platform_data; | ||
209 | |||
210 | /* NOTE: assumes card detect signal is active-low */ | ||
211 | return !gpio_get_value_cansleep(mmc->slots[0].switch_pin); | ||
212 | } | ||
213 | |||
214 | #ifdef CONFIG_PM | ||
215 | |||
216 | static int omap_hsmmc_suspend_cdirq(struct device *dev, int slot) | ||
217 | { | ||
218 | struct omap_mmc_platform_data *mmc = dev->platform_data; | ||
219 | |||
220 | disable_irq(mmc->slots[0].card_detect_irq); | ||
221 | return 0; | ||
222 | } | ||
223 | |||
224 | static int omap_hsmmc_resume_cdirq(struct device *dev, int slot) | ||
225 | { | ||
226 | struct omap_mmc_platform_data *mmc = dev->platform_data; | ||
227 | |||
228 | enable_irq(mmc->slots[0].card_detect_irq); | ||
229 | return 0; | ||
230 | } | ||
231 | |||
232 | #else | ||
233 | |||
234 | #define omap_hsmmc_suspend_cdirq NULL | ||
235 | #define omap_hsmmc_resume_cdirq NULL | ||
236 | |||
237 | #endif | ||
238 | |||
239 | #ifdef CONFIG_REGULATOR | ||
240 | |||
241 | static int omap_hsmmc_1_set_power(struct device *dev, int slot, int power_on, | ||
242 | int vdd) | ||
243 | { | ||
244 | struct omap_hsmmc_host *host = | ||
245 | platform_get_drvdata(to_platform_device(dev)); | ||
246 | int ret; | ||
247 | |||
248 | if (mmc_slot(host).before_set_reg) | ||
249 | mmc_slot(host).before_set_reg(dev, slot, power_on, vdd); | ||
250 | |||
251 | if (power_on) | ||
252 | ret = mmc_regulator_set_ocr(host->vcc, vdd); | ||
253 | else | ||
254 | ret = mmc_regulator_set_ocr(host->vcc, 0); | ||
255 | |||
256 | if (mmc_slot(host).after_set_reg) | ||
257 | mmc_slot(host).after_set_reg(dev, slot, power_on, vdd); | ||
258 | |||
259 | return ret; | ||
260 | } | ||
261 | |||
262 | static int omap_hsmmc_23_set_power(struct device *dev, int slot, int power_on, | ||
263 | int vdd) | ||
264 | { | ||
265 | struct omap_hsmmc_host *host = | ||
266 | platform_get_drvdata(to_platform_device(dev)); | ||
267 | int ret = 0; | ||
268 | |||
269 | /* | ||
270 | * If we don't see a Vcc regulator, assume it's a fixed | ||
271 | * voltage always-on regulator. | ||
272 | */ | ||
273 | if (!host->vcc) | ||
274 | return 0; | ||
275 | |||
276 | if (mmc_slot(host).before_set_reg) | ||
277 | mmc_slot(host).before_set_reg(dev, slot, power_on, vdd); | ||
278 | |||
279 | /* | ||
280 | * Assume Vcc regulator is used only to power the card ... OMAP | ||
281 | * VDDS is used to power the pins, optionally with a transceiver to | ||
282 | * support cards using voltages other than VDDS (1.8V nominal). When a | ||
283 | * transceiver is used, DAT3..7 are muxed as transceiver control pins. | ||
284 | * | ||
285 | * In some cases this regulator won't support enable/disable; | ||
286 | * e.g. it's a fixed rail for a WLAN chip. | ||
287 | * | ||
288 | * In other cases vcc_aux switches interface power. Example, for | ||
289 | * eMMC cards it represents VccQ. Sometimes transceivers or SDIO | ||
290 | * chips/cards need an interface voltage rail too. | ||
291 | */ | ||
292 | if (power_on) { | ||
293 | ret = mmc_regulator_set_ocr(host->vcc, vdd); | ||
294 | /* Enable interface voltage rail, if needed */ | ||
295 | if (ret == 0 && host->vcc_aux) { | ||
296 | ret = regulator_enable(host->vcc_aux); | ||
297 | if (ret < 0) | ||
298 | ret = mmc_regulator_set_ocr(host->vcc, 0); | ||
299 | } | ||
300 | } else { | ||
301 | if (host->vcc_aux) | ||
302 | ret = regulator_disable(host->vcc_aux); | ||
303 | if (ret == 0) | ||
304 | ret = mmc_regulator_set_ocr(host->vcc, 0); | ||
305 | } | ||
306 | |||
307 | if (mmc_slot(host).after_set_reg) | ||
308 | mmc_slot(host).after_set_reg(dev, slot, power_on, vdd); | ||
309 | |||
310 | return ret; | ||
311 | } | ||
312 | |||
313 | static int omap_hsmmc_1_set_sleep(struct device *dev, int slot, int sleep, | ||
314 | int vdd, int cardsleep) | ||
315 | { | ||
316 | struct omap_hsmmc_host *host = | ||
317 | platform_get_drvdata(to_platform_device(dev)); | ||
318 | int mode = sleep ? REGULATOR_MODE_STANDBY : REGULATOR_MODE_NORMAL; | ||
319 | |||
320 | return regulator_set_mode(host->vcc, mode); | ||
321 | } | ||
322 | |||
323 | static int omap_hsmmc_23_set_sleep(struct device *dev, int slot, int sleep, | ||
324 | int vdd, int cardsleep) | ||
325 | { | ||
326 | struct omap_hsmmc_host *host = | ||
327 | platform_get_drvdata(to_platform_device(dev)); | ||
328 | int err, mode; | ||
329 | |||
330 | /* | ||
331 | * If we don't see a Vcc regulator, assume it's a fixed | ||
332 | * voltage always-on regulator. | ||
333 | */ | ||
334 | if (!host->vcc) | ||
335 | return 0; | ||
336 | |||
337 | mode = sleep ? REGULATOR_MODE_STANDBY : REGULATOR_MODE_NORMAL; | ||
338 | |||
339 | if (!host->vcc_aux) | ||
340 | return regulator_set_mode(host->vcc, mode); | ||
341 | |||
342 | if (cardsleep) { | ||
343 | /* VCC can be turned off if card is asleep */ | ||
344 | if (sleep) | ||
345 | err = mmc_regulator_set_ocr(host->vcc, 0); | ||
346 | else | ||
347 | err = mmc_regulator_set_ocr(host->vcc, vdd); | ||
348 | } else | ||
349 | err = regulator_set_mode(host->vcc, mode); | ||
350 | if (err) | ||
351 | return err; | ||
352 | |||
353 | if (!mmc_slot(host).vcc_aux_disable_is_sleep) | ||
354 | return regulator_set_mode(host->vcc_aux, mode); | ||
355 | |||
356 | if (sleep) | ||
357 | return regulator_disable(host->vcc_aux); | ||
358 | else | ||
359 | return regulator_enable(host->vcc_aux); | ||
360 | } | ||
361 | |||
362 | static int omap_hsmmc_reg_get(struct omap_hsmmc_host *host) | ||
363 | { | ||
364 | struct regulator *reg; | ||
365 | int ret = 0; | ||
366 | |||
367 | switch (host->id) { | ||
368 | case OMAP_MMC1_DEVID: | ||
369 | /* On-chip level shifting via PBIAS0/PBIAS1 */ | ||
370 | mmc_slot(host).set_power = omap_hsmmc_1_set_power; | ||
371 | mmc_slot(host).set_sleep = omap_hsmmc_1_set_sleep; | ||
372 | break; | ||
373 | case OMAP_MMC2_DEVID: | ||
374 | case OMAP_MMC3_DEVID: | ||
375 | /* Off-chip level shifting, or none */ | ||
376 | mmc_slot(host).set_power = omap_hsmmc_23_set_power; | ||
377 | mmc_slot(host).set_sleep = omap_hsmmc_23_set_sleep; | ||
378 | break; | ||
379 | default: | ||
380 | pr_err("MMC%d configuration not supported!\n", host->id); | ||
381 | return -EINVAL; | ||
382 | } | ||
383 | |||
384 | reg = regulator_get(host->dev, "vmmc"); | ||
385 | if (IS_ERR(reg)) { | ||
386 | dev_dbg(host->dev, "vmmc regulator missing\n"); | ||
387 | /* | ||
388 | * HACK: until fixed.c regulator is usable, | ||
389 | * we don't require a main regulator | ||
390 | * for MMC2 or MMC3 | ||
391 | */ | ||
392 | if (host->id == OMAP_MMC1_DEVID) { | ||
393 | ret = PTR_ERR(reg); | ||
394 | goto err; | ||
395 | } | ||
396 | } else { | ||
397 | host->vcc = reg; | ||
398 | mmc_slot(host).ocr_mask = mmc_regulator_get_ocrmask(reg); | ||
399 | |||
400 | /* Allow an aux regulator */ | ||
401 | reg = regulator_get(host->dev, "vmmc_aux"); | ||
402 | host->vcc_aux = IS_ERR(reg) ? NULL : reg; | ||
403 | |||
404 | /* | ||
405 | * UGLY HACK: workaround regulator framework bugs. | ||
406 | * When the bootloader leaves a supply active, it's | ||
407 | * initialized with zero usecount ... and we can't | ||
408 | * disable it without first enabling it. Until the | ||
409 | * framework is fixed, we need a workaround like this | ||
410 | * (which is safe for MMC, but not in general). | ||
411 | */ | ||
412 | if (regulator_is_enabled(host->vcc) > 0) { | ||
413 | regulator_enable(host->vcc); | ||
414 | regulator_disable(host->vcc); | ||
415 | } | ||
416 | if (host->vcc_aux) { | ||
417 | if (regulator_is_enabled(reg) > 0) { | ||
418 | regulator_enable(reg); | ||
419 | regulator_disable(reg); | ||
420 | } | ||
421 | } | ||
422 | } | ||
423 | |||
424 | return 0; | ||
425 | |||
426 | err: | ||
427 | mmc_slot(host).set_power = NULL; | ||
428 | mmc_slot(host).set_sleep = NULL; | ||
429 | return ret; | ||
430 | } | ||
431 | |||
432 | static void omap_hsmmc_reg_put(struct omap_hsmmc_host *host) | ||
433 | { | ||
434 | regulator_put(host->vcc); | ||
435 | regulator_put(host->vcc_aux); | ||
436 | mmc_slot(host).set_power = NULL; | ||
437 | mmc_slot(host).set_sleep = NULL; | ||
438 | } | ||
439 | |||
440 | static inline int omap_hsmmc_have_reg(void) | ||
441 | { | ||
442 | return 1; | ||
443 | } | ||
444 | |||
445 | #else | ||
446 | |||
447 | static inline int omap_hsmmc_reg_get(struct omap_hsmmc_host *host) | ||
448 | { | ||
449 | return -EINVAL; | ||
450 | } | ||
451 | |||
452 | static inline void omap_hsmmc_reg_put(struct omap_hsmmc_host *host) | ||
453 | { | ||
454 | } | ||
455 | |||
456 | static inline int omap_hsmmc_have_reg(void) | ||
457 | { | ||
458 | return 0; | ||
459 | } | ||
460 | |||
461 | #endif | ||
462 | |||
463 | static int omap_hsmmc_gpio_init(struct omap_mmc_platform_data *pdata) | ||
464 | { | ||
465 | int ret; | ||
466 | |||
467 | if (gpio_is_valid(pdata->slots[0].switch_pin)) { | ||
468 | pdata->suspend = omap_hsmmc_suspend_cdirq; | ||
469 | pdata->resume = omap_hsmmc_resume_cdirq; | ||
470 | if (pdata->slots[0].cover) | ||
471 | pdata->slots[0].get_cover_state = | ||
472 | omap_hsmmc_get_cover_state; | ||
473 | else | ||
474 | pdata->slots[0].card_detect = omap_hsmmc_card_detect; | ||
475 | pdata->slots[0].card_detect_irq = | ||
476 | gpio_to_irq(pdata->slots[0].switch_pin); | ||
477 | ret = gpio_request(pdata->slots[0].switch_pin, "mmc_cd"); | ||
478 | if (ret) | ||
479 | return ret; | ||
480 | ret = gpio_direction_input(pdata->slots[0].switch_pin); | ||
481 | if (ret) | ||
482 | goto err_free_sp; | ||
483 | } else | ||
484 | pdata->slots[0].switch_pin = -EINVAL; | ||
485 | |||
486 | if (gpio_is_valid(pdata->slots[0].gpio_wp)) { | ||
487 | pdata->slots[0].get_ro = omap_hsmmc_get_wp; | ||
488 | ret = gpio_request(pdata->slots[0].gpio_wp, "mmc_wp"); | ||
489 | if (ret) | ||
490 | goto err_free_cd; | ||
491 | ret = gpio_direction_input(pdata->slots[0].gpio_wp); | ||
492 | if (ret) | ||
493 | goto err_free_wp; | ||
494 | } else | ||
495 | pdata->slots[0].gpio_wp = -EINVAL; | ||
496 | |||
497 | return 0; | ||
498 | |||
499 | err_free_wp: | ||
500 | gpio_free(pdata->slots[0].gpio_wp); | ||
501 | err_free_cd: | ||
502 | if (gpio_is_valid(pdata->slots[0].switch_pin)) | ||
503 | err_free_sp: | ||
504 | gpio_free(pdata->slots[0].switch_pin); | ||
505 | return ret; | ||
506 | } | ||
507 | |||
508 | static void omap_hsmmc_gpio_free(struct omap_mmc_platform_data *pdata) | ||
509 | { | ||
510 | if (gpio_is_valid(pdata->slots[0].gpio_wp)) | ||
511 | gpio_free(pdata->slots[0].gpio_wp); | ||
512 | if (gpio_is_valid(pdata->slots[0].switch_pin)) | ||
513 | gpio_free(pdata->slots[0].switch_pin); | ||
514 | } | ||
515 | |||
178 | /* | 516 | /* |
179 | * Stop clock to the card | 517 | * Stop clock to the card |
180 | */ | 518 | */ |
@@ -835,21 +1173,16 @@ static void omap_hsmmc_detect(struct work_struct *work) | |||
835 | sysfs_notify(&host->mmc->class_dev.kobj, NULL, "cover_switch"); | 1173 | sysfs_notify(&host->mmc->class_dev.kobj, NULL, "cover_switch"); |
836 | 1174 | ||
837 | if (slot->card_detect) | 1175 | if (slot->card_detect) |
838 | carddetect = slot->card_detect(slot->card_detect_irq); | 1176 | carddetect = slot->card_detect(host->dev, host->slot_id); |
839 | else { | 1177 | else { |
840 | omap_hsmmc_protect_card(host); | 1178 | omap_hsmmc_protect_card(host); |
841 | carddetect = -ENOSYS; | 1179 | carddetect = -ENOSYS; |
842 | } | 1180 | } |
843 | 1181 | ||
844 | if (carddetect) { | 1182 | if (carddetect) |
845 | mmc_detect_change(host->mmc, (HZ * 200) / 1000); | 1183 | mmc_detect_change(host->mmc, (HZ * 200) / 1000); |
846 | } else { | 1184 | else |
847 | mmc_host_enable(host->mmc); | ||
848 | omap_hsmmc_reset_controller_fsm(host, SRD); | ||
849 | mmc_host_lazy_disable(host->mmc); | ||
850 | |||
851 | mmc_detect_change(host->mmc, (HZ * 50) / 1000); | 1185 | mmc_detect_change(host->mmc, (HZ * 50) / 1000); |
852 | } | ||
853 | } | 1186 | } |
854 | 1187 | ||
855 | /* | 1188 | /* |
@@ -1242,7 +1575,7 @@ static int omap_hsmmc_get_cd(struct mmc_host *mmc) | |||
1242 | 1575 | ||
1243 | if (!mmc_slot(host).card_detect) | 1576 | if (!mmc_slot(host).card_detect) |
1244 | return -ENOSYS; | 1577 | return -ENOSYS; |
1245 | return mmc_slot(host).card_detect(mmc_slot(host).card_detect_irq); | 1578 | return mmc_slot(host).card_detect(host->dev, host->slot_id); |
1246 | } | 1579 | } |
1247 | 1580 | ||
1248 | static int omap_hsmmc_get_ro(struct mmc_host *mmc) | 1581 | static int omap_hsmmc_get_ro(struct mmc_host *mmc) |
@@ -1311,7 +1644,7 @@ static int omap_hsmmc_enabled_to_disabled(struct omap_hsmmc_host *host) | |||
1311 | if (host->power_mode == MMC_POWER_OFF) | 1644 | if (host->power_mode == MMC_POWER_OFF) |
1312 | return 0; | 1645 | return 0; |
1313 | 1646 | ||
1314 | return msecs_to_jiffies(OMAP_MMC_SLEEP_TIMEOUT); | 1647 | return OMAP_MMC_SLEEP_TIMEOUT; |
1315 | } | 1648 | } |
1316 | 1649 | ||
1317 | /* Handler for [DISABLED -> REGSLEEP / CARDSLEEP] transition */ | 1650 | /* Handler for [DISABLED -> REGSLEEP / CARDSLEEP] transition */ |
@@ -1347,11 +1680,14 @@ static int omap_hsmmc_disabled_to_sleep(struct omap_hsmmc_host *host) | |||
1347 | dev_dbg(mmc_dev(host->mmc), "DISABLED -> %s\n", | 1680 | dev_dbg(mmc_dev(host->mmc), "DISABLED -> %s\n", |
1348 | host->dpm_state == CARDSLEEP ? "CARDSLEEP" : "REGSLEEP"); | 1681 | host->dpm_state == CARDSLEEP ? "CARDSLEEP" : "REGSLEEP"); |
1349 | 1682 | ||
1683 | if (mmc_slot(host).no_off) | ||
1684 | return 0; | ||
1685 | |||
1350 | if ((host->mmc->caps & MMC_CAP_NONREMOVABLE) || | 1686 | if ((host->mmc->caps & MMC_CAP_NONREMOVABLE) || |
1351 | mmc_slot(host).card_detect || | 1687 | mmc_slot(host).card_detect || |
1352 | (mmc_slot(host).get_cover_state && | 1688 | (mmc_slot(host).get_cover_state && |
1353 | mmc_slot(host).get_cover_state(host->dev, host->slot_id))) | 1689 | mmc_slot(host).get_cover_state(host->dev, host->slot_id))) |
1354 | return msecs_to_jiffies(OMAP_MMC_OFF_TIMEOUT); | 1690 | return OMAP_MMC_OFF_TIMEOUT; |
1355 | 1691 | ||
1356 | return 0; | 1692 | return 0; |
1357 | } | 1693 | } |
@@ -1362,6 +1698,9 @@ static int omap_hsmmc_sleep_to_off(struct omap_hsmmc_host *host) | |||
1362 | if (!mmc_try_claim_host(host->mmc)) | 1698 | if (!mmc_try_claim_host(host->mmc)) |
1363 | return 0; | 1699 | return 0; |
1364 | 1700 | ||
1701 | if (mmc_slot(host).no_off) | ||
1702 | return 0; | ||
1703 | |||
1365 | if (!((host->mmc->caps & MMC_CAP_NONREMOVABLE) || | 1704 | if (!((host->mmc->caps & MMC_CAP_NONREMOVABLE) || |
1366 | mmc_slot(host).card_detect || | 1705 | mmc_slot(host).card_detect || |
1367 | (mmc_slot(host).get_cover_state && | 1706 | (mmc_slot(host).get_cover_state && |
@@ -1616,7 +1955,7 @@ static int __init omap_hsmmc_probe(struct platform_device *pdev) | |||
1616 | struct mmc_host *mmc; | 1955 | struct mmc_host *mmc; |
1617 | struct omap_hsmmc_host *host = NULL; | 1956 | struct omap_hsmmc_host *host = NULL; |
1618 | struct resource *res; | 1957 | struct resource *res; |
1619 | int ret = 0, irq; | 1958 | int ret, irq; |
1620 | 1959 | ||
1621 | if (pdata == NULL) { | 1960 | if (pdata == NULL) { |
1622 | dev_err(&pdev->dev, "Platform Data is missing\n"); | 1961 | dev_err(&pdev->dev, "Platform Data is missing\n"); |
@@ -1638,10 +1977,14 @@ static int __init omap_hsmmc_probe(struct platform_device *pdev) | |||
1638 | if (res == NULL) | 1977 | if (res == NULL) |
1639 | return -EBUSY; | 1978 | return -EBUSY; |
1640 | 1979 | ||
1980 | ret = omap_hsmmc_gpio_init(pdata); | ||
1981 | if (ret) | ||
1982 | goto err; | ||
1983 | |||
1641 | mmc = mmc_alloc_host(sizeof(struct omap_hsmmc_host), &pdev->dev); | 1984 | mmc = mmc_alloc_host(sizeof(struct omap_hsmmc_host), &pdev->dev); |
1642 | if (!mmc) { | 1985 | if (!mmc) { |
1643 | ret = -ENOMEM; | 1986 | ret = -ENOMEM; |
1644 | goto err; | 1987 | goto err_alloc; |
1645 | } | 1988 | } |
1646 | 1989 | ||
1647 | host = mmc_priv(mmc); | 1990 | host = mmc_priv(mmc); |
@@ -1656,7 +1999,7 @@ static int __init omap_hsmmc_probe(struct platform_device *pdev) | |||
1656 | host->slot_id = 0; | 1999 | host->slot_id = 0; |
1657 | host->mapbase = res->start; | 2000 | host->mapbase = res->start; |
1658 | host->base = ioremap(host->mapbase, SZ_4K); | 2001 | host->base = ioremap(host->mapbase, SZ_4K); |
1659 | host->power_mode = -1; | 2002 | host->power_mode = MMC_POWER_OFF; |
1660 | 2003 | ||
1661 | platform_set_drvdata(pdev, host); | 2004 | platform_set_drvdata(pdev, host); |
1662 | INIT_WORK(&host->mmc_carddetect_work, omap_hsmmc_detect); | 2005 | INIT_WORK(&host->mmc_carddetect_work, omap_hsmmc_detect); |
@@ -1666,6 +2009,13 @@ static int __init omap_hsmmc_probe(struct platform_device *pdev) | |||
1666 | else | 2009 | else |
1667 | mmc->ops = &omap_hsmmc_ops; | 2010 | mmc->ops = &omap_hsmmc_ops; |
1668 | 2011 | ||
2012 | /* | ||
2013 | * If regulator_disable can only put vcc_aux to sleep then there is | ||
2014 | * no off state. | ||
2015 | */ | ||
2016 | if (mmc_slot(host).vcc_aux_disable_is_sleep) | ||
2017 | mmc_slot(host).no_off = 1; | ||
2018 | |||
1669 | mmc->f_min = 400000; | 2019 | mmc->f_min = 400000; |
1670 | mmc->f_max = 52000000; | 2020 | mmc->f_max = 52000000; |
1671 | 2021 | ||
@@ -1781,7 +2131,6 @@ static int __init omap_hsmmc_probe(struct platform_device *pdev) | |||
1781 | goto err_irq; | 2131 | goto err_irq; |
1782 | } | 2132 | } |
1783 | 2133 | ||
1784 | /* initialize power supplies, gpios, etc */ | ||
1785 | if (pdata->init != NULL) { | 2134 | if (pdata->init != NULL) { |
1786 | if (pdata->init(&pdev->dev) != 0) { | 2135 | if (pdata->init(&pdev->dev) != 0) { |
1787 | dev_dbg(mmc_dev(host->mmc), | 2136 | dev_dbg(mmc_dev(host->mmc), |
@@ -1789,6 +2138,14 @@ static int __init omap_hsmmc_probe(struct platform_device *pdev) | |||
1789 | goto err_irq_cd_init; | 2138 | goto err_irq_cd_init; |
1790 | } | 2139 | } |
1791 | } | 2140 | } |
2141 | |||
2142 | if (omap_hsmmc_have_reg() && !mmc_slot(host).set_power) { | ||
2143 | ret = omap_hsmmc_reg_get(host); | ||
2144 | if (ret) | ||
2145 | goto err_reg; | ||
2146 | host->use_reg = 1; | ||
2147 | } | ||
2148 | |||
1792 | mmc->ocr_avail = mmc_slot(host).ocr_mask; | 2149 | mmc->ocr_avail = mmc_slot(host).ocr_mask; |
1793 | 2150 | ||
1794 | /* Request IRQ for card detect */ | 2151 | /* Request IRQ for card detect */ |
@@ -1823,19 +2180,22 @@ static int __init omap_hsmmc_probe(struct platform_device *pdev) | |||
1823 | ret = device_create_file(&mmc->class_dev, | 2180 | ret = device_create_file(&mmc->class_dev, |
1824 | &dev_attr_cover_switch); | 2181 | &dev_attr_cover_switch); |
1825 | if (ret < 0) | 2182 | if (ret < 0) |
1826 | goto err_cover_switch; | 2183 | goto err_slot_name; |
1827 | } | 2184 | } |
1828 | 2185 | ||
1829 | omap_hsmmc_debugfs(mmc); | 2186 | omap_hsmmc_debugfs(mmc); |
1830 | 2187 | ||
1831 | return 0; | 2188 | return 0; |
1832 | 2189 | ||
1833 | err_cover_switch: | ||
1834 | device_remove_file(&mmc->class_dev, &dev_attr_cover_switch); | ||
1835 | err_slot_name: | 2190 | err_slot_name: |
1836 | mmc_remove_host(mmc); | 2191 | mmc_remove_host(mmc); |
1837 | err_irq_cd: | ||
1838 | free_irq(mmc_slot(host).card_detect_irq, host); | 2192 | free_irq(mmc_slot(host).card_detect_irq, host); |
2193 | err_irq_cd: | ||
2194 | if (host->use_reg) | ||
2195 | omap_hsmmc_reg_put(host); | ||
2196 | err_reg: | ||
2197 | if (host->pdata->cleanup) | ||
2198 | host->pdata->cleanup(&pdev->dev); | ||
1839 | err_irq_cd_init: | 2199 | err_irq_cd_init: |
1840 | free_irq(host->irq, host); | 2200 | free_irq(host->irq, host); |
1841 | err_irq: | 2201 | err_irq: |
@@ -1847,14 +2207,14 @@ err_irq: | |||
1847 | clk_disable(host->dbclk); | 2207 | clk_disable(host->dbclk); |
1848 | clk_put(host->dbclk); | 2208 | clk_put(host->dbclk); |
1849 | } | 2209 | } |
1850 | |||
1851 | err1: | 2210 | err1: |
1852 | iounmap(host->base); | 2211 | iounmap(host->base); |
2212 | platform_set_drvdata(pdev, NULL); | ||
2213 | mmc_free_host(mmc); | ||
2214 | err_alloc: | ||
2215 | omap_hsmmc_gpio_free(pdata); | ||
1853 | err: | 2216 | err: |
1854 | dev_dbg(mmc_dev(host->mmc), "Probe Failed\n"); | ||
1855 | release_mem_region(res->start, res->end - res->start + 1); | 2217 | release_mem_region(res->start, res->end - res->start + 1); |
1856 | if (host) | ||
1857 | mmc_free_host(mmc); | ||
1858 | return ret; | 2218 | return ret; |
1859 | } | 2219 | } |
1860 | 2220 | ||
@@ -1866,6 +2226,8 @@ static int omap_hsmmc_remove(struct platform_device *pdev) | |||
1866 | if (host) { | 2226 | if (host) { |
1867 | mmc_host_enable(host->mmc); | 2227 | mmc_host_enable(host->mmc); |
1868 | mmc_remove_host(host->mmc); | 2228 | mmc_remove_host(host->mmc); |
2229 | if (host->use_reg) | ||
2230 | omap_hsmmc_reg_put(host); | ||
1869 | if (host->pdata->cleanup) | 2231 | if (host->pdata->cleanup) |
1870 | host->pdata->cleanup(&pdev->dev); | 2232 | host->pdata->cleanup(&pdev->dev); |
1871 | free_irq(host->irq, host); | 2233 | free_irq(host->irq, host); |
@@ -1884,6 +2246,7 @@ static int omap_hsmmc_remove(struct platform_device *pdev) | |||
1884 | 2246 | ||
1885 | mmc_free_host(host->mmc); | 2247 | mmc_free_host(host->mmc); |
1886 | iounmap(host->base); | 2248 | iounmap(host->base); |
2249 | omap_hsmmc_gpio_free(pdev->dev.platform_data); | ||
1887 | } | 2250 | } |
1888 | 2251 | ||
1889 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 2252 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
diff --git a/drivers/mmc/host/pxamci.c b/drivers/mmc/host/pxamci.c index 9fb480bb0e0a..0ed48959b590 100644 --- a/drivers/mmc/host/pxamci.c +++ b/drivers/mmc/host/pxamci.c | |||
@@ -29,6 +29,7 @@ | |||
29 | #include <linux/io.h> | 29 | #include <linux/io.h> |
30 | #include <linux/regulator/consumer.h> | 30 | #include <linux/regulator/consumer.h> |
31 | #include <linux/gpio.h> | 31 | #include <linux/gpio.h> |
32 | #include <linux/gfp.h> | ||
32 | 33 | ||
33 | #include <asm/sizes.h> | 34 | #include <asm/sizes.h> |
34 | 35 | ||
@@ -43,6 +44,9 @@ | |||
43 | #define NR_SG 1 | 44 | #define NR_SG 1 |
44 | #define CLKRT_OFF (~0) | 45 | #define CLKRT_OFF (~0) |
45 | 46 | ||
47 | #define mmc_has_26MHz() (cpu_is_pxa300() || cpu_is_pxa310() \ | ||
48 | || cpu_is_pxa935()) | ||
49 | |||
46 | struct pxamci_host { | 50 | struct pxamci_host { |
47 | struct mmc_host *mmc; | 51 | struct mmc_host *mmc; |
48 | spinlock_t lock; | 52 | spinlock_t lock; |
@@ -457,7 +461,7 @@ static void pxamci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) | |||
457 | clk_enable(host->clk); | 461 | clk_enable(host->clk); |
458 | 462 | ||
459 | if (ios->clock == 26000000) { | 463 | if (ios->clock == 26000000) { |
460 | /* to support 26MHz on pxa300/pxa310 */ | 464 | /* to support 26MHz */ |
461 | host->clkrt = 7; | 465 | host->clkrt = 7; |
462 | } else { | 466 | } else { |
463 | /* to handle (19.5MHz, 26MHz) */ | 467 | /* to handle (19.5MHz, 26MHz) */ |
@@ -608,8 +612,7 @@ static int pxamci_probe(struct platform_device *pdev) | |||
608 | * Calculate minimum clock rate, rounding up. | 612 | * Calculate minimum clock rate, rounding up. |
609 | */ | 613 | */ |
610 | mmc->f_min = (host->clkrate + 63) / 64; | 614 | mmc->f_min = (host->clkrate + 63) / 64; |
611 | mmc->f_max = (cpu_is_pxa300() || cpu_is_pxa310()) ? 26000000 | 615 | mmc->f_max = (mmc_has_26MHz()) ? 26000000 : host->clkrate; |
612 | : host->clkrate; | ||
613 | 616 | ||
614 | pxamci_init_ocr(host); | 617 | pxamci_init_ocr(host); |
615 | 618 | ||
@@ -618,7 +621,7 @@ static int pxamci_probe(struct platform_device *pdev) | |||
618 | if (!cpu_is_pxa25x()) { | 621 | if (!cpu_is_pxa25x()) { |
619 | mmc->caps |= MMC_CAP_4_BIT_DATA | MMC_CAP_SDIO_IRQ; | 622 | mmc->caps |= MMC_CAP_4_BIT_DATA | MMC_CAP_SDIO_IRQ; |
620 | host->cmdat |= CMDAT_SDIO_INT_EN; | 623 | host->cmdat |= CMDAT_SDIO_INT_EN; |
621 | if (cpu_is_pxa300() || cpu_is_pxa310()) | 624 | if (mmc_has_26MHz()) |
622 | mmc->caps |= MMC_CAP_MMC_HIGHSPEED | | 625 | mmc->caps |= MMC_CAP_MMC_HIGHSPEED | |
623 | MMC_CAP_SD_HIGHSPEED; | 626 | MMC_CAP_SD_HIGHSPEED; |
624 | } | 627 | } |
@@ -826,7 +829,7 @@ static int pxamci_resume(struct device *dev) | |||
826 | return ret; | 829 | return ret; |
827 | } | 830 | } |
828 | 831 | ||
829 | static struct dev_pm_ops pxamci_pm_ops = { | 832 | static const struct dev_pm_ops pxamci_pm_ops = { |
830 | .suspend = pxamci_suspend, | 833 | .suspend = pxamci_suspend, |
831 | .resume = pxamci_resume, | 834 | .resume = pxamci_resume, |
832 | }; | 835 | }; |
diff --git a/drivers/mmc/host/ricoh_mmc.c b/drivers/mmc/host/ricoh_mmc.c deleted file mode 100644 index f62790513322..000000000000 --- a/drivers/mmc/host/ricoh_mmc.c +++ /dev/null | |||
@@ -1,262 +0,0 @@ | |||
1 | /* | ||
2 | * ricoh_mmc.c - Dummy driver to disable the Rioch MMC controller. | ||
3 | * | ||
4 | * Copyright (C) 2007 Philip Langdale, All Rights Reserved. | ||
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 as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or (at | ||
9 | * your option) any later version. | ||
10 | */ | ||
11 | |||
12 | /* | ||
13 | * This is a conceptually ridiculous driver, but it is required by the way | ||
14 | * the Ricoh multi-function chips (R5CXXX) work. These chips implement | ||
15 | * the four main memory card controllers (SD, MMC, MS, xD) and one or both | ||
16 | * of cardbus or firewire. It happens that they implement SD and MMC | ||
17 | * support as separate controllers (and PCI functions). The linux SDHCI | ||
18 | * driver supports MMC cards but the chip detects MMC cards in hardware | ||
19 | * and directs them to the MMC controller - so the SDHCI driver never sees | ||
20 | * them. To get around this, we must disable the useless MMC controller. | ||
21 | * At that point, the SDHCI controller will start seeing them. As a bonus, | ||
22 | * a detection event occurs immediately, even if the MMC card is already | ||
23 | * in the reader. | ||
24 | * | ||
25 | * It seems to be the case that the relevant PCI registers to deactivate the | ||
26 | * MMC controller live on PCI function 0, which might be the cardbus controller | ||
27 | * or the firewire controller, depending on the particular chip in question. As | ||
28 | * such, it makes what this driver has to do unavoidably ugly. Such is life. | ||
29 | */ | ||
30 | |||
31 | #include <linux/pci.h> | ||
32 | |||
33 | #define DRIVER_NAME "ricoh-mmc" | ||
34 | |||
35 | static const struct pci_device_id pci_ids[] __devinitdata = { | ||
36 | { | ||
37 | .vendor = PCI_VENDOR_ID_RICOH, | ||
38 | .device = PCI_DEVICE_ID_RICOH_R5C843, | ||
39 | .subvendor = PCI_ANY_ID, | ||
40 | .subdevice = PCI_ANY_ID, | ||
41 | }, | ||
42 | { /* end: all zeroes */ }, | ||
43 | }; | ||
44 | |||
45 | MODULE_DEVICE_TABLE(pci, pci_ids); | ||
46 | |||
47 | static int ricoh_mmc_disable(struct pci_dev *fw_dev) | ||
48 | { | ||
49 | u8 write_enable; | ||
50 | u8 write_target; | ||
51 | u8 disable; | ||
52 | |||
53 | if (fw_dev->device == PCI_DEVICE_ID_RICOH_RL5C476) { | ||
54 | /* via RL5C476 */ | ||
55 | |||
56 | pci_read_config_byte(fw_dev, 0xB7, &disable); | ||
57 | if (disable & 0x02) { | ||
58 | printk(KERN_INFO DRIVER_NAME | ||
59 | ": Controller already disabled. " \ | ||
60 | "Nothing to do.\n"); | ||
61 | return -ENODEV; | ||
62 | } | ||
63 | |||
64 | pci_read_config_byte(fw_dev, 0x8E, &write_enable); | ||
65 | pci_write_config_byte(fw_dev, 0x8E, 0xAA); | ||
66 | pci_read_config_byte(fw_dev, 0x8D, &write_target); | ||
67 | pci_write_config_byte(fw_dev, 0x8D, 0xB7); | ||
68 | pci_write_config_byte(fw_dev, 0xB7, disable | 0x02); | ||
69 | pci_write_config_byte(fw_dev, 0x8E, write_enable); | ||
70 | pci_write_config_byte(fw_dev, 0x8D, write_target); | ||
71 | } else { | ||
72 | /* via R5C832 */ | ||
73 | |||
74 | pci_read_config_byte(fw_dev, 0xCB, &disable); | ||
75 | if (disable & 0x02) { | ||
76 | printk(KERN_INFO DRIVER_NAME | ||
77 | ": Controller already disabled. " \ | ||
78 | "Nothing to do.\n"); | ||
79 | return -ENODEV; | ||
80 | } | ||
81 | |||
82 | pci_read_config_byte(fw_dev, 0xCA, &write_enable); | ||
83 | pci_write_config_byte(fw_dev, 0xCA, 0x57); | ||
84 | pci_write_config_byte(fw_dev, 0xCB, disable | 0x02); | ||
85 | pci_write_config_byte(fw_dev, 0xCA, write_enable); | ||
86 | } | ||
87 | |||
88 | printk(KERN_INFO DRIVER_NAME | ||
89 | ": Controller is now disabled.\n"); | ||
90 | |||
91 | return 0; | ||
92 | } | ||
93 | |||
94 | static int ricoh_mmc_enable(struct pci_dev *fw_dev) | ||
95 | { | ||
96 | u8 write_enable; | ||
97 | u8 write_target; | ||
98 | u8 disable; | ||
99 | |||
100 | if (fw_dev->device == PCI_DEVICE_ID_RICOH_RL5C476) { | ||
101 | /* via RL5C476 */ | ||
102 | |||
103 | pci_read_config_byte(fw_dev, 0x8E, &write_enable); | ||
104 | pci_write_config_byte(fw_dev, 0x8E, 0xAA); | ||
105 | pci_read_config_byte(fw_dev, 0x8D, &write_target); | ||
106 | pci_write_config_byte(fw_dev, 0x8D, 0xB7); | ||
107 | pci_read_config_byte(fw_dev, 0xB7, &disable); | ||
108 | pci_write_config_byte(fw_dev, 0xB7, disable & ~0x02); | ||
109 | pci_write_config_byte(fw_dev, 0x8E, write_enable); | ||
110 | pci_write_config_byte(fw_dev, 0x8D, write_target); | ||
111 | } else { | ||
112 | /* via R5C832 */ | ||
113 | |||
114 | pci_read_config_byte(fw_dev, 0xCA, &write_enable); | ||
115 | pci_read_config_byte(fw_dev, 0xCB, &disable); | ||
116 | pci_write_config_byte(fw_dev, 0xCA, 0x57); | ||
117 | pci_write_config_byte(fw_dev, 0xCB, disable & ~0x02); | ||
118 | pci_write_config_byte(fw_dev, 0xCA, write_enable); | ||
119 | } | ||
120 | |||
121 | printk(KERN_INFO DRIVER_NAME | ||
122 | ": Controller is now re-enabled.\n"); | ||
123 | |||
124 | return 0; | ||
125 | } | ||
126 | |||
127 | static int __devinit ricoh_mmc_probe(struct pci_dev *pdev, | ||
128 | const struct pci_device_id *ent) | ||
129 | { | ||
130 | u8 rev; | ||
131 | u8 ctrlfound = 0; | ||
132 | |||
133 | struct pci_dev *fw_dev = NULL; | ||
134 | |||
135 | BUG_ON(pdev == NULL); | ||
136 | BUG_ON(ent == NULL); | ||
137 | |||
138 | pci_read_config_byte(pdev, PCI_CLASS_REVISION, &rev); | ||
139 | |||
140 | printk(KERN_INFO DRIVER_NAME | ||
141 | ": Ricoh MMC controller found at %s [%04x:%04x] (rev %x)\n", | ||
142 | pci_name(pdev), (int)pdev->vendor, (int)pdev->device, | ||
143 | (int)rev); | ||
144 | |||
145 | while ((fw_dev = | ||
146 | pci_get_device(PCI_VENDOR_ID_RICOH, | ||
147 | PCI_DEVICE_ID_RICOH_RL5C476, fw_dev))) { | ||
148 | if (PCI_SLOT(pdev->devfn) == PCI_SLOT(fw_dev->devfn) && | ||
149 | PCI_FUNC(fw_dev->devfn) == 0 && | ||
150 | pdev->bus == fw_dev->bus) { | ||
151 | if (ricoh_mmc_disable(fw_dev) != 0) | ||
152 | return -ENODEV; | ||
153 | |||
154 | pci_set_drvdata(pdev, fw_dev); | ||
155 | |||
156 | ++ctrlfound; | ||
157 | break; | ||
158 | } | ||
159 | } | ||
160 | |||
161 | fw_dev = NULL; | ||
162 | |||
163 | while (!ctrlfound && | ||
164 | (fw_dev = pci_get_device(PCI_VENDOR_ID_RICOH, | ||
165 | PCI_DEVICE_ID_RICOH_R5C832, fw_dev))) { | ||
166 | if (PCI_SLOT(pdev->devfn) == PCI_SLOT(fw_dev->devfn) && | ||
167 | PCI_FUNC(fw_dev->devfn) == 0 && | ||
168 | pdev->bus == fw_dev->bus) { | ||
169 | if (ricoh_mmc_disable(fw_dev) != 0) | ||
170 | return -ENODEV; | ||
171 | |||
172 | pci_set_drvdata(pdev, fw_dev); | ||
173 | |||
174 | ++ctrlfound; | ||
175 | } | ||
176 | } | ||
177 | |||
178 | if (!ctrlfound) { | ||
179 | printk(KERN_WARNING DRIVER_NAME | ||
180 | ": Main Ricoh function not found. Cannot disable controller.\n"); | ||
181 | return -ENODEV; | ||
182 | } | ||
183 | |||
184 | return 0; | ||
185 | } | ||
186 | |||
187 | static void __devexit ricoh_mmc_remove(struct pci_dev *pdev) | ||
188 | { | ||
189 | struct pci_dev *fw_dev = NULL; | ||
190 | |||
191 | fw_dev = pci_get_drvdata(pdev); | ||
192 | BUG_ON(fw_dev == NULL); | ||
193 | |||
194 | ricoh_mmc_enable(fw_dev); | ||
195 | |||
196 | pci_set_drvdata(pdev, NULL); | ||
197 | } | ||
198 | |||
199 | static int ricoh_mmc_suspend_late(struct pci_dev *pdev, pm_message_t state) | ||
200 | { | ||
201 | struct pci_dev *fw_dev = NULL; | ||
202 | |||
203 | fw_dev = pci_get_drvdata(pdev); | ||
204 | BUG_ON(fw_dev == NULL); | ||
205 | |||
206 | printk(KERN_INFO DRIVER_NAME ": Suspending.\n"); | ||
207 | |||
208 | ricoh_mmc_enable(fw_dev); | ||
209 | |||
210 | return 0; | ||
211 | } | ||
212 | |||
213 | static int ricoh_mmc_resume_early(struct pci_dev *pdev) | ||
214 | { | ||
215 | struct pci_dev *fw_dev = NULL; | ||
216 | |||
217 | fw_dev = pci_get_drvdata(pdev); | ||
218 | BUG_ON(fw_dev == NULL); | ||
219 | |||
220 | printk(KERN_INFO DRIVER_NAME ": Resuming.\n"); | ||
221 | |||
222 | ricoh_mmc_disable(fw_dev); | ||
223 | |||
224 | return 0; | ||
225 | } | ||
226 | |||
227 | static struct pci_driver ricoh_mmc_driver = { | ||
228 | .name = DRIVER_NAME, | ||
229 | .id_table = pci_ids, | ||
230 | .probe = ricoh_mmc_probe, | ||
231 | .remove = __devexit_p(ricoh_mmc_remove), | ||
232 | .suspend_late = ricoh_mmc_suspend_late, | ||
233 | .resume_early = ricoh_mmc_resume_early, | ||
234 | }; | ||
235 | |||
236 | /*****************************************************************************\ | ||
237 | * * | ||
238 | * Driver init/exit * | ||
239 | * * | ||
240 | \*****************************************************************************/ | ||
241 | |||
242 | static int __init ricoh_mmc_drv_init(void) | ||
243 | { | ||
244 | printk(KERN_INFO DRIVER_NAME | ||
245 | ": Ricoh MMC Controller disabling driver\n"); | ||
246 | printk(KERN_INFO DRIVER_NAME ": Copyright(c) Philip Langdale\n"); | ||
247 | |||
248 | return pci_register_driver(&ricoh_mmc_driver); | ||
249 | } | ||
250 | |||
251 | static void __exit ricoh_mmc_drv_exit(void) | ||
252 | { | ||
253 | pci_unregister_driver(&ricoh_mmc_driver); | ||
254 | } | ||
255 | |||
256 | module_init(ricoh_mmc_drv_init); | ||
257 | module_exit(ricoh_mmc_drv_exit); | ||
258 | |||
259 | MODULE_AUTHOR("Philip Langdale <philipl@alumni.utexas.net>"); | ||
260 | MODULE_DESCRIPTION("Ricoh MMC Controller disabling driver"); | ||
261 | MODULE_LICENSE("GPL"); | ||
262 | |||
diff --git a/drivers/mmc/host/s3cmci.c b/drivers/mmc/host/s3cmci.c index 99b74a351020..2fdf7689ae6c 100644 --- a/drivers/mmc/host/s3cmci.c +++ b/drivers/mmc/host/s3cmci.c | |||
@@ -820,7 +820,7 @@ fail_request: | |||
820 | static void finalize_request(struct s3cmci_host *host) | 820 | static void finalize_request(struct s3cmci_host *host) |
821 | { | 821 | { |
822 | struct mmc_request *mrq = host->mrq; | 822 | struct mmc_request *mrq = host->mrq; |
823 | struct mmc_command *cmd = host->cmd_is_stop ? mrq->stop : mrq->cmd; | 823 | struct mmc_command *cmd; |
824 | int debug_as_failure = 0; | 824 | int debug_as_failure = 0; |
825 | 825 | ||
826 | if (host->complete_what != COMPLETION_FINALIZE) | 826 | if (host->complete_what != COMPLETION_FINALIZE) |
@@ -828,6 +828,7 @@ static void finalize_request(struct s3cmci_host *host) | |||
828 | 828 | ||
829 | if (!mrq) | 829 | if (!mrq) |
830 | return; | 830 | return; |
831 | cmd = host->cmd_is_stop ? mrq->stop : mrq->cmd; | ||
831 | 832 | ||
832 | if (cmd->data && (cmd->error == 0) && | 833 | if (cmd->data && (cmd->error == 0) && |
833 | (cmd->data->error == 0)) { | 834 | (cmd->data->error == 0)) { |
@@ -1178,7 +1179,7 @@ static int s3cmci_card_present(struct mmc_host *mmc) | |||
1178 | struct s3c24xx_mci_pdata *pdata = host->pdata; | 1179 | struct s3c24xx_mci_pdata *pdata = host->pdata; |
1179 | int ret; | 1180 | int ret; |
1180 | 1181 | ||
1181 | if (pdata->gpio_detect == 0) | 1182 | if (pdata->no_detect) |
1182 | return -ENOSYS; | 1183 | return -ENOSYS; |
1183 | 1184 | ||
1184 | ret = gpio_get_value(pdata->gpio_detect) ? 0 : 1; | 1185 | ret = gpio_get_value(pdata->gpio_detect) ? 0 : 1; |
@@ -1302,10 +1303,8 @@ static int s3cmci_get_ro(struct mmc_host *mmc) | |||
1302 | if (pdata->no_wprotect) | 1303 | if (pdata->no_wprotect) |
1303 | return 0; | 1304 | return 0; |
1304 | 1305 | ||
1305 | ret = s3c2410_gpio_getpin(pdata->gpio_wprotect); | 1306 | ret = gpio_get_value(pdata->gpio_wprotect) ? 1 : 0; |
1306 | 1307 | ret ^= pdata->wprotect_invert; | |
1307 | if (pdata->wprotect_invert) | ||
1308 | ret = !ret; | ||
1309 | 1308 | ||
1310 | return ret; | 1309 | return ret; |
1311 | } | 1310 | } |
@@ -1360,7 +1359,9 @@ static struct mmc_host_ops s3cmci_ops = { | |||
1360 | 1359 | ||
1361 | static struct s3c24xx_mci_pdata s3cmci_def_pdata = { | 1360 | static struct s3c24xx_mci_pdata s3cmci_def_pdata = { |
1362 | /* This is currently here to avoid a number of if (host->pdata) | 1361 | /* This is currently here to avoid a number of if (host->pdata) |
1363 | * checks. Any zero fields to ensure reaonable defaults are picked. */ | 1362 | * checks. Any zero fields to ensure reasonable defaults are picked. */ |
1363 | .no_wprotect = 1, | ||
1364 | .no_detect = 1, | ||
1364 | }; | 1365 | }; |
1365 | 1366 | ||
1366 | #ifdef CONFIG_CPU_FREQ | 1367 | #ifdef CONFIG_CPU_FREQ |
@@ -1654,7 +1655,7 @@ static int __devinit s3cmci_probe(struct platform_device *pdev) | |||
1654 | goto probe_free_irq; | 1655 | goto probe_free_irq; |
1655 | } | 1656 | } |
1656 | 1657 | ||
1657 | host->irq_cd = s3c2410_gpio_getirq(host->pdata->gpio_detect); | 1658 | host->irq_cd = gpio_to_irq(host->pdata->gpio_detect); |
1658 | 1659 | ||
1659 | if (host->irq_cd >= 0) { | 1660 | if (host->irq_cd >= 0) { |
1660 | if (request_irq(host->irq_cd, s3cmci_irq_cd, | 1661 | if (request_irq(host->irq_cd, s3cmci_irq_cd, |
@@ -1892,7 +1893,7 @@ static int s3cmci_resume(struct device *dev) | |||
1892 | return mmc_resume_host(mmc); | 1893 | return mmc_resume_host(mmc); |
1893 | } | 1894 | } |
1894 | 1895 | ||
1895 | static struct dev_pm_ops s3cmci_pm = { | 1896 | static const struct dev_pm_ops s3cmci_pm = { |
1896 | .suspend = s3cmci_suspend, | 1897 | .suspend = s3cmci_suspend, |
1897 | .resume = s3cmci_resume, | 1898 | .resume = s3cmci_resume, |
1898 | }; | 1899 | }; |
diff --git a/drivers/mmc/host/sdhci-of.c b/drivers/mmc/host/sdhci-of-core.c index 01ab916c2802..55e33135edb4 100644 --- a/drivers/mmc/host/sdhci-of.c +++ b/drivers/mmc/host/sdhci-of-core.c | |||
@@ -22,62 +22,37 @@ | |||
22 | #include <linux/of_platform.h> | 22 | #include <linux/of_platform.h> |
23 | #include <linux/mmc/host.h> | 23 | #include <linux/mmc/host.h> |
24 | #include <asm/machdep.h> | 24 | #include <asm/machdep.h> |
25 | #include "sdhci-of.h" | ||
25 | #include "sdhci.h" | 26 | #include "sdhci.h" |
26 | 27 | ||
27 | struct sdhci_of_data { | 28 | #ifdef CONFIG_MMC_SDHCI_BIG_ENDIAN_32BIT_BYTE_SWAPPER |
28 | unsigned int quirks; | ||
29 | struct sdhci_ops ops; | ||
30 | }; | ||
31 | |||
32 | struct sdhci_of_host { | ||
33 | unsigned int clock; | ||
34 | u16 xfer_mode_shadow; | ||
35 | }; | ||
36 | 29 | ||
37 | /* | 30 | /* |
38 | * Ops and quirks for the Freescale eSDHC controller. | 31 | * These accessors are designed for big endian hosts doing I/O to |
32 | * little endian controllers incorporating a 32-bit hardware byte swapper. | ||
39 | */ | 33 | */ |
40 | 34 | ||
41 | #define ESDHC_DMA_SYSCTL 0x40c | 35 | u32 sdhci_be32bs_readl(struct sdhci_host *host, int reg) |
42 | #define ESDHC_DMA_SNOOP 0x00000040 | ||
43 | |||
44 | #define ESDHC_SYSTEM_CONTROL 0x2c | ||
45 | #define ESDHC_CLOCK_MASK 0x0000fff0 | ||
46 | #define ESDHC_PREDIV_SHIFT 8 | ||
47 | #define ESDHC_DIVIDER_SHIFT 4 | ||
48 | #define ESDHC_CLOCK_PEREN 0x00000004 | ||
49 | #define ESDHC_CLOCK_HCKEN 0x00000002 | ||
50 | #define ESDHC_CLOCK_IPGEN 0x00000001 | ||
51 | |||
52 | #define ESDHC_HOST_CONTROL_RES 0x05 | ||
53 | |||
54 | static u32 esdhc_readl(struct sdhci_host *host, int reg) | ||
55 | { | 36 | { |
56 | return in_be32(host->ioaddr + reg); | 37 | return in_be32(host->ioaddr + reg); |
57 | } | 38 | } |
58 | 39 | ||
59 | static u16 esdhc_readw(struct sdhci_host *host, int reg) | 40 | u16 sdhci_be32bs_readw(struct sdhci_host *host, int reg) |
60 | { | 41 | { |
61 | u16 ret; | 42 | return in_be16(host->ioaddr + (reg ^ 0x2)); |
62 | |||
63 | if (unlikely(reg == SDHCI_HOST_VERSION)) | ||
64 | ret = in_be16(host->ioaddr + reg); | ||
65 | else | ||
66 | ret = in_be16(host->ioaddr + (reg ^ 0x2)); | ||
67 | return ret; | ||
68 | } | 43 | } |
69 | 44 | ||
70 | static u8 esdhc_readb(struct sdhci_host *host, int reg) | 45 | u8 sdhci_be32bs_readb(struct sdhci_host *host, int reg) |
71 | { | 46 | { |
72 | return in_8(host->ioaddr + (reg ^ 0x3)); | 47 | return in_8(host->ioaddr + (reg ^ 0x3)); |
73 | } | 48 | } |
74 | 49 | ||
75 | static void esdhc_writel(struct sdhci_host *host, u32 val, int reg) | 50 | void sdhci_be32bs_writel(struct sdhci_host *host, u32 val, int reg) |
76 | { | 51 | { |
77 | out_be32(host->ioaddr + reg, val); | 52 | out_be32(host->ioaddr + reg, val); |
78 | } | 53 | } |
79 | 54 | ||
80 | static void esdhc_writew(struct sdhci_host *host, u16 val, int reg) | 55 | void sdhci_be32bs_writew(struct sdhci_host *host, u16 val, int reg) |
81 | { | 56 | { |
82 | struct sdhci_of_host *of_host = sdhci_priv(host); | 57 | struct sdhci_of_host *of_host = sdhci_priv(host); |
83 | int base = reg & ~0x3; | 58 | int base = reg & ~0x3; |
@@ -92,106 +67,21 @@ static void esdhc_writew(struct sdhci_host *host, u16 val, int reg) | |||
92 | of_host->xfer_mode_shadow = val; | 67 | of_host->xfer_mode_shadow = val; |
93 | return; | 68 | return; |
94 | case SDHCI_COMMAND: | 69 | case SDHCI_COMMAND: |
95 | esdhc_writel(host, val << 16 | of_host->xfer_mode_shadow, | 70 | sdhci_be32bs_writel(host, val << 16 | of_host->xfer_mode_shadow, |
96 | SDHCI_TRANSFER_MODE); | 71 | SDHCI_TRANSFER_MODE); |
97 | return; | 72 | return; |
98 | case SDHCI_BLOCK_SIZE: | ||
99 | /* | ||
100 | * Two last DMA bits are reserved, and first one is used for | ||
101 | * non-standard blksz of 4096 bytes that we don't support | ||
102 | * yet. So clear the DMA boundary bits. | ||
103 | */ | ||
104 | val &= ~SDHCI_MAKE_BLKSZ(0x7, 0); | ||
105 | /* fall through */ | ||
106 | } | 73 | } |
107 | clrsetbits_be32(host->ioaddr + base, 0xffff << shift, val << shift); | 74 | clrsetbits_be32(host->ioaddr + base, 0xffff << shift, val << shift); |
108 | } | 75 | } |
109 | 76 | ||
110 | static void esdhc_writeb(struct sdhci_host *host, u8 val, int reg) | 77 | void sdhci_be32bs_writeb(struct sdhci_host *host, u8 val, int reg) |
111 | { | 78 | { |
112 | int base = reg & ~0x3; | 79 | int base = reg & ~0x3; |
113 | int shift = (reg & 0x3) * 8; | 80 | int shift = (reg & 0x3) * 8; |
114 | 81 | ||
115 | /* Prevent SDHCI core from writing reserved bits (e.g. HISPD). */ | ||
116 | if (reg == SDHCI_HOST_CONTROL) | ||
117 | val &= ~ESDHC_HOST_CONTROL_RES; | ||
118 | |||
119 | clrsetbits_be32(host->ioaddr + base , 0xff << shift, val << shift); | 82 | clrsetbits_be32(host->ioaddr + base , 0xff << shift, val << shift); |
120 | } | 83 | } |
121 | 84 | #endif /* CONFIG_MMC_SDHCI_BIG_ENDIAN_32BIT_BYTE_SWAPPER */ | |
122 | static void esdhc_set_clock(struct sdhci_host *host, unsigned int clock) | ||
123 | { | ||
124 | int pre_div = 2; | ||
125 | int div = 1; | ||
126 | |||
127 | clrbits32(host->ioaddr + ESDHC_SYSTEM_CONTROL, ESDHC_CLOCK_IPGEN | | ||
128 | ESDHC_CLOCK_HCKEN | ESDHC_CLOCK_PEREN | ESDHC_CLOCK_MASK); | ||
129 | |||
130 | if (clock == 0) | ||
131 | goto out; | ||
132 | |||
133 | while (host->max_clk / pre_div / 16 > clock && pre_div < 256) | ||
134 | pre_div *= 2; | ||
135 | |||
136 | while (host->max_clk / pre_div / div > clock && div < 16) | ||
137 | div++; | ||
138 | |||
139 | dev_dbg(mmc_dev(host->mmc), "desired SD clock: %d, actual: %d\n", | ||
140 | clock, host->max_clk / pre_div / div); | ||
141 | |||
142 | pre_div >>= 1; | ||
143 | div--; | ||
144 | |||
145 | setbits32(host->ioaddr + ESDHC_SYSTEM_CONTROL, ESDHC_CLOCK_IPGEN | | ||
146 | ESDHC_CLOCK_HCKEN | ESDHC_CLOCK_PEREN | | ||
147 | div << ESDHC_DIVIDER_SHIFT | pre_div << ESDHC_PREDIV_SHIFT); | ||
148 | mdelay(100); | ||
149 | out: | ||
150 | host->clock = clock; | ||
151 | } | ||
152 | |||
153 | static int esdhc_enable_dma(struct sdhci_host *host) | ||
154 | { | ||
155 | setbits32(host->ioaddr + ESDHC_DMA_SYSCTL, ESDHC_DMA_SNOOP); | ||
156 | return 0; | ||
157 | } | ||
158 | |||
159 | static unsigned int esdhc_get_max_clock(struct sdhci_host *host) | ||
160 | { | ||
161 | struct sdhci_of_host *of_host = sdhci_priv(host); | ||
162 | |||
163 | return of_host->clock; | ||
164 | } | ||
165 | |||
166 | static unsigned int esdhc_get_min_clock(struct sdhci_host *host) | ||
167 | { | ||
168 | struct sdhci_of_host *of_host = sdhci_priv(host); | ||
169 | |||
170 | return of_host->clock / 256 / 16; | ||
171 | } | ||
172 | |||
173 | static struct sdhci_of_data sdhci_esdhc = { | ||
174 | .quirks = SDHCI_QUIRK_FORCE_BLK_SZ_2048 | | ||
175 | SDHCI_QUIRK_BROKEN_CARD_DETECTION | | ||
176 | SDHCI_QUIRK_NO_BUSY_IRQ | | ||
177 | SDHCI_QUIRK_NONSTANDARD_CLOCK | | ||
178 | SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK | | ||
179 | SDHCI_QUIRK_PIO_NEEDS_DELAY | | ||
180 | SDHCI_QUIRK_RESTORE_IRQS_AFTER_RESET | | ||
181 | SDHCI_QUIRK_NO_CARD_NO_RESET, | ||
182 | .ops = { | ||
183 | .readl = esdhc_readl, | ||
184 | .readw = esdhc_readw, | ||
185 | .readb = esdhc_readb, | ||
186 | .writel = esdhc_writel, | ||
187 | .writew = esdhc_writew, | ||
188 | .writeb = esdhc_writeb, | ||
189 | .set_clock = esdhc_set_clock, | ||
190 | .enable_dma = esdhc_enable_dma, | ||
191 | .get_max_clock = esdhc_get_max_clock, | ||
192 | .get_min_clock = esdhc_get_min_clock, | ||
193 | }, | ||
194 | }; | ||
195 | 85 | ||
196 | #ifdef CONFIG_PM | 86 | #ifdef CONFIG_PM |
197 | 87 | ||
@@ -301,9 +191,14 @@ static int __devexit sdhci_of_remove(struct of_device *ofdev) | |||
301 | } | 191 | } |
302 | 192 | ||
303 | static const struct of_device_id sdhci_of_match[] = { | 193 | static const struct of_device_id sdhci_of_match[] = { |
194 | #ifdef CONFIG_MMC_SDHCI_OF_ESDHC | ||
304 | { .compatible = "fsl,mpc8379-esdhc", .data = &sdhci_esdhc, }, | 195 | { .compatible = "fsl,mpc8379-esdhc", .data = &sdhci_esdhc, }, |
305 | { .compatible = "fsl,mpc8536-esdhc", .data = &sdhci_esdhc, }, | 196 | { .compatible = "fsl,mpc8536-esdhc", .data = &sdhci_esdhc, }, |
306 | { .compatible = "fsl,esdhc", .data = &sdhci_esdhc, }, | 197 | { .compatible = "fsl,esdhc", .data = &sdhci_esdhc, }, |
198 | #endif | ||
199 | #ifdef CONFIG_MMC_SDHCI_OF_HLWD | ||
200 | { .compatible = "nintendo,hollywood-sdhci", .data = &sdhci_hlwd, }, | ||
201 | #endif | ||
307 | { .compatible = "generic-sdhci", }, | 202 | { .compatible = "generic-sdhci", }, |
308 | {}, | 203 | {}, |
309 | }; | 204 | }; |
diff --git a/drivers/mmc/host/sdhci-of-esdhc.c b/drivers/mmc/host/sdhci-of-esdhc.c new file mode 100644 index 000000000000..d5b11a17e648 --- /dev/null +++ b/drivers/mmc/host/sdhci-of-esdhc.c | |||
@@ -0,0 +1,143 @@ | |||
1 | /* | ||
2 | * Freescale eSDHC controller driver. | ||
3 | * | ||
4 | * Copyright (c) 2007 Freescale Semiconductor, Inc. | ||
5 | * Copyright (c) 2009 MontaVista Software, Inc. | ||
6 | * | ||
7 | * Authors: Xiaobo Xie <X.Xie@freescale.com> | ||
8 | * Anton Vorontsov <avorontsov@ru.mvista.com> | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of the GNU General Public License as published by | ||
12 | * the Free Software Foundation; either version 2 of the License, or (at | ||
13 | * your option) any later version. | ||
14 | */ | ||
15 | |||
16 | #include <linux/io.h> | ||
17 | #include <linux/delay.h> | ||
18 | #include <linux/mmc/host.h> | ||
19 | #include "sdhci-of.h" | ||
20 | #include "sdhci.h" | ||
21 | |||
22 | /* | ||
23 | * Ops and quirks for the Freescale eSDHC controller. | ||
24 | */ | ||
25 | |||
26 | #define ESDHC_DMA_SYSCTL 0x40c | ||
27 | #define ESDHC_DMA_SNOOP 0x00000040 | ||
28 | |||
29 | #define ESDHC_SYSTEM_CONTROL 0x2c | ||
30 | #define ESDHC_CLOCK_MASK 0x0000fff0 | ||
31 | #define ESDHC_PREDIV_SHIFT 8 | ||
32 | #define ESDHC_DIVIDER_SHIFT 4 | ||
33 | #define ESDHC_CLOCK_PEREN 0x00000004 | ||
34 | #define ESDHC_CLOCK_HCKEN 0x00000002 | ||
35 | #define ESDHC_CLOCK_IPGEN 0x00000001 | ||
36 | |||
37 | #define ESDHC_HOST_CONTROL_RES 0x05 | ||
38 | |||
39 | static u16 esdhc_readw(struct sdhci_host *host, int reg) | ||
40 | { | ||
41 | u16 ret; | ||
42 | |||
43 | if (unlikely(reg == SDHCI_HOST_VERSION)) | ||
44 | ret = in_be16(host->ioaddr + reg); | ||
45 | else | ||
46 | ret = sdhci_be32bs_readw(host, reg); | ||
47 | return ret; | ||
48 | } | ||
49 | |||
50 | static void esdhc_writew(struct sdhci_host *host, u16 val, int reg) | ||
51 | { | ||
52 | if (reg == SDHCI_BLOCK_SIZE) { | ||
53 | /* | ||
54 | * Two last DMA bits are reserved, and first one is used for | ||
55 | * non-standard blksz of 4096 bytes that we don't support | ||
56 | * yet. So clear the DMA boundary bits. | ||
57 | */ | ||
58 | val &= ~SDHCI_MAKE_BLKSZ(0x7, 0); | ||
59 | } | ||
60 | sdhci_be32bs_writew(host, val, reg); | ||
61 | } | ||
62 | |||
63 | static void esdhc_writeb(struct sdhci_host *host, u8 val, int reg) | ||
64 | { | ||
65 | /* Prevent SDHCI core from writing reserved bits (e.g. HISPD). */ | ||
66 | if (reg == SDHCI_HOST_CONTROL) | ||
67 | val &= ~ESDHC_HOST_CONTROL_RES; | ||
68 | sdhci_be32bs_writeb(host, val, reg); | ||
69 | } | ||
70 | |||
71 | static void esdhc_set_clock(struct sdhci_host *host, unsigned int clock) | ||
72 | { | ||
73 | int pre_div = 2; | ||
74 | int div = 1; | ||
75 | |||
76 | clrbits32(host->ioaddr + ESDHC_SYSTEM_CONTROL, ESDHC_CLOCK_IPGEN | | ||
77 | ESDHC_CLOCK_HCKEN | ESDHC_CLOCK_PEREN | ESDHC_CLOCK_MASK); | ||
78 | |||
79 | if (clock == 0) | ||
80 | goto out; | ||
81 | |||
82 | while (host->max_clk / pre_div / 16 > clock && pre_div < 256) | ||
83 | pre_div *= 2; | ||
84 | |||
85 | while (host->max_clk / pre_div / div > clock && div < 16) | ||
86 | div++; | ||
87 | |||
88 | dev_dbg(mmc_dev(host->mmc), "desired SD clock: %d, actual: %d\n", | ||
89 | clock, host->max_clk / pre_div / div); | ||
90 | |||
91 | pre_div >>= 1; | ||
92 | div--; | ||
93 | |||
94 | setbits32(host->ioaddr + ESDHC_SYSTEM_CONTROL, ESDHC_CLOCK_IPGEN | | ||
95 | ESDHC_CLOCK_HCKEN | ESDHC_CLOCK_PEREN | | ||
96 | div << ESDHC_DIVIDER_SHIFT | pre_div << ESDHC_PREDIV_SHIFT); | ||
97 | mdelay(100); | ||
98 | out: | ||
99 | host->clock = clock; | ||
100 | } | ||
101 | |||
102 | static int esdhc_enable_dma(struct sdhci_host *host) | ||
103 | { | ||
104 | setbits32(host->ioaddr + ESDHC_DMA_SYSCTL, ESDHC_DMA_SNOOP); | ||
105 | return 0; | ||
106 | } | ||
107 | |||
108 | static unsigned int esdhc_get_max_clock(struct sdhci_host *host) | ||
109 | { | ||
110 | struct sdhci_of_host *of_host = sdhci_priv(host); | ||
111 | |||
112 | return of_host->clock; | ||
113 | } | ||
114 | |||
115 | static unsigned int esdhc_get_min_clock(struct sdhci_host *host) | ||
116 | { | ||
117 | struct sdhci_of_host *of_host = sdhci_priv(host); | ||
118 | |||
119 | return of_host->clock / 256 / 16; | ||
120 | } | ||
121 | |||
122 | struct sdhci_of_data sdhci_esdhc = { | ||
123 | .quirks = SDHCI_QUIRK_FORCE_BLK_SZ_2048 | | ||
124 | SDHCI_QUIRK_BROKEN_CARD_DETECTION | | ||
125 | SDHCI_QUIRK_NO_BUSY_IRQ | | ||
126 | SDHCI_QUIRK_NONSTANDARD_CLOCK | | ||
127 | SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK | | ||
128 | SDHCI_QUIRK_PIO_NEEDS_DELAY | | ||
129 | SDHCI_QUIRK_RESTORE_IRQS_AFTER_RESET | | ||
130 | SDHCI_QUIRK_NO_CARD_NO_RESET, | ||
131 | .ops = { | ||
132 | .readl = sdhci_be32bs_readl, | ||
133 | .readw = esdhc_readw, | ||
134 | .readb = sdhci_be32bs_readb, | ||
135 | .writel = sdhci_be32bs_writel, | ||
136 | .writew = esdhc_writew, | ||
137 | .writeb = esdhc_writeb, | ||
138 | .set_clock = esdhc_set_clock, | ||
139 | .enable_dma = esdhc_enable_dma, | ||
140 | .get_max_clock = esdhc_get_max_clock, | ||
141 | .get_min_clock = esdhc_get_min_clock, | ||
142 | }, | ||
143 | }; | ||
diff --git a/drivers/mmc/host/sdhci-of-hlwd.c b/drivers/mmc/host/sdhci-of-hlwd.c new file mode 100644 index 000000000000..35117f3ed757 --- /dev/null +++ b/drivers/mmc/host/sdhci-of-hlwd.c | |||
@@ -0,0 +1,65 @@ | |||
1 | /* | ||
2 | * drivers/mmc/host/sdhci-of-hlwd.c | ||
3 | * | ||
4 | * Nintendo Wii Secure Digital Host Controller Interface. | ||
5 | * Copyright (C) 2009 The GameCube Linux Team | ||
6 | * Copyright (C) 2009 Albert Herranz | ||
7 | * | ||
8 | * Based on sdhci-of-esdhc.c | ||
9 | * | ||
10 | * Copyright (c) 2007 Freescale Semiconductor, Inc. | ||
11 | * Copyright (c) 2009 MontaVista Software, Inc. | ||
12 | * | ||
13 | * Authors: Xiaobo Xie <X.Xie@freescale.com> | ||
14 | * Anton Vorontsov <avorontsov@ru.mvista.com> | ||
15 | * | ||
16 | * This program is free software; you can redistribute it and/or modify | ||
17 | * it under the terms of the GNU General Public License as published by | ||
18 | * the Free Software Foundation; either version 2 of the License, or (at | ||
19 | * your option) any later version. | ||
20 | */ | ||
21 | |||
22 | #include <linux/delay.h> | ||
23 | #include <linux/mmc/host.h> | ||
24 | #include "sdhci-of.h" | ||
25 | #include "sdhci.h" | ||
26 | |||
27 | /* | ||
28 | * Ops and quirks for the Nintendo Wii SDHCI controllers. | ||
29 | */ | ||
30 | |||
31 | /* | ||
32 | * We need a small delay after each write, or things go horribly wrong. | ||
33 | */ | ||
34 | #define SDHCI_HLWD_WRITE_DELAY 5 /* usecs */ | ||
35 | |||
36 | static void sdhci_hlwd_writel(struct sdhci_host *host, u32 val, int reg) | ||
37 | { | ||
38 | sdhci_be32bs_writel(host, val, reg); | ||
39 | udelay(SDHCI_HLWD_WRITE_DELAY); | ||
40 | } | ||
41 | |||
42 | static void sdhci_hlwd_writew(struct sdhci_host *host, u16 val, int reg) | ||
43 | { | ||
44 | sdhci_be32bs_writew(host, val, reg); | ||
45 | udelay(SDHCI_HLWD_WRITE_DELAY); | ||
46 | } | ||
47 | |||
48 | static void sdhci_hlwd_writeb(struct sdhci_host *host, u8 val, int reg) | ||
49 | { | ||
50 | sdhci_be32bs_writeb(host, val, reg); | ||
51 | udelay(SDHCI_HLWD_WRITE_DELAY); | ||
52 | } | ||
53 | |||
54 | struct sdhci_of_data sdhci_hlwd = { | ||
55 | .quirks = SDHCI_QUIRK_32BIT_DMA_ADDR | | ||
56 | SDHCI_QUIRK_32BIT_DMA_SIZE, | ||
57 | .ops = { | ||
58 | .readl = sdhci_be32bs_readl, | ||
59 | .readw = sdhci_be32bs_readw, | ||
60 | .readb = sdhci_be32bs_readb, | ||
61 | .writel = sdhci_hlwd_writel, | ||
62 | .writew = sdhci_hlwd_writew, | ||
63 | .writeb = sdhci_hlwd_writeb, | ||
64 | }, | ||
65 | }; | ||
diff --git a/drivers/mmc/host/sdhci-of.h b/drivers/mmc/host/sdhci-of.h new file mode 100644 index 000000000000..ad09ad9915d8 --- /dev/null +++ b/drivers/mmc/host/sdhci-of.h | |||
@@ -0,0 +1,42 @@ | |||
1 | /* | ||
2 | * OpenFirmware bindings for Secure Digital Host Controller Interface. | ||
3 | * | ||
4 | * Copyright (c) 2007 Freescale Semiconductor, Inc. | ||
5 | * Copyright (c) 2009 MontaVista Software, Inc. | ||
6 | * | ||
7 | * Authors: Xiaobo Xie <X.Xie@freescale.com> | ||
8 | * Anton Vorontsov <avorontsov@ru.mvista.com> | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of the GNU General Public License as published by | ||
12 | * the Free Software Foundation; either version 2 of the License, or (at | ||
13 | * your option) any later version. | ||
14 | */ | ||
15 | |||
16 | #ifndef __SDHCI_OF_H | ||
17 | #define __SDHCI_OF_H | ||
18 | |||
19 | #include <linux/types.h> | ||
20 | #include "sdhci.h" | ||
21 | |||
22 | struct sdhci_of_data { | ||
23 | unsigned int quirks; | ||
24 | struct sdhci_ops ops; | ||
25 | }; | ||
26 | |||
27 | struct sdhci_of_host { | ||
28 | unsigned int clock; | ||
29 | u16 xfer_mode_shadow; | ||
30 | }; | ||
31 | |||
32 | extern u32 sdhci_be32bs_readl(struct sdhci_host *host, int reg); | ||
33 | extern u16 sdhci_be32bs_readw(struct sdhci_host *host, int reg); | ||
34 | extern u8 sdhci_be32bs_readb(struct sdhci_host *host, int reg); | ||
35 | extern void sdhci_be32bs_writel(struct sdhci_host *host, u32 val, int reg); | ||
36 | extern void sdhci_be32bs_writew(struct sdhci_host *host, u16 val, int reg); | ||
37 | extern void sdhci_be32bs_writeb(struct sdhci_host *host, u8 val, int reg); | ||
38 | |||
39 | extern struct sdhci_of_data sdhci_esdhc; | ||
40 | extern struct sdhci_of_data sdhci_hlwd; | ||
41 | |||
42 | #endif /* __SDHCI_OF_H */ | ||
diff --git a/drivers/mmc/host/sdhci-pci.c b/drivers/mmc/host/sdhci-pci.c index e0356644d1aa..6701af629c30 100644 --- a/drivers/mmc/host/sdhci-pci.c +++ b/drivers/mmc/host/sdhci-pci.c | |||
@@ -16,6 +16,7 @@ | |||
16 | #include <linux/highmem.h> | 16 | #include <linux/highmem.h> |
17 | #include <linux/pci.h> | 17 | #include <linux/pci.h> |
18 | #include <linux/dma-mapping.h> | 18 | #include <linux/dma-mapping.h> |
19 | #include <linux/slab.h> | ||
19 | 20 | ||
20 | #include <linux/mmc/host.h> | 21 | #include <linux/mmc/host.h> |
21 | 22 | ||
@@ -80,9 +81,6 @@ struct sdhci_pci_chip { | |||
80 | 81 | ||
81 | static int ricoh_probe(struct sdhci_pci_chip *chip) | 82 | static int ricoh_probe(struct sdhci_pci_chip *chip) |
82 | { | 83 | { |
83 | if (chip->pdev->subsystem_vendor == PCI_VENDOR_ID_IBM) | ||
84 | chip->quirks |= SDHCI_QUIRK_CLOCK_BEFORE_RESET; | ||
85 | |||
86 | if (chip->pdev->subsystem_vendor == PCI_VENDOR_ID_SAMSUNG || | 84 | if (chip->pdev->subsystem_vendor == PCI_VENDOR_ID_SAMSUNG || |
87 | chip->pdev->subsystem_vendor == PCI_VENDOR_ID_SONY) | 85 | chip->pdev->subsystem_vendor == PCI_VENDOR_ID_SONY) |
88 | chip->quirks |= SDHCI_QUIRK_NO_CARD_NO_RESET; | 86 | chip->quirks |= SDHCI_QUIRK_NO_CARD_NO_RESET; |
@@ -92,7 +90,9 @@ static int ricoh_probe(struct sdhci_pci_chip *chip) | |||
92 | 90 | ||
93 | static const struct sdhci_pci_fixes sdhci_ricoh = { | 91 | static const struct sdhci_pci_fixes sdhci_ricoh = { |
94 | .probe = ricoh_probe, | 92 | .probe = ricoh_probe, |
95 | .quirks = SDHCI_QUIRK_32BIT_DMA_ADDR, | 93 | .quirks = SDHCI_QUIRK_32BIT_DMA_ADDR | |
94 | SDHCI_QUIRK_FORCE_DMA | | ||
95 | SDHCI_QUIRK_CLOCK_BEFORE_RESET, | ||
96 | }; | 96 | }; |
97 | 97 | ||
98 | static const struct sdhci_pci_fixes sdhci_ene_712 = { | 98 | static const struct sdhci_pci_fixes sdhci_ene_712 = { |
@@ -285,6 +285,73 @@ static const struct sdhci_pci_fixes sdhci_jmicron = { | |||
285 | .resume = jmicron_resume, | 285 | .resume = jmicron_resume, |
286 | }; | 286 | }; |
287 | 287 | ||
288 | /* SysKonnect CardBus2SDIO extra registers */ | ||
289 | #define SYSKT_CTRL 0x200 | ||
290 | #define SYSKT_RDFIFO_STAT 0x204 | ||
291 | #define SYSKT_WRFIFO_STAT 0x208 | ||
292 | #define SYSKT_POWER_DATA 0x20c | ||
293 | #define SYSKT_POWER_330 0xef | ||
294 | #define SYSKT_POWER_300 0xf8 | ||
295 | #define SYSKT_POWER_184 0xcc | ||
296 | #define SYSKT_POWER_CMD 0x20d | ||
297 | #define SYSKT_POWER_START (1 << 7) | ||
298 | #define SYSKT_POWER_STATUS 0x20e | ||
299 | #define SYSKT_POWER_STATUS_OK (1 << 0) | ||
300 | #define SYSKT_BOARD_REV 0x210 | ||
301 | #define SYSKT_CHIP_REV 0x211 | ||
302 | #define SYSKT_CONF_DATA 0x212 | ||
303 | #define SYSKT_CONF_DATA_1V8 (1 << 2) | ||
304 | #define SYSKT_CONF_DATA_2V5 (1 << 1) | ||
305 | #define SYSKT_CONF_DATA_3V3 (1 << 0) | ||
306 | |||
307 | static int syskt_probe(struct sdhci_pci_chip *chip) | ||
308 | { | ||
309 | if ((chip->pdev->class & 0x0000FF) == PCI_SDHCI_IFVENDOR) { | ||
310 | chip->pdev->class &= ~0x0000FF; | ||
311 | chip->pdev->class |= PCI_SDHCI_IFDMA; | ||
312 | } | ||
313 | return 0; | ||
314 | } | ||
315 | |||
316 | static int syskt_probe_slot(struct sdhci_pci_slot *slot) | ||
317 | { | ||
318 | int tm, ps; | ||
319 | |||
320 | u8 board_rev = readb(slot->host->ioaddr + SYSKT_BOARD_REV); | ||
321 | u8 chip_rev = readb(slot->host->ioaddr + SYSKT_CHIP_REV); | ||
322 | dev_info(&slot->chip->pdev->dev, "SysKonnect CardBus2SDIO, " | ||
323 | "board rev %d.%d, chip rev %d.%d\n", | ||
324 | board_rev >> 4, board_rev & 0xf, | ||
325 | chip_rev >> 4, chip_rev & 0xf); | ||
326 | if (chip_rev >= 0x20) | ||
327 | slot->host->quirks |= SDHCI_QUIRK_FORCE_DMA; | ||
328 | |||
329 | writeb(SYSKT_POWER_330, slot->host->ioaddr + SYSKT_POWER_DATA); | ||
330 | writeb(SYSKT_POWER_START, slot->host->ioaddr + SYSKT_POWER_CMD); | ||
331 | udelay(50); | ||
332 | tm = 10; /* Wait max 1 ms */ | ||
333 | do { | ||
334 | ps = readw(slot->host->ioaddr + SYSKT_POWER_STATUS); | ||
335 | if (ps & SYSKT_POWER_STATUS_OK) | ||
336 | break; | ||
337 | udelay(100); | ||
338 | } while (--tm); | ||
339 | if (!tm) { | ||
340 | dev_err(&slot->chip->pdev->dev, | ||
341 | "power regulator never stabilized"); | ||
342 | writeb(0, slot->host->ioaddr + SYSKT_POWER_CMD); | ||
343 | return -ENODEV; | ||
344 | } | ||
345 | |||
346 | return 0; | ||
347 | } | ||
348 | |||
349 | static const struct sdhci_pci_fixes sdhci_syskt = { | ||
350 | .quirks = SDHCI_QUIRK_NO_SIMULT_VDD_AND_POWER, | ||
351 | .probe = syskt_probe, | ||
352 | .probe_slot = syskt_probe_slot, | ||
353 | }; | ||
354 | |||
288 | static int via_probe(struct sdhci_pci_chip *chip) | 355 | static int via_probe(struct sdhci_pci_chip *chip) |
289 | { | 356 | { |
290 | if (chip->pdev->revision == 0x10) | 357 | if (chip->pdev->revision == 0x10) |
@@ -363,6 +430,14 @@ static const struct pci_device_id pci_ids[] __devinitdata = { | |||
363 | }, | 430 | }, |
364 | 431 | ||
365 | { | 432 | { |
433 | .vendor = PCI_VENDOR_ID_SYSKONNECT, | ||
434 | .device = 0x8000, | ||
435 | .subvendor = PCI_ANY_ID, | ||
436 | .subdevice = PCI_ANY_ID, | ||
437 | .driver_data = (kernel_ulong_t)&sdhci_syskt, | ||
438 | }, | ||
439 | |||
440 | { | ||
366 | .vendor = PCI_VENDOR_ID_VIA, | 441 | .vendor = PCI_VENDOR_ID_VIA, |
367 | .device = 0x95d0, | 442 | .device = 0x95d0, |
368 | .subvendor = PCI_ANY_ID, | 443 | .subvendor = PCI_ANY_ID, |
@@ -426,6 +501,7 @@ static int sdhci_pci_suspend (struct pci_dev *pdev, pm_message_t state) | |||
426 | { | 501 | { |
427 | struct sdhci_pci_chip *chip; | 502 | struct sdhci_pci_chip *chip; |
428 | struct sdhci_pci_slot *slot; | 503 | struct sdhci_pci_slot *slot; |
504 | mmc_pm_flag_t pm_flags = 0; | ||
429 | int i, ret; | 505 | int i, ret; |
430 | 506 | ||
431 | chip = pci_get_drvdata(pdev); | 507 | chip = pci_get_drvdata(pdev); |
@@ -444,6 +520,8 @@ static int sdhci_pci_suspend (struct pci_dev *pdev, pm_message_t state) | |||
444 | sdhci_resume_host(chip->slots[i]->host); | 520 | sdhci_resume_host(chip->slots[i]->host); |
445 | return ret; | 521 | return ret; |
446 | } | 522 | } |
523 | |||
524 | pm_flags |= slot->host->mmc->pm_flags; | ||
447 | } | 525 | } |
448 | 526 | ||
449 | if (chip->fixes && chip->fixes->suspend) { | 527 | if (chip->fixes && chip->fixes->suspend) { |
@@ -456,9 +534,15 @@ static int sdhci_pci_suspend (struct pci_dev *pdev, pm_message_t state) | |||
456 | } | 534 | } |
457 | 535 | ||
458 | pci_save_state(pdev); | 536 | pci_save_state(pdev); |
459 | pci_enable_wake(pdev, pci_choose_state(pdev, state), 0); | 537 | if (pm_flags & MMC_PM_KEEP_POWER) { |
460 | pci_disable_device(pdev); | 538 | if (pm_flags & MMC_PM_WAKE_SDIO_IRQ) |
461 | pci_set_power_state(pdev, pci_choose_state(pdev, state)); | 539 | pci_enable_wake(pdev, PCI_D3hot, 1); |
540 | pci_set_power_state(pdev, PCI_D3hot); | ||
541 | } else { | ||
542 | pci_enable_wake(pdev, pci_choose_state(pdev, state), 0); | ||
543 | pci_disable_device(pdev); | ||
544 | pci_set_power_state(pdev, pci_choose_state(pdev, state)); | ||
545 | } | ||
462 | 546 | ||
463 | return 0; | 547 | return 0; |
464 | } | 548 | } |
@@ -578,6 +662,8 @@ static struct sdhci_pci_slot * __devinit sdhci_pci_probe_slot( | |||
578 | goto unmap; | 662 | goto unmap; |
579 | } | 663 | } |
580 | 664 | ||
665 | host->mmc->pm_caps = MMC_PM_KEEP_POWER | MMC_PM_WAKE_SDIO_IRQ; | ||
666 | |||
581 | ret = sdhci_add_host(host); | 667 | ret = sdhci_add_host(host); |
582 | if (ret) | 668 | if (ret) |
583 | goto remove; | 669 | goto remove; |
diff --git a/drivers/mmc/host/sdhci-s3c.c b/drivers/mmc/host/sdhci-s3c.c index 50997d2a63e7..2136794c0cfa 100644 --- a/drivers/mmc/host/sdhci-s3c.c +++ b/drivers/mmc/host/sdhci-s3c.c | |||
@@ -15,6 +15,7 @@ | |||
15 | #include <linux/delay.h> | 15 | #include <linux/delay.h> |
16 | #include <linux/dma-mapping.h> | 16 | #include <linux/dma-mapping.h> |
17 | #include <linux/platform_device.h> | 17 | #include <linux/platform_device.h> |
18 | #include <linux/slab.h> | ||
18 | #include <linux/clk.h> | 19 | #include <linux/clk.h> |
19 | #include <linux/io.h> | 20 | #include <linux/io.h> |
20 | 21 | ||
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index c279fbc4c2e5..9d4fdfa685e5 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c | |||
@@ -17,6 +17,7 @@ | |||
17 | #include <linux/highmem.h> | 17 | #include <linux/highmem.h> |
18 | #include <linux/io.h> | 18 | #include <linux/io.h> |
19 | #include <linux/dma-mapping.h> | 19 | #include <linux/dma-mapping.h> |
20 | #include <linux/slab.h> | ||
20 | #include <linux/scatterlist.h> | 21 | #include <linux/scatterlist.h> |
21 | 22 | ||
22 | #include <linux/leds.h> | 23 | #include <linux/leds.h> |
@@ -174,20 +175,31 @@ static void sdhci_reset(struct sdhci_host *host, u8 mask) | |||
174 | sdhci_clear_set_irqs(host, SDHCI_INT_ALL_MASK, ier); | 175 | sdhci_clear_set_irqs(host, SDHCI_INT_ALL_MASK, ier); |
175 | } | 176 | } |
176 | 177 | ||
177 | static void sdhci_init(struct sdhci_host *host) | 178 | static void sdhci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios); |
179 | |||
180 | static void sdhci_init(struct sdhci_host *host, int soft) | ||
178 | { | 181 | { |
179 | sdhci_reset(host, SDHCI_RESET_ALL); | 182 | if (soft) |
183 | sdhci_reset(host, SDHCI_RESET_CMD|SDHCI_RESET_DATA); | ||
184 | else | ||
185 | sdhci_reset(host, SDHCI_RESET_ALL); | ||
180 | 186 | ||
181 | sdhci_clear_set_irqs(host, SDHCI_INT_ALL_MASK, | 187 | sdhci_clear_set_irqs(host, SDHCI_INT_ALL_MASK, |
182 | SDHCI_INT_BUS_POWER | SDHCI_INT_DATA_END_BIT | | 188 | SDHCI_INT_BUS_POWER | SDHCI_INT_DATA_END_BIT | |
183 | SDHCI_INT_DATA_CRC | SDHCI_INT_DATA_TIMEOUT | SDHCI_INT_INDEX | | 189 | SDHCI_INT_DATA_CRC | SDHCI_INT_DATA_TIMEOUT | SDHCI_INT_INDEX | |
184 | SDHCI_INT_END_BIT | SDHCI_INT_CRC | SDHCI_INT_TIMEOUT | | 190 | SDHCI_INT_END_BIT | SDHCI_INT_CRC | SDHCI_INT_TIMEOUT | |
185 | SDHCI_INT_DATA_END | SDHCI_INT_RESPONSE); | 191 | SDHCI_INT_DATA_END | SDHCI_INT_RESPONSE); |
192 | |||
193 | if (soft) { | ||
194 | /* force clock reconfiguration */ | ||
195 | host->clock = 0; | ||
196 | sdhci_set_ios(host->mmc, &host->mmc->ios); | ||
197 | } | ||
186 | } | 198 | } |
187 | 199 | ||
188 | static void sdhci_reinit(struct sdhci_host *host) | 200 | static void sdhci_reinit(struct sdhci_host *host) |
189 | { | 201 | { |
190 | sdhci_init(host); | 202 | sdhci_init(host, 0); |
191 | sdhci_enable_card_detection(host); | 203 | sdhci_enable_card_detection(host); |
192 | } | 204 | } |
193 | 205 | ||
@@ -376,6 +388,20 @@ static void sdhci_kunmap_atomic(void *buffer, unsigned long *flags) | |||
376 | local_irq_restore(*flags); | 388 | local_irq_restore(*flags); |
377 | } | 389 | } |
378 | 390 | ||
391 | static void sdhci_set_adma_desc(u8 *desc, u32 addr, int len, unsigned cmd) | ||
392 | { | ||
393 | __le32 *dataddr = (__le32 __force *)(desc + 4); | ||
394 | __le16 *cmdlen = (__le16 __force *)desc; | ||
395 | |||
396 | /* SDHCI specification says ADMA descriptors should be 4 byte | ||
397 | * aligned, so using 16 or 32bit operations should be safe. */ | ||
398 | |||
399 | cmdlen[0] = cpu_to_le16(cmd); | ||
400 | cmdlen[1] = cpu_to_le16(len); | ||
401 | |||
402 | dataddr[0] = cpu_to_le32(addr); | ||
403 | } | ||
404 | |||
379 | static int sdhci_adma_table_pre(struct sdhci_host *host, | 405 | static int sdhci_adma_table_pre(struct sdhci_host *host, |
380 | struct mmc_data *data) | 406 | struct mmc_data *data) |
381 | { | 407 | { |
@@ -443,19 +469,11 @@ static int sdhci_adma_table_pre(struct sdhci_host *host, | |||
443 | sdhci_kunmap_atomic(buffer, &flags); | 469 | sdhci_kunmap_atomic(buffer, &flags); |
444 | } | 470 | } |
445 | 471 | ||
446 | desc[7] = (align_addr >> 24) & 0xff; | 472 | /* tran, valid */ |
447 | desc[6] = (align_addr >> 16) & 0xff; | 473 | sdhci_set_adma_desc(desc, align_addr, offset, 0x21); |
448 | desc[5] = (align_addr >> 8) & 0xff; | ||
449 | desc[4] = (align_addr >> 0) & 0xff; | ||
450 | 474 | ||
451 | BUG_ON(offset > 65536); | 475 | BUG_ON(offset > 65536); |
452 | 476 | ||
453 | desc[3] = (offset >> 8) & 0xff; | ||
454 | desc[2] = (offset >> 0) & 0xff; | ||
455 | |||
456 | desc[1] = 0x00; | ||
457 | desc[0] = 0x21; /* tran, valid */ | ||
458 | |||
459 | align += 4; | 477 | align += 4; |
460 | align_addr += 4; | 478 | align_addr += 4; |
461 | 479 | ||
@@ -465,19 +483,10 @@ static int sdhci_adma_table_pre(struct sdhci_host *host, | |||
465 | len -= offset; | 483 | len -= offset; |
466 | } | 484 | } |
467 | 485 | ||
468 | desc[7] = (addr >> 24) & 0xff; | ||
469 | desc[6] = (addr >> 16) & 0xff; | ||
470 | desc[5] = (addr >> 8) & 0xff; | ||
471 | desc[4] = (addr >> 0) & 0xff; | ||
472 | |||
473 | BUG_ON(len > 65536); | 486 | BUG_ON(len > 65536); |
474 | 487 | ||
475 | desc[3] = (len >> 8) & 0xff; | 488 | /* tran, valid */ |
476 | desc[2] = (len >> 0) & 0xff; | 489 | sdhci_set_adma_desc(desc, addr, len, 0x21); |
477 | |||
478 | desc[1] = 0x00; | ||
479 | desc[0] = 0x21; /* tran, valid */ | ||
480 | |||
481 | desc += 8; | 490 | desc += 8; |
482 | 491 | ||
483 | /* | 492 | /* |
@@ -490,16 +499,9 @@ static int sdhci_adma_table_pre(struct sdhci_host *host, | |||
490 | /* | 499 | /* |
491 | * Add a terminating entry. | 500 | * Add a terminating entry. |
492 | */ | 501 | */ |
493 | desc[7] = 0; | ||
494 | desc[6] = 0; | ||
495 | desc[5] = 0; | ||
496 | desc[4] = 0; | ||
497 | 502 | ||
498 | desc[3] = 0; | 503 | /* nop, end, valid */ |
499 | desc[2] = 0; | 504 | sdhci_set_adma_desc(desc, 0, 0, 0x3); |
500 | |||
501 | desc[1] = 0x00; | ||
502 | desc[0] = 0x03; /* nop, end, valid */ | ||
503 | 505 | ||
504 | /* | 506 | /* |
505 | * Resync align buffer as we might have changed it. | 507 | * Resync align buffer as we might have changed it. |
@@ -1610,16 +1612,13 @@ int sdhci_resume_host(struct sdhci_host *host) | |||
1610 | if (ret) | 1612 | if (ret) |
1611 | return ret; | 1613 | return ret; |
1612 | 1614 | ||
1613 | sdhci_init(host); | 1615 | sdhci_init(host, (host->mmc->pm_flags & MMC_PM_KEEP_POWER)); |
1614 | mmiowb(); | 1616 | mmiowb(); |
1615 | 1617 | ||
1616 | ret = mmc_resume_host(host->mmc); | 1618 | ret = mmc_resume_host(host->mmc); |
1617 | if (ret) | ||
1618 | return ret; | ||
1619 | |||
1620 | sdhci_enable_card_detection(host); | 1619 | sdhci_enable_card_detection(host); |
1621 | 1620 | ||
1622 | return 0; | 1621 | return ret; |
1623 | } | 1622 | } |
1624 | 1623 | ||
1625 | EXPORT_SYMBOL_GPL(sdhci_resume_host); | 1624 | EXPORT_SYMBOL_GPL(sdhci_resume_host); |
@@ -1874,7 +1873,7 @@ int sdhci_add_host(struct sdhci_host *host) | |||
1874 | if (ret) | 1873 | if (ret) |
1875 | goto untasklet; | 1874 | goto untasklet; |
1876 | 1875 | ||
1877 | sdhci_init(host); | 1876 | sdhci_init(host, 0); |
1878 | 1877 | ||
1879 | #ifdef CONFIG_MMC_DEBUG | 1878 | #ifdef CONFIG_MMC_DEBUG |
1880 | sdhci_dumpregs(host); | 1879 | sdhci_dumpregs(host); |
diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h index ce5f1d73dc04..842f46f94284 100644 --- a/drivers/mmc/host/sdhci.h +++ b/drivers/mmc/host/sdhci.h | |||
@@ -8,6 +8,8 @@ | |||
8 | * the Free Software Foundation; either version 2 of the License, or (at | 8 | * the Free Software Foundation; either version 2 of the License, or (at |
9 | * your option) any later version. | 9 | * your option) any later version. |
10 | */ | 10 | */ |
11 | #ifndef __SDHCI_H | ||
12 | #define __SDHCI_H | ||
11 | 13 | ||
12 | #include <linux/scatterlist.h> | 14 | #include <linux/scatterlist.h> |
13 | #include <linux/compiler.h> | 15 | #include <linux/compiler.h> |
@@ -408,3 +410,5 @@ extern void sdhci_remove_host(struct sdhci_host *host, int dead); | |||
408 | extern int sdhci_suspend_host(struct sdhci_host *host, pm_message_t state); | 410 | extern int sdhci_suspend_host(struct sdhci_host *host, pm_message_t state); |
409 | extern int sdhci_resume_host(struct sdhci_host *host); | 411 | extern int sdhci_resume_host(struct sdhci_host *host); |
410 | #endif | 412 | #endif |
413 | |||
414 | #endif /* __SDHCI_H */ | ||
diff --git a/drivers/mmc/host/tmio_mmc.c b/drivers/mmc/host/tmio_mmc.c index 91991b460c45..b2b577f6afd4 100644 --- a/drivers/mmc/host/tmio_mmc.c +++ b/drivers/mmc/host/tmio_mmc.c | |||
@@ -46,7 +46,9 @@ static void tmio_mmc_set_clock(struct tmio_mmc_host *host, int new_clock) | |||
46 | clk |= 0x100; | 46 | clk |= 0x100; |
47 | } | 47 | } |
48 | 48 | ||
49 | sd_config_write8(host, CNF_SD_CLK_MODE, clk >> 22); | 49 | if (host->set_clk_div) |
50 | host->set_clk_div(host->pdev, (clk>>22) & 1); | ||
51 | |||
50 | sd_ctrl_write16(host, CTL_SD_CARD_CLK_CTL, clk & 0x1ff); | 52 | sd_ctrl_write16(host, CTL_SD_CARD_CLK_CTL, clk & 0x1ff); |
51 | } | 53 | } |
52 | 54 | ||
@@ -321,7 +323,7 @@ static irqreturn_t tmio_mmc_irq(int irq, void *devid) | |||
321 | if (ireg & (TMIO_STAT_CARD_INSERT | TMIO_STAT_CARD_REMOVE)) { | 323 | if (ireg & (TMIO_STAT_CARD_INSERT | TMIO_STAT_CARD_REMOVE)) { |
322 | ack_mmc_irqs(host, TMIO_STAT_CARD_INSERT | | 324 | ack_mmc_irqs(host, TMIO_STAT_CARD_INSERT | |
323 | TMIO_STAT_CARD_REMOVE); | 325 | TMIO_STAT_CARD_REMOVE); |
324 | mmc_detect_change(host->mmc, 0); | 326 | mmc_detect_change(host->mmc, msecs_to_jiffies(100)); |
325 | } | 327 | } |
326 | 328 | ||
327 | /* CRC and other errors */ | 329 | /* CRC and other errors */ |
@@ -427,12 +429,13 @@ static void tmio_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) | |||
427 | /* Power sequence - OFF -> ON -> UP */ | 429 | /* Power sequence - OFF -> ON -> UP */ |
428 | switch (ios->power_mode) { | 430 | switch (ios->power_mode) { |
429 | case MMC_POWER_OFF: /* power down SD bus */ | 431 | case MMC_POWER_OFF: /* power down SD bus */ |
430 | sd_config_write8(host, CNF_PWR_CTL_2, 0x00); | 432 | if (host->set_pwr) |
433 | host->set_pwr(host->pdev, 0); | ||
431 | tmio_mmc_clk_stop(host); | 434 | tmio_mmc_clk_stop(host); |
432 | break; | 435 | break; |
433 | case MMC_POWER_ON: /* power up SD bus */ | 436 | case MMC_POWER_ON: /* power up SD bus */ |
434 | 437 | if (host->set_pwr) | |
435 | sd_config_write8(host, CNF_PWR_CTL_2, 0x02); | 438 | host->set_pwr(host->pdev, 1); |
436 | break; | 439 | break; |
437 | case MMC_POWER_UP: /* start bus clock */ | 440 | case MMC_POWER_UP: /* start bus clock */ |
438 | tmio_mmc_clk_start(host); | 441 | tmio_mmc_clk_start(host); |
@@ -485,21 +488,15 @@ static int tmio_mmc_resume(struct platform_device *dev) | |||
485 | { | 488 | { |
486 | struct mfd_cell *cell = (struct mfd_cell *)dev->dev.platform_data; | 489 | struct mfd_cell *cell = (struct mfd_cell *)dev->dev.platform_data; |
487 | struct mmc_host *mmc = platform_get_drvdata(dev); | 490 | struct mmc_host *mmc = platform_get_drvdata(dev); |
488 | struct tmio_mmc_host *host = mmc_priv(mmc); | ||
489 | int ret = 0; | 491 | int ret = 0; |
490 | 492 | ||
491 | /* Tell the MFD core we are ready to be enabled */ | 493 | /* Tell the MFD core we are ready to be enabled */ |
492 | if (cell->enable) { | 494 | if (cell->resume) { |
493 | ret = cell->enable(dev); | 495 | ret = cell->resume(dev); |
494 | if (ret) | 496 | if (ret) |
495 | goto out; | 497 | goto out; |
496 | } | 498 | } |
497 | 499 | ||
498 | /* Enable the MMC/SD Control registers */ | ||
499 | sd_config_write16(host, CNF_CMD, SDCREN); | ||
500 | sd_config_write32(host, CNF_CTL_BASE, | ||
501 | (dev->resource[0].start >> host->bus_shift) & 0xfffe); | ||
502 | |||
503 | mmc_resume_host(mmc); | 500 | mmc_resume_host(mmc); |
504 | 501 | ||
505 | out: | 502 | out: |
@@ -514,17 +511,16 @@ static int __devinit tmio_mmc_probe(struct platform_device *dev) | |||
514 | { | 511 | { |
515 | struct mfd_cell *cell = (struct mfd_cell *)dev->dev.platform_data; | 512 | struct mfd_cell *cell = (struct mfd_cell *)dev->dev.platform_data; |
516 | struct tmio_mmc_data *pdata; | 513 | struct tmio_mmc_data *pdata; |
517 | struct resource *res_ctl, *res_cnf; | 514 | struct resource *res_ctl; |
518 | struct tmio_mmc_host *host; | 515 | struct tmio_mmc_host *host; |
519 | struct mmc_host *mmc; | 516 | struct mmc_host *mmc; |
520 | int ret = -EINVAL; | 517 | int ret = -EINVAL; |
521 | 518 | ||
522 | if (dev->num_resources != 3) | 519 | if (dev->num_resources != 2) |
523 | goto out; | 520 | goto out; |
524 | 521 | ||
525 | res_ctl = platform_get_resource(dev, IORESOURCE_MEM, 0); | 522 | res_ctl = platform_get_resource(dev, IORESOURCE_MEM, 0); |
526 | res_cnf = platform_get_resource(dev, IORESOURCE_MEM, 1); | 523 | if (!res_ctl) |
527 | if (!res_ctl || !res_cnf) | ||
528 | goto out; | 524 | goto out; |
529 | 525 | ||
530 | pdata = cell->driver_data; | 526 | pdata = cell->driver_data; |
@@ -539,8 +535,12 @@ static int __devinit tmio_mmc_probe(struct platform_device *dev) | |||
539 | 535 | ||
540 | host = mmc_priv(mmc); | 536 | host = mmc_priv(mmc); |
541 | host->mmc = mmc; | 537 | host->mmc = mmc; |
538 | host->pdev = dev; | ||
542 | platform_set_drvdata(dev, mmc); | 539 | platform_set_drvdata(dev, mmc); |
543 | 540 | ||
541 | host->set_pwr = pdata->set_pwr; | ||
542 | host->set_clk_div = pdata->set_clk_div; | ||
543 | |||
544 | /* SD control register space size is 0x200, 0x400 for bus_shift=1 */ | 544 | /* SD control register space size is 0x200, 0x400 for bus_shift=1 */ |
545 | host->bus_shift = resource_size(res_ctl) >> 10; | 545 | host->bus_shift = resource_size(res_ctl) >> 10; |
546 | 546 | ||
@@ -548,12 +548,9 @@ static int __devinit tmio_mmc_probe(struct platform_device *dev) | |||
548 | if (!host->ctl) | 548 | if (!host->ctl) |
549 | goto host_free; | 549 | goto host_free; |
550 | 550 | ||
551 | host->cnf = ioremap(res_cnf->start, resource_size(res_cnf)); | ||
552 | if (!host->cnf) | ||
553 | goto unmap_ctl; | ||
554 | |||
555 | mmc->ops = &tmio_mmc_ops; | 551 | mmc->ops = &tmio_mmc_ops; |
556 | mmc->caps = MMC_CAP_4_BIT_DATA; | 552 | mmc->caps = MMC_CAP_4_BIT_DATA; |
553 | mmc->caps |= pdata->capabilities; | ||
557 | mmc->f_max = pdata->hclk; | 554 | mmc->f_max = pdata->hclk; |
558 | mmc->f_min = mmc->f_max / 512; | 555 | mmc->f_min = mmc->f_max / 512; |
559 | mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34; | 556 | mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34; |
@@ -562,23 +559,9 @@ static int __devinit tmio_mmc_probe(struct platform_device *dev) | |||
562 | if (cell->enable) { | 559 | if (cell->enable) { |
563 | ret = cell->enable(dev); | 560 | ret = cell->enable(dev); |
564 | if (ret) | 561 | if (ret) |
565 | goto unmap_cnf; | 562 | goto unmap_ctl; |
566 | } | 563 | } |
567 | 564 | ||
568 | /* Enable the MMC/SD Control registers */ | ||
569 | sd_config_write16(host, CNF_CMD, SDCREN); | ||
570 | sd_config_write32(host, CNF_CTL_BASE, | ||
571 | (dev->resource[0].start >> host->bus_shift) & 0xfffe); | ||
572 | |||
573 | /* Disable SD power during suspend */ | ||
574 | sd_config_write8(host, CNF_PWR_CTL_3, 0x01); | ||
575 | |||
576 | /* The below is required but why? FIXME */ | ||
577 | sd_config_write8(host, CNF_STOP_CLK_CTL, 0x1f); | ||
578 | |||
579 | /* Power down SD bus*/ | ||
580 | sd_config_write8(host, CNF_PWR_CTL_2, 0x00); | ||
581 | |||
582 | tmio_mmc_clk_stop(host); | 565 | tmio_mmc_clk_stop(host); |
583 | reset(host); | 566 | reset(host); |
584 | 567 | ||
@@ -586,14 +569,14 @@ static int __devinit tmio_mmc_probe(struct platform_device *dev) | |||
586 | if (ret >= 0) | 569 | if (ret >= 0) |
587 | host->irq = ret; | 570 | host->irq = ret; |
588 | else | 571 | else |
589 | goto unmap_cnf; | 572 | goto cell_disable; |
590 | 573 | ||
591 | disable_mmc_irqs(host, TMIO_MASK_ALL); | 574 | disable_mmc_irqs(host, TMIO_MASK_ALL); |
592 | 575 | ||
593 | ret = request_irq(host->irq, tmio_mmc_irq, IRQF_DISABLED | | 576 | ret = request_irq(host->irq, tmio_mmc_irq, IRQF_DISABLED | |
594 | IRQF_TRIGGER_FALLING, "tmio-mmc", host); | 577 | IRQF_TRIGGER_FALLING, dev_name(&dev->dev), host); |
595 | if (ret) | 578 | if (ret) |
596 | goto unmap_cnf; | 579 | goto cell_disable; |
597 | 580 | ||
598 | mmc_add_host(mmc); | 581 | mmc_add_host(mmc); |
599 | 582 | ||
@@ -605,8 +588,9 @@ static int __devinit tmio_mmc_probe(struct platform_device *dev) | |||
605 | 588 | ||
606 | return 0; | 589 | return 0; |
607 | 590 | ||
608 | unmap_cnf: | 591 | cell_disable: |
609 | iounmap(host->cnf); | 592 | if (cell->disable) |
593 | cell->disable(dev); | ||
610 | unmap_ctl: | 594 | unmap_ctl: |
611 | iounmap(host->ctl); | 595 | iounmap(host->ctl); |
612 | host_free: | 596 | host_free: |
@@ -617,6 +601,7 @@ out: | |||
617 | 601 | ||
618 | static int __devexit tmio_mmc_remove(struct platform_device *dev) | 602 | static int __devexit tmio_mmc_remove(struct platform_device *dev) |
619 | { | 603 | { |
604 | struct mfd_cell *cell = (struct mfd_cell *)dev->dev.platform_data; | ||
620 | struct mmc_host *mmc = platform_get_drvdata(dev); | 605 | struct mmc_host *mmc = platform_get_drvdata(dev); |
621 | 606 | ||
622 | platform_set_drvdata(dev, NULL); | 607 | platform_set_drvdata(dev, NULL); |
@@ -625,8 +610,9 @@ static int __devexit tmio_mmc_remove(struct platform_device *dev) | |||
625 | struct tmio_mmc_host *host = mmc_priv(mmc); | 610 | struct tmio_mmc_host *host = mmc_priv(mmc); |
626 | mmc_remove_host(mmc); | 611 | mmc_remove_host(mmc); |
627 | free_irq(host->irq, host); | 612 | free_irq(host->irq, host); |
613 | if (cell->disable) | ||
614 | cell->disable(dev); | ||
628 | iounmap(host->ctl); | 615 | iounmap(host->ctl); |
629 | iounmap(host->cnf); | ||
630 | mmc_free_host(mmc); | 616 | mmc_free_host(mmc); |
631 | } | 617 | } |
632 | 618 | ||
diff --git a/drivers/mmc/host/tmio_mmc.h b/drivers/mmc/host/tmio_mmc.h index 9fa998594974..dafecfbcd91a 100644 --- a/drivers/mmc/host/tmio_mmc.h +++ b/drivers/mmc/host/tmio_mmc.h | |||
@@ -11,26 +11,6 @@ | |||
11 | 11 | ||
12 | #include <linux/highmem.h> | 12 | #include <linux/highmem.h> |
13 | 13 | ||
14 | #define CNF_CMD 0x04 | ||
15 | #define CNF_CTL_BASE 0x10 | ||
16 | #define CNF_INT_PIN 0x3d | ||
17 | #define CNF_STOP_CLK_CTL 0x40 | ||
18 | #define CNF_GCLK_CTL 0x41 | ||
19 | #define CNF_SD_CLK_MODE 0x42 | ||
20 | #define CNF_PIN_STATUS 0x44 | ||
21 | #define CNF_PWR_CTL_1 0x48 | ||
22 | #define CNF_PWR_CTL_2 0x49 | ||
23 | #define CNF_PWR_CTL_3 0x4a | ||
24 | #define CNF_CARD_DETECT_MODE 0x4c | ||
25 | #define CNF_SD_SLOT 0x50 | ||
26 | #define CNF_EXT_GCLK_CTL_1 0xf0 | ||
27 | #define CNF_EXT_GCLK_CTL_2 0xf1 | ||
28 | #define CNF_EXT_GCLK_CTL_3 0xf9 | ||
29 | #define CNF_SD_LED_EN_1 0xfa | ||
30 | #define CNF_SD_LED_EN_2 0xfe | ||
31 | |||
32 | #define SDCREN 0x2 /* Enable access to MMC CTL regs. (flag in COMMAND_REG)*/ | ||
33 | |||
34 | #define CTL_SD_CMD 0x00 | 14 | #define CTL_SD_CMD 0x00 |
35 | #define CTL_ARG_REG 0x04 | 15 | #define CTL_ARG_REG 0x04 |
36 | #define CTL_STOP_INTERNAL_ACTION 0x08 | 16 | #define CTL_STOP_INTERNAL_ACTION 0x08 |
@@ -75,10 +55,8 @@ | |||
75 | /* Define some IRQ masks */ | 55 | /* Define some IRQ masks */ |
76 | /* This is the mask used at reset by the chip */ | 56 | /* This is the mask used at reset by the chip */ |
77 | #define TMIO_MASK_ALL 0x837f031d | 57 | #define TMIO_MASK_ALL 0x837f031d |
78 | #define TMIO_MASK_READOP (TMIO_STAT_RXRDY | TMIO_STAT_DATAEND | \ | 58 | #define TMIO_MASK_READOP (TMIO_STAT_RXRDY | TMIO_STAT_DATAEND) |
79 | TMIO_STAT_CARD_REMOVE | TMIO_STAT_CARD_INSERT) | 59 | #define TMIO_MASK_WRITEOP (TMIO_STAT_TXRQ | TMIO_STAT_DATAEND) |
80 | #define TMIO_MASK_WRITEOP (TMIO_STAT_TXRQ | TMIO_STAT_DATAEND | \ | ||
81 | TMIO_STAT_CARD_REMOVE | TMIO_STAT_CARD_INSERT) | ||
82 | #define TMIO_MASK_CMD (TMIO_STAT_CMDRESPEND | TMIO_STAT_CMDTIMEOUT | \ | 60 | #define TMIO_MASK_CMD (TMIO_STAT_CMDRESPEND | TMIO_STAT_CMDTIMEOUT | \ |
83 | TMIO_STAT_CARD_REMOVE | TMIO_STAT_CARD_INSERT) | 61 | TMIO_STAT_CARD_REMOVE | TMIO_STAT_CARD_INSERT) |
84 | #define TMIO_MASK_IRQ (TMIO_MASK_READOP | TMIO_MASK_WRITEOP | TMIO_MASK_CMD) | 62 | #define TMIO_MASK_IRQ (TMIO_MASK_READOP | TMIO_MASK_WRITEOP | TMIO_MASK_CMD) |
@@ -110,7 +88,6 @@ | |||
110 | 88 | ||
111 | 89 | ||
112 | struct tmio_mmc_host { | 90 | struct tmio_mmc_host { |
113 | void __iomem *cnf; | ||
114 | void __iomem *ctl; | 91 | void __iomem *ctl; |
115 | unsigned long bus_shift; | 92 | unsigned long bus_shift; |
116 | struct mmc_command *cmd; | 93 | struct mmc_command *cmd; |
@@ -119,10 +96,16 @@ struct tmio_mmc_host { | |||
119 | struct mmc_host *mmc; | 96 | struct mmc_host *mmc; |
120 | int irq; | 97 | int irq; |
121 | 98 | ||
99 | /* Callbacks for clock / power control */ | ||
100 | void (*set_pwr)(struct platform_device *host, int state); | ||
101 | void (*set_clk_div)(struct platform_device *host, int state); | ||
102 | |||
122 | /* pio related stuff */ | 103 | /* pio related stuff */ |
123 | struct scatterlist *sg_ptr; | 104 | struct scatterlist *sg_ptr; |
124 | unsigned int sg_len; | 105 | unsigned int sg_len; |
125 | unsigned int sg_off; | 106 | unsigned int sg_off; |
107 | |||
108 | struct platform_device *pdev; | ||
126 | }; | 109 | }; |
127 | 110 | ||
128 | #include <linux/io.h> | 111 | #include <linux/io.h> |
@@ -163,25 +146,6 @@ static inline void sd_ctrl_write32(struct tmio_mmc_host *host, int addr, | |||
163 | writew(val >> 16, host->ctl + ((addr + 2) << host->bus_shift)); | 146 | writew(val >> 16, host->ctl + ((addr + 2) << host->bus_shift)); |
164 | } | 147 | } |
165 | 148 | ||
166 | static inline void sd_config_write8(struct tmio_mmc_host *host, int addr, | ||
167 | u8 val) | ||
168 | { | ||
169 | writeb(val, host->cnf + (addr << host->bus_shift)); | ||
170 | } | ||
171 | |||
172 | static inline void sd_config_write16(struct tmio_mmc_host *host, int addr, | ||
173 | u16 val) | ||
174 | { | ||
175 | writew(val, host->cnf + (addr << host->bus_shift)); | ||
176 | } | ||
177 | |||
178 | static inline void sd_config_write32(struct tmio_mmc_host *host, int addr, | ||
179 | u32 val) | ||
180 | { | ||
181 | writew(val, host->cnf + (addr << host->bus_shift)); | ||
182 | writew(val >> 16, host->cnf + ((addr + 2) << host->bus_shift)); | ||
183 | } | ||
184 | |||
185 | #include <linux/scatterlist.h> | 149 | #include <linux/scatterlist.h> |
186 | #include <linux/blkdev.h> | 150 | #include <linux/blkdev.h> |
187 | 151 | ||
diff --git a/drivers/mmc/host/wbsd.c b/drivers/mmc/host/wbsd.c index 89bf8cd25cac..69efe01eece8 100644 --- a/drivers/mmc/host/wbsd.c +++ b/drivers/mmc/host/wbsd.c | |||
@@ -34,6 +34,7 @@ | |||
34 | #include <linux/highmem.h> | 34 | #include <linux/highmem.h> |
35 | #include <linux/mmc/host.h> | 35 | #include <linux/mmc/host.h> |
36 | #include <linux/scatterlist.h> | 36 | #include <linux/scatterlist.h> |
37 | #include <linux/slab.h> | ||
37 | 38 | ||
38 | #include <asm/io.h> | 39 | #include <asm/io.h> |
39 | #include <asm/dma.h> | 40 | #include <asm/dma.h> |