Commit | Line | Data |
---|---|---|
4a48998f IM |
1 | /* |
2 | * linux/drivers/mmc/tmio_mmc.c | |
3 | * | |
4 | * Copyright (C) 2004 Ian Molton | |
5 | * Copyright (C) 2007 Ian Molton | |
6 | * | |
7 | * This program is free software; you can redistribute it and/or modify | |
8 | * it under the terms of the GNU General Public License version 2 as | |
9 | * published by the Free Software Foundation. | |
10 | * | |
11 | * Driver for the MMC / SD / SDIO cell found in: | |
12 | * | |
13 | * TC6393XB TC6391XB TC6387XB T7L66XB | |
14 | * | |
15 | * This driver draws mainly on scattered spec sheets, Reverse engineering | |
16 | * of the toshiba e800 SD driver and some parts of the 2.4 ASIC3 driver (4 bit | |
17 | * support). (Further 4 bit support from a later datasheet). | |
18 | * | |
19 | * TODO: | |
20 | * Investigate using a workqueue for PIO transfers | |
21 | * Eliminate FIXMEs | |
22 | * SDIO support | |
23 | * Better Power management | |
24 | * Handle MMC errors better | |
25 | * double buffer support | |
26 | * | |
27 | */ | |
28 | #include <linux/module.h> | |
29 | #include <linux/irq.h> | |
30 | #include <linux/device.h> | |
31 | #include <linux/delay.h> | |
32 | #include <linux/mmc/host.h> | |
33 | #include <linux/mfd/core.h> | |
34 | #include <linux/mfd/tmio.h> | |
35 | ||
36 | #include "tmio_mmc.h" | |
37 | ||
38 | /* | |
39 | * Fixme - documentation conflicts on what the clock values are for the | |
40 | * various dividers. | |
41 | * One document I have says that its a divisor of a 24MHz clock, another 33. | |
42 | * This probably depends on HCLK for a given platform, so we may need to | |
43 | * require HCLK be passed to us from the MFD core. | |
44 | * | |
45 | */ | |
46 | ||
47 | static void tmio_mmc_set_clock(struct tmio_mmc_host *host, int new_clock) | |
48 | { | |
49 | void __iomem *cnf = host->cnf; | |
50 | void __iomem *ctl = host->ctl; | |
51 | u32 clk = 0, clock; | |
52 | ||
53 | if (new_clock) { | |
54 | for (clock = 46875, clk = 0x100; new_clock >= (clock<<1); ) { | |
55 | clock <<= 1; | |
56 | clk >>= 1; | |
57 | } | |
58 | if (clk & 0x1) | |
59 | clk = 0x20000; | |
60 | ||
61 | clk >>= 2; | |
62 | tmio_iowrite8((clk & 0x8000) ? 0 : 1, cnf + CNF_SD_CLK_MODE); | |
63 | clk |= 0x100; | |
64 | } | |
65 | ||
66 | tmio_iowrite16(clk, ctl + CTL_SD_CARD_CLK_CTL); | |
67 | } | |
68 | ||
69 | static void tmio_mmc_clk_stop(struct tmio_mmc_host *host) | |
70 | { | |
71 | void __iomem *ctl = host->ctl; | |
72 | ||
73 | tmio_iowrite16(0x0000, ctl + CTL_CLK_AND_WAIT_CTL); | |
74 | msleep(10); | |
75 | tmio_iowrite16(tmio_ioread16(ctl + CTL_SD_CARD_CLK_CTL) & ~0x0100, | |
76 | ctl + CTL_SD_CARD_CLK_CTL); | |
77 | msleep(10); | |
78 | } | |
79 | ||
80 | static void tmio_mmc_clk_start(struct tmio_mmc_host *host) | |
81 | { | |
82 | void __iomem *ctl = host->ctl; | |
83 | ||
84 | tmio_iowrite16(tmio_ioread16(ctl + CTL_SD_CARD_CLK_CTL) | 0x0100, | |
85 | ctl + CTL_SD_CARD_CLK_CTL); | |
86 | msleep(10); | |
87 | tmio_iowrite16(0x0100, ctl + CTL_CLK_AND_WAIT_CTL); | |
88 | msleep(10); | |
89 | } | |
90 | ||
91 | static void reset(struct tmio_mmc_host *host) | |
92 | { | |
93 | void __iomem *ctl = host->ctl; | |
94 | ||
95 | /* FIXME - should we set stop clock reg here */ | |
96 | tmio_iowrite16(0x0000, ctl + CTL_RESET_SD); | |
97 | tmio_iowrite16(0x0000, ctl + CTL_RESET_SDIO); | |
98 | msleep(10); | |
99 | tmio_iowrite16(0x0001, ctl + CTL_RESET_SD); | |
100 | tmio_iowrite16(0x0001, ctl + CTL_RESET_SDIO); | |
101 | msleep(10); | |
102 | } | |
103 | ||
104 | static void | |
105 | tmio_mmc_finish_request(struct tmio_mmc_host *host) | |
106 | { | |
107 | struct mmc_request *mrq = host->mrq; | |
108 | ||
109 | host->mrq = NULL; | |
110 | host->cmd = NULL; | |
111 | host->data = NULL; | |
112 | ||
113 | mmc_request_done(host->mmc, mrq); | |
114 | } | |
115 | ||
116 | /* These are the bitmasks the tmio chip requires to implement the MMC response | |
117 | * types. Note that R1 and R6 are the same in this scheme. */ | |
118 | #define APP_CMD 0x0040 | |
119 | #define RESP_NONE 0x0300 | |
120 | #define RESP_R1 0x0400 | |
121 | #define RESP_R1B 0x0500 | |
122 | #define RESP_R2 0x0600 | |
123 | #define RESP_R3 0x0700 | |
124 | #define DATA_PRESENT 0x0800 | |
125 | #define TRANSFER_READ 0x1000 | |
126 | #define TRANSFER_MULTI 0x2000 | |
127 | #define SECURITY_CMD 0x4000 | |
128 | ||
129 | static int | |
130 | tmio_mmc_start_command(struct tmio_mmc_host *host, struct mmc_command *cmd) | |
131 | { | |
132 | void __iomem *ctl = host->ctl; | |
133 | struct mmc_data *data = host->data; | |
134 | int c = cmd->opcode; | |
135 | ||
136 | /* Command 12 is handled by hardware */ | |
137 | if (cmd->opcode == 12 && !cmd->arg) { | |
138 | tmio_iowrite16(0x001, ctl + CTL_STOP_INTERNAL_ACTION); | |
139 | return 0; | |
140 | } | |
141 | ||
142 | switch (mmc_resp_type(cmd)) { | |
143 | case MMC_RSP_NONE: c |= RESP_NONE; break; | |
144 | case MMC_RSP_R1: c |= RESP_R1; break; | |
145 | case MMC_RSP_R1B: c |= RESP_R1B; break; | |
146 | case MMC_RSP_R2: c |= RESP_R2; break; | |
147 | case MMC_RSP_R3: c |= RESP_R3; break; | |
148 | default: | |
149 | pr_debug("Unknown response type %d\n", mmc_resp_type(cmd)); | |
150 | return -EINVAL; | |
151 | } | |
152 | ||
153 | host->cmd = cmd; | |
154 | ||
155 | /* FIXME - this seems to be ok comented out but the spec suggest this bit should | |
156 | * be set when issuing app commands. | |
157 | * if(cmd->flags & MMC_FLAG_ACMD) | |
158 | * c |= APP_CMD; | |
159 | */ | |
160 | if (data) { | |
161 | c |= DATA_PRESENT; | |
162 | if (data->blocks > 1) { | |
163 | tmio_iowrite16(0x100, ctl + CTL_STOP_INTERNAL_ACTION); | |
164 | c |= TRANSFER_MULTI; | |
165 | } | |
166 | if (data->flags & MMC_DATA_READ) | |
167 | c |= TRANSFER_READ; | |
168 | } | |
169 | ||
170 | enable_mmc_irqs(ctl, TMIO_MASK_CMD); | |
171 | ||
172 | /* Fire off the command */ | |
173 | tmio_iowrite32(cmd->arg, ctl + CTL_ARG_REG); | |
174 | tmio_iowrite16(c, ctl + CTL_SD_CMD); | |
175 | ||
176 | return 0; | |
177 | } | |
178 | ||
179 | /* This chip always returns (at least?) as much data as you ask for. | |
180 | * I'm unsure what happens if you ask for less than a block. This should be | |
181 | * looked into to ensure that a funny length read doesnt hose the controller. | |
182 | * | |
183 | */ | |
184 | static inline void tmio_mmc_pio_irq(struct tmio_mmc_host *host) | |
185 | { | |
186 | void __iomem *ctl = host->ctl; | |
187 | struct mmc_data *data = host->data; | |
188 | unsigned short *buf; | |
189 | unsigned int count; | |
190 | unsigned long flags; | |
191 | ||
192 | if (!data) { | |
193 | pr_debug("Spurious PIO IRQ\n"); | |
194 | return; | |
195 | } | |
196 | ||
197 | buf = (unsigned short *)(tmio_mmc_kmap_atomic(host, &flags) + | |
198 | host->sg_off); | |
199 | ||
200 | count = host->sg_ptr->length - host->sg_off; | |
201 | if (count > data->blksz) | |
202 | count = data->blksz; | |
203 | ||
204 | pr_debug("count: %08x offset: %08x flags %08x\n", | |
205 | count, host->sg_off, data->flags); | |
206 | ||
207 | /* Transfer the data */ | |
208 | if (data->flags & MMC_DATA_READ) | |
209 | tmio_ioread16_rep(ctl + CTL_SD_DATA_PORT, buf, count >> 1); | |
210 | else | |
211 | tmio_iowrite16_rep(ctl + CTL_SD_DATA_PORT, buf, count >> 1); | |
212 | ||
213 | host->sg_off += count; | |
214 | ||
215 | tmio_mmc_kunmap_atomic(host, &flags); | |
216 | ||
217 | if (host->sg_off == host->sg_ptr->length) | |
218 | tmio_mmc_next_sg(host); | |
219 | ||
220 | return; | |
221 | } | |
222 | ||
223 | static inline void tmio_mmc_data_irq(struct tmio_mmc_host *host) | |
224 | { | |
225 | void __iomem *ctl = host->ctl; | |
226 | struct mmc_data *data = host->data; | |
a0d045ca | 227 | struct mmc_command *stop; |
4a48998f IM |
228 | |
229 | host->data = NULL; | |
230 | ||
231 | if (!data) { | |
232 | pr_debug("Spurious data end IRQ\n"); | |
233 | return; | |
234 | } | |
a0d045ca | 235 | stop = data->stop; |
4a48998f IM |
236 | |
237 | /* FIXME - return correct transfer count on errors */ | |
238 | if (!data->error) | |
239 | data->bytes_xfered = data->blocks * data->blksz; | |
240 | else | |
241 | data->bytes_xfered = 0; | |
242 | ||
243 | pr_debug("Completed data request\n"); | |
244 | ||
245 | /*FIXME - other drivers allow an optional stop command of any given type | |
246 | * which we dont do, as the chip can auto generate them. | |
247 | * Perhaps we can be smarter about when to use auto CMD12 and | |
248 | * only issue the auto request when we know this is the desired | |
249 | * stop command, allowing fallback to the stop command the | |
250 | * upper layers expect. For now, we do what works. | |
251 | */ | |
252 | ||
253 | if (data->flags & MMC_DATA_READ) | |
254 | disable_mmc_irqs(ctl, TMIO_MASK_READOP); | |
255 | else | |
256 | disable_mmc_irqs(ctl, TMIO_MASK_WRITEOP); | |
257 | ||
258 | if (stop) { | |
259 | if (stop->opcode == 12 && !stop->arg) | |
260 | tmio_iowrite16(0x000, ctl + CTL_STOP_INTERNAL_ACTION); | |
261 | else | |
262 | BUG(); | |
263 | } | |
264 | ||
265 | tmio_mmc_finish_request(host); | |
266 | } | |
267 | ||
268 | static inline void tmio_mmc_cmd_irq(struct tmio_mmc_host *host, | |
269 | unsigned int stat) | |
270 | { | |
271 | void __iomem *ctl = host->ctl, *addr; | |
272 | struct mmc_command *cmd = host->cmd; | |
273 | int i; | |
274 | ||
275 | if (!host->cmd) { | |
276 | pr_debug("Spurious CMD irq\n"); | |
277 | return; | |
278 | } | |
279 | ||
280 | host->cmd = NULL; | |
281 | ||
282 | /* This controller is sicker than the PXA one. Not only do we need to | |
283 | * drop the top 8 bits of the first response word, we also need to | |
284 | * modify the order of the response for short response command types. | |
285 | */ | |
286 | ||
287 | for (i = 3, addr = ctl + CTL_RESPONSE ; i >= 0 ; i--, addr += 4) | |
288 | cmd->resp[i] = tmio_ioread32(addr); | |
289 | ||
290 | if (cmd->flags & MMC_RSP_136) { | |
291 | cmd->resp[0] = (cmd->resp[0] << 8) | (cmd->resp[1] >> 24); | |
292 | cmd->resp[1] = (cmd->resp[1] << 8) | (cmd->resp[2] >> 24); | |
293 | cmd->resp[2] = (cmd->resp[2] << 8) | (cmd->resp[3] >> 24); | |
294 | cmd->resp[3] <<= 8; | |
295 | } else if (cmd->flags & MMC_RSP_R3) { | |
296 | cmd->resp[0] = cmd->resp[3]; | |
297 | } | |
298 | ||
299 | if (stat & TMIO_STAT_CMDTIMEOUT) | |
300 | cmd->error = -ETIMEDOUT; | |
301 | else if (stat & TMIO_STAT_CRCFAIL && cmd->flags & MMC_RSP_CRC) | |
302 | cmd->error = -EILSEQ; | |
303 | ||
304 | /* If there is data to handle we enable data IRQs here, and | |
305 | * we will ultimatley finish the request in the data_end handler. | |
306 | * If theres no data or we encountered an error, finish now. | |
307 | */ | |
308 | if (host->data && !cmd->error) { | |
309 | if (host->data->flags & MMC_DATA_READ) | |
310 | enable_mmc_irqs(ctl, TMIO_MASK_READOP); | |
311 | else | |
312 | enable_mmc_irqs(ctl, TMIO_MASK_WRITEOP); | |
313 | } else { | |
314 | tmio_mmc_finish_request(host); | |
315 | } | |
316 | ||
317 | return; | |
318 | } | |
319 | ||
320 | ||
321 | static irqreturn_t tmio_mmc_irq(int irq, void *devid) | |
322 | { | |
323 | struct tmio_mmc_host *host = devid; | |
324 | void __iomem *ctl = host->ctl; | |
325 | unsigned int ireg, irq_mask, status; | |
326 | ||
327 | pr_debug("MMC IRQ begin\n"); | |
328 | ||
329 | status = tmio_ioread32(ctl + CTL_STATUS); | |
330 | irq_mask = tmio_ioread32(ctl + CTL_IRQ_MASK); | |
331 | ireg = status & TMIO_MASK_IRQ & ~irq_mask; | |
332 | ||
333 | pr_debug_status(status); | |
334 | pr_debug_status(ireg); | |
335 | ||
336 | if (!ireg) { | |
337 | disable_mmc_irqs(ctl, status & ~irq_mask); | |
338 | ||
339 | pr_debug("tmio_mmc: Spurious irq, disabling! " | |
340 | "0x%08x 0x%08x 0x%08x\n", status, irq_mask, ireg); | |
341 | pr_debug_status(status); | |
342 | ||
343 | goto out; | |
344 | } | |
345 | ||
346 | while (ireg) { | |
347 | /* Card insert / remove attempts */ | |
348 | if (ireg & (TMIO_STAT_CARD_INSERT | TMIO_STAT_CARD_REMOVE)) { | |
349 | ack_mmc_irqs(ctl, TMIO_STAT_CARD_INSERT | | |
350 | TMIO_STAT_CARD_REMOVE); | |
351 | mmc_detect_change(host->mmc, 0); | |
352 | } | |
353 | ||
354 | /* CRC and other errors */ | |
355 | /* if (ireg & TMIO_STAT_ERR_IRQ) | |
356 | * handled |= tmio_error_irq(host, irq, stat); | |
357 | */ | |
358 | ||
359 | /* Command completion */ | |
360 | if (ireg & TMIO_MASK_CMD) { | |
361 | ack_mmc_irqs(ctl, TMIO_MASK_CMD); | |
362 | tmio_mmc_cmd_irq(host, status); | |
363 | } | |
364 | ||
365 | /* Data transfer */ | |
366 | if (ireg & (TMIO_STAT_RXRDY | TMIO_STAT_TXRQ)) { | |
367 | ack_mmc_irqs(ctl, TMIO_STAT_RXRDY | TMIO_STAT_TXRQ); | |
368 | tmio_mmc_pio_irq(host); | |
369 | } | |
370 | ||
371 | /* Data transfer completion */ | |
372 | if (ireg & TMIO_STAT_DATAEND) { | |
373 | ack_mmc_irqs(ctl, TMIO_STAT_DATAEND); | |
374 | tmio_mmc_data_irq(host); | |
375 | } | |
376 | ||
377 | /* Check status - keep going until we've handled it all */ | |
378 | status = tmio_ioread32(ctl + CTL_STATUS); | |
379 | irq_mask = tmio_ioread32(ctl + CTL_IRQ_MASK); | |
380 | ireg = status & TMIO_MASK_IRQ & ~irq_mask; | |
381 | ||
382 | pr_debug("Status at end of loop: %08x\n", status); | |
383 | pr_debug_status(status); | |
384 | } | |
385 | pr_debug("MMC IRQ end\n"); | |
386 | ||
387 | out: | |
388 | return IRQ_HANDLED; | |
389 | } | |
390 | ||
391 | static int tmio_mmc_start_data(struct tmio_mmc_host *host, | |
392 | struct mmc_data *data) | |
393 | { | |
394 | void __iomem *ctl = host->ctl; | |
395 | ||
396 | pr_debug("setup data transfer: blocksize %08x nr_blocks %d\n", | |
397 | data->blksz, data->blocks); | |
398 | ||
399 | /* Hardware cannot perform 1 and 2 byte requests in 4 bit mode */ | |
400 | if (data->blksz < 4 && host->mmc->ios.bus_width == MMC_BUS_WIDTH_4) { | |
401 | printk(KERN_ERR "%s: %d byte block unsupported in 4 bit mode\n", | |
402 | mmc_hostname(host->mmc), data->blksz); | |
403 | return -EINVAL; | |
404 | } | |
405 | ||
406 | tmio_mmc_init_sg(host, data); | |
407 | host->data = data; | |
408 | ||
409 | /* Set transfer length / blocksize */ | |
410 | tmio_iowrite16(data->blksz, ctl + CTL_SD_XFER_LEN); | |
411 | tmio_iowrite16(data->blocks, ctl + CTL_XFER_BLK_COUNT); | |
412 | ||
413 | return 0; | |
414 | } | |
415 | ||
416 | /* Process requests from the MMC layer */ | |
417 | static void tmio_mmc_request(struct mmc_host *mmc, struct mmc_request *mrq) | |
418 | { | |
419 | struct tmio_mmc_host *host = mmc_priv(mmc); | |
420 | int ret; | |
421 | ||
422 | if (host->mrq) | |
423 | pr_debug("request not null\n"); | |
424 | ||
425 | host->mrq = mrq; | |
426 | ||
427 | if (mrq->data) { | |
428 | ret = tmio_mmc_start_data(host, mrq->data); | |
429 | if (ret) | |
430 | goto fail; | |
431 | } | |
432 | ||
433 | ret = tmio_mmc_start_command(host, mrq->cmd); | |
434 | ||
435 | if (!ret) | |
436 | return; | |
437 | ||
438 | fail: | |
439 | mrq->cmd->error = ret; | |
440 | mmc_request_done(mmc, mrq); | |
441 | } | |
442 | ||
443 | /* Set MMC clock / power. | |
444 | * Note: This controller uses a simple divider scheme therefore it cannot | |
445 | * run a MMC card at full speed (20MHz). The max clock is 24MHz on SD, but as | |
446 | * MMC wont run that fast, it has to be clocked at 12MHz which is the next | |
447 | * slowest setting. | |
448 | */ | |
449 | static void tmio_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) | |
450 | { | |
451 | struct tmio_mmc_host *host = mmc_priv(mmc); | |
452 | void __iomem *cnf = host->cnf; | |
453 | void __iomem *ctl = host->ctl; | |
454 | ||
455 | if (ios->clock) | |
456 | tmio_mmc_set_clock(host, ios->clock); | |
457 | ||
458 | /* Power sequence - OFF -> ON -> UP */ | |
459 | switch (ios->power_mode) { | |
460 | case MMC_POWER_OFF: /* power down SD bus */ | |
461 | tmio_iowrite8(0x00, cnf + CNF_PWR_CTL_2); | |
462 | tmio_mmc_clk_stop(host); | |
463 | break; | |
464 | case MMC_POWER_ON: /* power up SD bus */ | |
465 | ||
466 | tmio_iowrite8(0x02, cnf + CNF_PWR_CTL_2); | |
467 | break; | |
468 | case MMC_POWER_UP: /* start bus clock */ | |
469 | tmio_mmc_clk_start(host); | |
470 | break; | |
471 | } | |
472 | ||
473 | switch (ios->bus_width) { | |
474 | case MMC_BUS_WIDTH_1: | |
475 | tmio_iowrite16(0x80e0, ctl + CTL_SD_MEM_CARD_OPT); | |
476 | break; | |
477 | case MMC_BUS_WIDTH_4: | |
478 | tmio_iowrite16(0x00e0, ctl + CTL_SD_MEM_CARD_OPT); | |
479 | break; | |
480 | } | |
481 | ||
482 | /* Let things settle. delay taken from winCE driver */ | |
483 | udelay(140); | |
484 | } | |
485 | ||
486 | static int tmio_mmc_get_ro(struct mmc_host *mmc) | |
487 | { | |
488 | struct tmio_mmc_host *host = mmc_priv(mmc); | |
489 | void __iomem *ctl = host->ctl; | |
490 | ||
491 | return (tmio_ioread16(ctl + CTL_STATUS) & TMIO_STAT_WRPROTECT) ? 0 : 1; | |
492 | } | |
493 | ||
494 | static struct mmc_host_ops tmio_mmc_ops = { | |
495 | .request = tmio_mmc_request, | |
496 | .set_ios = tmio_mmc_set_ios, | |
497 | .get_ro = tmio_mmc_get_ro, | |
498 | }; | |
499 | ||
500 | #ifdef CONFIG_PM | |
501 | static int tmio_mmc_suspend(struct platform_device *dev, pm_message_t state) | |
502 | { | |
503 | struct mfd_cell *cell = (struct mfd_cell *)dev->dev.platform_data; | |
504 | struct mmc_host *mmc = platform_get_drvdata(dev); | |
505 | int ret; | |
506 | ||
507 | ret = mmc_suspend_host(mmc, state); | |
508 | ||
509 | /* Tell MFD core it can disable us now.*/ | |
510 | if (!ret && cell->disable) | |
511 | cell->disable(dev); | |
512 | ||
513 | return ret; | |
514 | } | |
515 | ||
516 | static int tmio_mmc_resume(struct platform_device *dev) | |
517 | { | |
518 | struct mfd_cell *cell = (struct mfd_cell *)dev->dev.platform_data; | |
519 | struct mmc_host *mmc = platform_get_drvdata(dev); | |
520 | struct tmio_mmc_host *host = mmc_priv(mmc); | |
521 | void __iomem *cnf = host->cnf; | |
522 | int ret = 0; | |
523 | ||
524 | /* Enable the MMC/SD Control registers */ | |
525 | tmio_iowrite16(SDCREN, cnf + CNF_CMD); | |
526 | tmio_iowrite32(dev->resource[0].start & 0xfffe, cnf + CNF_CTL_BASE); | |
527 | ||
528 | /* Tell the MFD core we are ready to be enabled */ | |
529 | if (cell->enable) { | |
530 | ret = cell->enable(dev); | |
531 | if (ret) | |
532 | goto out; | |
533 | } | |
534 | ||
535 | mmc_resume_host(mmc); | |
536 | ||
537 | out: | |
538 | return ret; | |
539 | } | |
540 | #else | |
541 | #define tmio_mmc_suspend NULL | |
542 | #define tmio_mmc_resume NULL | |
543 | #endif | |
544 | ||
545 | static int __devinit tmio_mmc_probe(struct platform_device *dev) | |
546 | { | |
547 | struct mfd_cell *cell = (struct mfd_cell *)dev->dev.platform_data; | |
548 | struct resource *res_ctl, *res_cnf; | |
549 | struct tmio_mmc_host *host; | |
550 | struct mmc_host *mmc; | |
551 | int ret = -ENOMEM; | |
552 | ||
553 | if (dev->num_resources != 3) | |
554 | goto out; | |
555 | ||
556 | res_ctl = platform_get_resource(dev, IORESOURCE_MEM, 0); | |
557 | res_cnf = platform_get_resource(dev, IORESOURCE_MEM, 1); | |
558 | if (!res_ctl || !res_cnf) { | |
559 | ret = -EINVAL; | |
560 | goto out; | |
561 | } | |
562 | ||
563 | mmc = mmc_alloc_host(sizeof(struct tmio_mmc_host), &dev->dev); | |
564 | if (!mmc) | |
565 | goto out; | |
566 | ||
567 | host = mmc_priv(mmc); | |
568 | host->mmc = mmc; | |
569 | platform_set_drvdata(dev, mmc); | |
570 | ||
571 | host->ctl = ioremap(res_ctl->start, res_ctl->end - res_ctl->start); | |
572 | if (!host->ctl) | |
573 | goto host_free; | |
574 | ||
575 | host->cnf = ioremap(res_cnf->start, res_cnf->end - res_cnf->start); | |
576 | if (!host->cnf) | |
577 | goto unmap_ctl; | |
578 | ||
579 | mmc->ops = &tmio_mmc_ops; | |
580 | mmc->caps = MMC_CAP_4_BIT_DATA; | |
581 | mmc->f_min = 46875; /* 24000000 / 512 */ | |
582 | mmc->f_max = 24000000; | |
583 | mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34; | |
584 | ||
585 | /* Enable the MMC/SD Control registers */ | |
586 | tmio_iowrite16(SDCREN, host->cnf + CNF_CMD); | |
587 | tmio_iowrite32(dev->resource[0].start & 0xfffe, | |
588 | host->cnf + CNF_CTL_BASE); | |
589 | ||
590 | /* Tell the MFD core we are ready to be enabled */ | |
591 | if (cell->enable) { | |
592 | ret = cell->enable(dev); | |
593 | if (ret) | |
594 | goto unmap_cnf; | |
595 | } | |
596 | ||
597 | /* Disable SD power during suspend */ | |
598 | tmio_iowrite8(0x01, host->cnf + CNF_PWR_CTL_3); | |
599 | ||
600 | /* The below is required but why? FIXME */ | |
601 | tmio_iowrite8(0x1f, host->cnf + CNF_STOP_CLK_CTL); | |
602 | ||
603 | /* Power down SD bus*/ | |
604 | tmio_iowrite8(0x0, host->cnf + CNF_PWR_CTL_2); | |
605 | ||
606 | tmio_mmc_clk_stop(host); | |
607 | reset(host); | |
608 | ||
609 | ret = platform_get_irq(dev, 0); | |
610 | if (ret >= 0) | |
611 | host->irq = ret; | |
612 | else | |
613 | goto unmap_cnf; | |
614 | ||
615 | disable_mmc_irqs(host->ctl, TMIO_MASK_ALL); | |
616 | ||
617 | ret = request_irq(host->irq, tmio_mmc_irq, IRQF_DISABLED, "tmio-mmc", | |
618 | host); | |
619 | if (ret) | |
620 | goto unmap_cnf; | |
621 | ||
622 | set_irq_type(host->irq, IRQ_TYPE_EDGE_FALLING); | |
623 | ||
624 | mmc_add_host(mmc); | |
625 | ||
626 | printk(KERN_INFO "%s at 0x%08lx irq %d\n", mmc_hostname(host->mmc), | |
627 | (unsigned long)host->ctl, host->irq); | |
628 | ||
629 | /* Unmask the IRQs we want to know about */ | |
630 | enable_mmc_irqs(host->ctl, TMIO_MASK_IRQ); | |
631 | ||
632 | return 0; | |
633 | ||
634 | unmap_cnf: | |
635 | iounmap(host->cnf); | |
636 | unmap_ctl: | |
637 | iounmap(host->ctl); | |
638 | host_free: | |
639 | mmc_free_host(mmc); | |
640 | out: | |
641 | return ret; | |
642 | } | |
643 | ||
644 | static int __devexit tmio_mmc_remove(struct platform_device *dev) | |
645 | { | |
646 | struct mmc_host *mmc = platform_get_drvdata(dev); | |
647 | ||
648 | platform_set_drvdata(dev, NULL); | |
649 | ||
650 | if (mmc) { | |
651 | struct tmio_mmc_host *host = mmc_priv(mmc); | |
652 | mmc_remove_host(mmc); | |
653 | mmc_free_host(mmc); | |
654 | free_irq(host->irq, host); | |
655 | iounmap(host->ctl); | |
656 | iounmap(host->cnf); | |
657 | } | |
658 | ||
659 | return 0; | |
660 | } | |
661 | ||
662 | /* ------------------- device registration ----------------------- */ | |
663 | ||
664 | static struct platform_driver tmio_mmc_driver = { | |
665 | .driver = { | |
666 | .name = "tmio-mmc", | |
667 | .owner = THIS_MODULE, | |
668 | }, | |
669 | .probe = tmio_mmc_probe, | |
670 | .remove = __devexit_p(tmio_mmc_remove), | |
671 | .suspend = tmio_mmc_suspend, | |
672 | .resume = tmio_mmc_resume, | |
673 | }; | |
674 | ||
675 | ||
676 | static int __init tmio_mmc_init(void) | |
677 | { | |
678 | return platform_driver_register(&tmio_mmc_driver); | |
679 | } | |
680 | ||
681 | static void __exit tmio_mmc_exit(void) | |
682 | { | |
683 | platform_driver_unregister(&tmio_mmc_driver); | |
684 | } | |
685 | ||
686 | module_init(tmio_mmc_init); | |
687 | module_exit(tmio_mmc_exit); | |
688 | ||
689 | MODULE_DESCRIPTION("Toshiba TMIO SD/MMC driver"); | |
690 | MODULE_AUTHOR("Ian Molton <spyro@f2s.com>"); | |
691 | MODULE_LICENSE("GPL v2"); | |
692 | MODULE_ALIAS("platform:tmio-mmc"); |