diff options
Diffstat (limited to 'drivers/mmc/core')
-rw-r--r-- | drivers/mmc/core/Kconfig | 17 | ||||
-rw-r--r-- | drivers/mmc/core/Makefile | 11 | ||||
-rw-r--r-- | drivers/mmc/core/core.c | 727 | ||||
-rw-r--r-- | drivers/mmc/core/core.h | 70 | ||||
-rw-r--r-- | drivers/mmc/core/mmc.c | 537 | ||||
-rw-r--r-- | drivers/mmc/core/mmc_ops.c | 276 | ||||
-rw-r--r-- | drivers/mmc/core/mmc_ops.h | 27 | ||||
-rw-r--r-- | drivers/mmc/core/sd.c | 587 | ||||
-rw-r--r-- | drivers/mmc/core/sd_ops.c | 316 | ||||
-rw-r--r-- | drivers/mmc/core/sd_ops.h | 25 | ||||
-rw-r--r-- | drivers/mmc/core/sysfs.c | 360 | ||||
-rw-r--r-- | drivers/mmc/core/sysfs.h | 27 |
12 files changed, 2980 insertions, 0 deletions
diff --git a/drivers/mmc/core/Kconfig b/drivers/mmc/core/Kconfig new file mode 100644 index 000000000000..94222b9a15ea --- /dev/null +++ b/drivers/mmc/core/Kconfig | |||
@@ -0,0 +1,17 @@ | |||
1 | # | ||
2 | # MMC core configuration | ||
3 | # | ||
4 | |||
5 | config MMC_UNSAFE_RESUME | ||
6 | bool "Allow unsafe resume (DANGEROUS)" | ||
7 | depends on MMC != n | ||
8 | help | ||
9 | If you say Y here, the MMC layer will assume that all cards | ||
10 | stayed in their respective slots during the suspend. The | ||
11 | normal behaviour is to remove them at suspend and | ||
12 | redetecting them at resume. Breaking this assumption will | ||
13 | in most cases result in data corruption. | ||
14 | |||
15 | This option is usually just for embedded systems which use | ||
16 | a MMC/SD card for rootfs. Most people should say N here. | ||
17 | |||
diff --git a/drivers/mmc/core/Makefile b/drivers/mmc/core/Makefile new file mode 100644 index 000000000000..1075b02ae754 --- /dev/null +++ b/drivers/mmc/core/Makefile | |||
@@ -0,0 +1,11 @@ | |||
1 | # | ||
2 | # Makefile for the kernel mmc core. | ||
3 | # | ||
4 | |||
5 | ifeq ($(CONFIG_MMC_DEBUG),y) | ||
6 | EXTRA_CFLAGS += -DDEBUG | ||
7 | endif | ||
8 | |||
9 | obj-$(CONFIG_MMC) += mmc_core.o | ||
10 | mmc_core-y := core.o sysfs.o mmc.o mmc_ops.o sd.o sd_ops.o | ||
11 | |||
diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c new file mode 100644 index 000000000000..72c7cf4a9f9d --- /dev/null +++ b/drivers/mmc/core/core.c | |||
@@ -0,0 +1,727 @@ | |||
1 | /* | ||
2 | * linux/drivers/mmc/core/core.c | ||
3 | * | ||
4 | * Copyright (C) 2003-2004 Russell King, All Rights Reserved. | ||
5 | * SD support Copyright (C) 2004 Ian Molton, All Rights Reserved. | ||
6 | * Copyright (C) 2005-2007 Pierre Ossman, All Rights Reserved. | ||
7 | * MMCv4 support Copyright (C) 2006 Philip Langdale, All Rights Reserved. | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License version 2 as | ||
11 | * published by the Free Software Foundation. | ||
12 | */ | ||
13 | #include <linux/module.h> | ||
14 | #include <linux/init.h> | ||
15 | #include <linux/interrupt.h> | ||
16 | #include <linux/completion.h> | ||
17 | #include <linux/device.h> | ||
18 | #include <linux/delay.h> | ||
19 | #include <linux/pagemap.h> | ||
20 | #include <linux/err.h> | ||
21 | #include <asm/scatterlist.h> | ||
22 | #include <linux/scatterlist.h> | ||
23 | |||
24 | #include <linux/mmc/card.h> | ||
25 | #include <linux/mmc/host.h> | ||
26 | #include <linux/mmc/mmc.h> | ||
27 | #include <linux/mmc/sd.h> | ||
28 | |||
29 | #include "core.h" | ||
30 | #include "sysfs.h" | ||
31 | |||
32 | #include "mmc_ops.h" | ||
33 | #include "sd_ops.h" | ||
34 | |||
35 | extern int mmc_attach_mmc(struct mmc_host *host, u32 ocr); | ||
36 | extern int mmc_attach_sd(struct mmc_host *host, u32 ocr); | ||
37 | |||
38 | /** | ||
39 | * mmc_request_done - finish processing an MMC request | ||
40 | * @host: MMC host which completed request | ||
41 | * @mrq: MMC request which request | ||
42 | * | ||
43 | * MMC drivers should call this function when they have completed | ||
44 | * their processing of a request. | ||
45 | */ | ||
46 | void mmc_request_done(struct mmc_host *host, struct mmc_request *mrq) | ||
47 | { | ||
48 | struct mmc_command *cmd = mrq->cmd; | ||
49 | int err = cmd->error; | ||
50 | |||
51 | pr_debug("%s: req done (CMD%u): %d/%d/%d: %08x %08x %08x %08x\n", | ||
52 | mmc_hostname(host), cmd->opcode, err, | ||
53 | mrq->data ? mrq->data->error : 0, | ||
54 | mrq->stop ? mrq->stop->error : 0, | ||
55 | cmd->resp[0], cmd->resp[1], cmd->resp[2], cmd->resp[3]); | ||
56 | |||
57 | if (err && cmd->retries) { | ||
58 | cmd->retries--; | ||
59 | cmd->error = 0; | ||
60 | host->ops->request(host, mrq); | ||
61 | } else if (mrq->done) { | ||
62 | mrq->done(mrq); | ||
63 | } | ||
64 | } | ||
65 | |||
66 | EXPORT_SYMBOL(mmc_request_done); | ||
67 | |||
68 | /** | ||
69 | * mmc_start_request - start a command on a host | ||
70 | * @host: MMC host to start command on | ||
71 | * @mrq: MMC request to start | ||
72 | * | ||
73 | * Queue a command on the specified host. We expect the | ||
74 | * caller to be holding the host lock with interrupts disabled. | ||
75 | */ | ||
76 | void | ||
77 | mmc_start_request(struct mmc_host *host, struct mmc_request *mrq) | ||
78 | { | ||
79 | #ifdef CONFIG_MMC_DEBUG | ||
80 | unsigned int i, sz; | ||
81 | #endif | ||
82 | |||
83 | pr_debug("%s: starting CMD%u arg %08x flags %08x\n", | ||
84 | mmc_hostname(host), mrq->cmd->opcode, | ||
85 | mrq->cmd->arg, mrq->cmd->flags); | ||
86 | |||
87 | WARN_ON(!host->claimed); | ||
88 | |||
89 | mrq->cmd->error = 0; | ||
90 | mrq->cmd->mrq = mrq; | ||
91 | if (mrq->data) { | ||
92 | BUG_ON(mrq->data->blksz > host->max_blk_size); | ||
93 | BUG_ON(mrq->data->blocks > host->max_blk_count); | ||
94 | BUG_ON(mrq->data->blocks * mrq->data->blksz > | ||
95 | host->max_req_size); | ||
96 | |||
97 | #ifdef CONFIG_MMC_DEBUG | ||
98 | sz = 0; | ||
99 | for (i = 0;i < mrq->data->sg_len;i++) | ||
100 | sz += mrq->data->sg[i].length; | ||
101 | BUG_ON(sz != mrq->data->blocks * mrq->data->blksz); | ||
102 | #endif | ||
103 | |||
104 | mrq->cmd->data = mrq->data; | ||
105 | mrq->data->error = 0; | ||
106 | mrq->data->mrq = mrq; | ||
107 | if (mrq->stop) { | ||
108 | mrq->data->stop = mrq->stop; | ||
109 | mrq->stop->error = 0; | ||
110 | mrq->stop->mrq = mrq; | ||
111 | } | ||
112 | } | ||
113 | host->ops->request(host, mrq); | ||
114 | } | ||
115 | |||
116 | EXPORT_SYMBOL(mmc_start_request); | ||
117 | |||
118 | static void mmc_wait_done(struct mmc_request *mrq) | ||
119 | { | ||
120 | complete(mrq->done_data); | ||
121 | } | ||
122 | |||
123 | int mmc_wait_for_req(struct mmc_host *host, struct mmc_request *mrq) | ||
124 | { | ||
125 | DECLARE_COMPLETION_ONSTACK(complete); | ||
126 | |||
127 | mrq->done_data = &complete; | ||
128 | mrq->done = mmc_wait_done; | ||
129 | |||
130 | mmc_start_request(host, mrq); | ||
131 | |||
132 | wait_for_completion(&complete); | ||
133 | |||
134 | return 0; | ||
135 | } | ||
136 | |||
137 | EXPORT_SYMBOL(mmc_wait_for_req); | ||
138 | |||
139 | /** | ||
140 | * mmc_wait_for_cmd - start a command and wait for completion | ||
141 | * @host: MMC host to start command | ||
142 | * @cmd: MMC command to start | ||
143 | * @retries: maximum number of retries | ||
144 | * | ||
145 | * Start a new MMC command for a host, and wait for the command | ||
146 | * to complete. Return any error that occurred while the command | ||
147 | * was executing. Do not attempt to parse the response. | ||
148 | */ | ||
149 | int mmc_wait_for_cmd(struct mmc_host *host, struct mmc_command *cmd, int retries) | ||
150 | { | ||
151 | struct mmc_request mrq; | ||
152 | |||
153 | BUG_ON(!host->claimed); | ||
154 | |||
155 | memset(&mrq, 0, sizeof(struct mmc_request)); | ||
156 | |||
157 | memset(cmd->resp, 0, sizeof(cmd->resp)); | ||
158 | cmd->retries = retries; | ||
159 | |||
160 | mrq.cmd = cmd; | ||
161 | cmd->data = NULL; | ||
162 | |||
163 | mmc_wait_for_req(host, &mrq); | ||
164 | |||
165 | return cmd->error; | ||
166 | } | ||
167 | |||
168 | EXPORT_SYMBOL(mmc_wait_for_cmd); | ||
169 | |||
170 | /** | ||
171 | * mmc_set_data_timeout - set the timeout for a data command | ||
172 | * @data: data phase for command | ||
173 | * @card: the MMC card associated with the data transfer | ||
174 | * @write: flag to differentiate reads from writes | ||
175 | */ | ||
176 | void mmc_set_data_timeout(struct mmc_data *data, const struct mmc_card *card, | ||
177 | int write) | ||
178 | { | ||
179 | unsigned int mult; | ||
180 | |||
181 | /* | ||
182 | * SD cards use a 100 multiplier rather than 10 | ||
183 | */ | ||
184 | mult = mmc_card_sd(card) ? 100 : 10; | ||
185 | |||
186 | /* | ||
187 | * Scale up the multiplier (and therefore the timeout) by | ||
188 | * the r2w factor for writes. | ||
189 | */ | ||
190 | if (write) | ||
191 | mult <<= card->csd.r2w_factor; | ||
192 | |||
193 | data->timeout_ns = card->csd.tacc_ns * mult; | ||
194 | data->timeout_clks = card->csd.tacc_clks * mult; | ||
195 | |||
196 | /* | ||
197 | * SD cards also have an upper limit on the timeout. | ||
198 | */ | ||
199 | if (mmc_card_sd(card)) { | ||
200 | unsigned int timeout_us, limit_us; | ||
201 | |||
202 | timeout_us = data->timeout_ns / 1000; | ||
203 | timeout_us += data->timeout_clks * 1000 / | ||
204 | (card->host->ios.clock / 1000); | ||
205 | |||
206 | if (write) | ||
207 | limit_us = 250000; | ||
208 | else | ||
209 | limit_us = 100000; | ||
210 | |||
211 | /* | ||
212 | * SDHC cards always use these fixed values. | ||
213 | */ | ||
214 | if (timeout_us > limit_us || mmc_card_blockaddr(card)) { | ||
215 | data->timeout_ns = limit_us * 1000; | ||
216 | data->timeout_clks = 0; | ||
217 | } | ||
218 | } | ||
219 | } | ||
220 | EXPORT_SYMBOL(mmc_set_data_timeout); | ||
221 | |||
222 | /** | ||
223 | * __mmc_claim_host - exclusively claim a host | ||
224 | * @host: mmc host to claim | ||
225 | * @card: mmc card to claim host for | ||
226 | * | ||
227 | * Claim a host for a set of operations. If a valid card | ||
228 | * is passed and this wasn't the last card selected, select | ||
229 | * the card before returning. | ||
230 | * | ||
231 | * Note: you should use mmc_card_claim_host or mmc_claim_host. | ||
232 | */ | ||
233 | void mmc_claim_host(struct mmc_host *host) | ||
234 | { | ||
235 | DECLARE_WAITQUEUE(wait, current); | ||
236 | unsigned long flags; | ||
237 | |||
238 | add_wait_queue(&host->wq, &wait); | ||
239 | spin_lock_irqsave(&host->lock, flags); | ||
240 | while (1) { | ||
241 | set_current_state(TASK_UNINTERRUPTIBLE); | ||
242 | if (!host->claimed) | ||
243 | break; | ||
244 | spin_unlock_irqrestore(&host->lock, flags); | ||
245 | schedule(); | ||
246 | spin_lock_irqsave(&host->lock, flags); | ||
247 | } | ||
248 | set_current_state(TASK_RUNNING); | ||
249 | host->claimed = 1; | ||
250 | spin_unlock_irqrestore(&host->lock, flags); | ||
251 | remove_wait_queue(&host->wq, &wait); | ||
252 | } | ||
253 | |||
254 | EXPORT_SYMBOL(mmc_claim_host); | ||
255 | |||
256 | /** | ||
257 | * mmc_release_host - release a host | ||
258 | * @host: mmc host to release | ||
259 | * | ||
260 | * Release a MMC host, allowing others to claim the host | ||
261 | * for their operations. | ||
262 | */ | ||
263 | void mmc_release_host(struct mmc_host *host) | ||
264 | { | ||
265 | unsigned long flags; | ||
266 | |||
267 | BUG_ON(!host->claimed); | ||
268 | |||
269 | spin_lock_irqsave(&host->lock, flags); | ||
270 | host->claimed = 0; | ||
271 | spin_unlock_irqrestore(&host->lock, flags); | ||
272 | |||
273 | wake_up(&host->wq); | ||
274 | } | ||
275 | |||
276 | EXPORT_SYMBOL(mmc_release_host); | ||
277 | |||
278 | /* | ||
279 | * Internal function that does the actual ios call to the host driver, | ||
280 | * optionally printing some debug output. | ||
281 | */ | ||
282 | static inline void mmc_set_ios(struct mmc_host *host) | ||
283 | { | ||
284 | struct mmc_ios *ios = &host->ios; | ||
285 | |||
286 | pr_debug("%s: clock %uHz busmode %u powermode %u cs %u Vdd %u " | ||
287 | "width %u timing %u\n", | ||
288 | mmc_hostname(host), ios->clock, ios->bus_mode, | ||
289 | ios->power_mode, ios->chip_select, ios->vdd, | ||
290 | ios->bus_width, ios->timing); | ||
291 | |||
292 | host->ops->set_ios(host, ios); | ||
293 | } | ||
294 | |||
295 | /* | ||
296 | * Control chip select pin on a host. | ||
297 | */ | ||
298 | void mmc_set_chip_select(struct mmc_host *host, int mode) | ||
299 | { | ||
300 | host->ios.chip_select = mode; | ||
301 | mmc_set_ios(host); | ||
302 | } | ||
303 | |||
304 | /* | ||
305 | * Sets the host clock to the highest possible frequency that | ||
306 | * is below "hz". | ||
307 | */ | ||
308 | void mmc_set_clock(struct mmc_host *host, unsigned int hz) | ||
309 | { | ||
310 | WARN_ON(hz < host->f_min); | ||
311 | |||
312 | if (hz > host->f_max) | ||
313 | hz = host->f_max; | ||
314 | |||
315 | host->ios.clock = hz; | ||
316 | mmc_set_ios(host); | ||
317 | } | ||
318 | |||
319 | /* | ||
320 | * Change the bus mode (open drain/push-pull) of a host. | ||
321 | */ | ||
322 | void mmc_set_bus_mode(struct mmc_host *host, unsigned int mode) | ||
323 | { | ||
324 | host->ios.bus_mode = mode; | ||
325 | mmc_set_ios(host); | ||
326 | } | ||
327 | |||
328 | /* | ||
329 | * Change data bus width of a host. | ||
330 | */ | ||
331 | void mmc_set_bus_width(struct mmc_host *host, unsigned int width) | ||
332 | { | ||
333 | host->ios.bus_width = width; | ||
334 | mmc_set_ios(host); | ||
335 | } | ||
336 | |||
337 | /* | ||
338 | * Mask off any voltages we don't support and select | ||
339 | * the lowest voltage | ||
340 | */ | ||
341 | u32 mmc_select_voltage(struct mmc_host *host, u32 ocr) | ||
342 | { | ||
343 | int bit; | ||
344 | |||
345 | ocr &= host->ocr_avail; | ||
346 | |||
347 | bit = ffs(ocr); | ||
348 | if (bit) { | ||
349 | bit -= 1; | ||
350 | |||
351 | ocr &= 3 << bit; | ||
352 | |||
353 | host->ios.vdd = bit; | ||
354 | mmc_set_ios(host); | ||
355 | } else { | ||
356 | ocr = 0; | ||
357 | } | ||
358 | |||
359 | return ocr; | ||
360 | } | ||
361 | |||
362 | /* | ||
363 | * Select timing parameters for host. | ||
364 | */ | ||
365 | void mmc_set_timing(struct mmc_host *host, unsigned int timing) | ||
366 | { | ||
367 | host->ios.timing = timing; | ||
368 | mmc_set_ios(host); | ||
369 | } | ||
370 | |||
371 | /* | ||
372 | * Allocate a new MMC card | ||
373 | */ | ||
374 | struct mmc_card *mmc_alloc_card(struct mmc_host *host) | ||
375 | { | ||
376 | struct mmc_card *card; | ||
377 | |||
378 | card = kmalloc(sizeof(struct mmc_card), GFP_KERNEL); | ||
379 | if (!card) | ||
380 | return ERR_PTR(-ENOMEM); | ||
381 | |||
382 | mmc_init_card(card, host); | ||
383 | |||
384 | return card; | ||
385 | } | ||
386 | |||
387 | /* | ||
388 | * Apply power to the MMC stack. This is a two-stage process. | ||
389 | * First, we enable power to the card without the clock running. | ||
390 | * We then wait a bit for the power to stabilise. Finally, | ||
391 | * enable the bus drivers and clock to the card. | ||
392 | * | ||
393 | * We must _NOT_ enable the clock prior to power stablising. | ||
394 | * | ||
395 | * If a host does all the power sequencing itself, ignore the | ||
396 | * initial MMC_POWER_UP stage. | ||
397 | */ | ||
398 | static void mmc_power_up(struct mmc_host *host) | ||
399 | { | ||
400 | int bit = fls(host->ocr_avail) - 1; | ||
401 | |||
402 | host->ios.vdd = bit; | ||
403 | host->ios.bus_mode = MMC_BUSMODE_OPENDRAIN; | ||
404 | host->ios.chip_select = MMC_CS_DONTCARE; | ||
405 | host->ios.power_mode = MMC_POWER_UP; | ||
406 | host->ios.bus_width = MMC_BUS_WIDTH_1; | ||
407 | host->ios.timing = MMC_TIMING_LEGACY; | ||
408 | mmc_set_ios(host); | ||
409 | |||
410 | mmc_delay(1); | ||
411 | |||
412 | host->ios.clock = host->f_min; | ||
413 | host->ios.power_mode = MMC_POWER_ON; | ||
414 | mmc_set_ios(host); | ||
415 | |||
416 | mmc_delay(2); | ||
417 | } | ||
418 | |||
419 | static void mmc_power_off(struct mmc_host *host) | ||
420 | { | ||
421 | host->ios.clock = 0; | ||
422 | host->ios.vdd = 0; | ||
423 | host->ios.bus_mode = MMC_BUSMODE_OPENDRAIN; | ||
424 | host->ios.chip_select = MMC_CS_DONTCARE; | ||
425 | host->ios.power_mode = MMC_POWER_OFF; | ||
426 | host->ios.bus_width = MMC_BUS_WIDTH_1; | ||
427 | host->ios.timing = MMC_TIMING_LEGACY; | ||
428 | mmc_set_ios(host); | ||
429 | } | ||
430 | |||
431 | /* | ||
432 | * Assign a mmc bus handler to a host. Only one bus handler may control a | ||
433 | * host at any given time. | ||
434 | */ | ||
435 | void mmc_attach_bus(struct mmc_host *host, const struct mmc_bus_ops *ops) | ||
436 | { | ||
437 | unsigned long flags; | ||
438 | |||
439 | BUG_ON(!host); | ||
440 | BUG_ON(!ops); | ||
441 | |||
442 | BUG_ON(!host->claimed); | ||
443 | |||
444 | spin_lock_irqsave(&host->lock, flags); | ||
445 | |||
446 | BUG_ON(host->bus_ops); | ||
447 | BUG_ON(host->bus_refs); | ||
448 | |||
449 | host->bus_ops = ops; | ||
450 | host->bus_refs = 1; | ||
451 | host->bus_dead = 0; | ||
452 | |||
453 | spin_unlock_irqrestore(&host->lock, flags); | ||
454 | } | ||
455 | |||
456 | /* | ||
457 | * Remove the current bus handler from a host. Assumes that there are | ||
458 | * no interesting cards left, so the bus is powered down. | ||
459 | */ | ||
460 | void mmc_detach_bus(struct mmc_host *host) | ||
461 | { | ||
462 | unsigned long flags; | ||
463 | |||
464 | BUG_ON(!host); | ||
465 | |||
466 | BUG_ON(!host->claimed); | ||
467 | BUG_ON(!host->bus_ops); | ||
468 | |||
469 | spin_lock_irqsave(&host->lock, flags); | ||
470 | |||
471 | host->bus_dead = 1; | ||
472 | |||
473 | spin_unlock_irqrestore(&host->lock, flags); | ||
474 | |||
475 | mmc_power_off(host); | ||
476 | |||
477 | mmc_bus_put(host); | ||
478 | } | ||
479 | |||
480 | /* | ||
481 | * Cleanup when the last reference to the bus operator is dropped. | ||
482 | */ | ||
483 | void __mmc_release_bus(struct mmc_host *host) | ||
484 | { | ||
485 | BUG_ON(!host); | ||
486 | BUG_ON(host->bus_refs); | ||
487 | BUG_ON(!host->bus_dead); | ||
488 | |||
489 | host->bus_ops = NULL; | ||
490 | } | ||
491 | |||
492 | /** | ||
493 | * mmc_detect_change - process change of state on a MMC socket | ||
494 | * @host: host which changed state. | ||
495 | * @delay: optional delay to wait before detection (jiffies) | ||
496 | * | ||
497 | * All we know is that card(s) have been inserted or removed | ||
498 | * from the socket(s). We don't know which socket or cards. | ||
499 | */ | ||
500 | void mmc_detect_change(struct mmc_host *host, unsigned long delay) | ||
501 | { | ||
502 | #ifdef CONFIG_MMC_DEBUG | ||
503 | mmc_claim_host(host); | ||
504 | BUG_ON(host->removed); | ||
505 | mmc_release_host(host); | ||
506 | #endif | ||
507 | |||
508 | mmc_schedule_delayed_work(&host->detect, delay); | ||
509 | } | ||
510 | |||
511 | EXPORT_SYMBOL(mmc_detect_change); | ||
512 | |||
513 | |||
514 | static void mmc_rescan(struct work_struct *work) | ||
515 | { | ||
516 | struct mmc_host *host = | ||
517 | container_of(work, struct mmc_host, detect.work); | ||
518 | u32 ocr; | ||
519 | int err; | ||
520 | |||
521 | mmc_bus_get(host); | ||
522 | |||
523 | if (host->bus_ops == NULL) { | ||
524 | /* | ||
525 | * Only we can add a new handler, so it's safe to | ||
526 | * release the lock here. | ||
527 | */ | ||
528 | mmc_bus_put(host); | ||
529 | |||
530 | mmc_claim_host(host); | ||
531 | |||
532 | mmc_power_up(host); | ||
533 | mmc_go_idle(host); | ||
534 | |||
535 | mmc_send_if_cond(host, host->ocr_avail); | ||
536 | |||
537 | err = mmc_send_app_op_cond(host, 0, &ocr); | ||
538 | if (err == MMC_ERR_NONE) { | ||
539 | if (mmc_attach_sd(host, ocr)) | ||
540 | mmc_power_off(host); | ||
541 | } else { | ||
542 | /* | ||
543 | * If we fail to detect any SD cards then try | ||
544 | * searching for MMC cards. | ||
545 | */ | ||
546 | err = mmc_send_op_cond(host, 0, &ocr); | ||
547 | if (err == MMC_ERR_NONE) { | ||
548 | if (mmc_attach_mmc(host, ocr)) | ||
549 | mmc_power_off(host); | ||
550 | } else { | ||
551 | mmc_power_off(host); | ||
552 | mmc_release_host(host); | ||
553 | } | ||
554 | } | ||
555 | } else { | ||
556 | if (host->bus_ops->detect && !host->bus_dead) | ||
557 | host->bus_ops->detect(host); | ||
558 | |||
559 | mmc_bus_put(host); | ||
560 | } | ||
561 | } | ||
562 | |||
563 | |||
564 | /** | ||
565 | * mmc_alloc_host - initialise the per-host structure. | ||
566 | * @extra: sizeof private data structure | ||
567 | * @dev: pointer to host device model structure | ||
568 | * | ||
569 | * Initialise the per-host structure. | ||
570 | */ | ||
571 | struct mmc_host *mmc_alloc_host(int extra, struct device *dev) | ||
572 | { | ||
573 | struct mmc_host *host; | ||
574 | |||
575 | host = mmc_alloc_host_sysfs(extra, dev); | ||
576 | if (host) { | ||
577 | spin_lock_init(&host->lock); | ||
578 | init_waitqueue_head(&host->wq); | ||
579 | INIT_DELAYED_WORK(&host->detect, mmc_rescan); | ||
580 | |||
581 | /* | ||
582 | * By default, hosts do not support SGIO or large requests. | ||
583 | * They have to set these according to their abilities. | ||
584 | */ | ||
585 | host->max_hw_segs = 1; | ||
586 | host->max_phys_segs = 1; | ||
587 | host->max_seg_size = PAGE_CACHE_SIZE; | ||
588 | |||
589 | host->max_req_size = PAGE_CACHE_SIZE; | ||
590 | host->max_blk_size = 512; | ||
591 | host->max_blk_count = PAGE_CACHE_SIZE / 512; | ||
592 | } | ||
593 | |||
594 | return host; | ||
595 | } | ||
596 | |||
597 | EXPORT_SYMBOL(mmc_alloc_host); | ||
598 | |||
599 | /** | ||
600 | * mmc_add_host - initialise host hardware | ||
601 | * @host: mmc host | ||
602 | */ | ||
603 | int mmc_add_host(struct mmc_host *host) | ||
604 | { | ||
605 | int ret; | ||
606 | |||
607 | ret = mmc_add_host_sysfs(host); | ||
608 | if (ret == 0) { | ||
609 | mmc_power_off(host); | ||
610 | mmc_detect_change(host, 0); | ||
611 | } | ||
612 | |||
613 | return ret; | ||
614 | } | ||
615 | |||
616 | EXPORT_SYMBOL(mmc_add_host); | ||
617 | |||
618 | /** | ||
619 | * mmc_remove_host - remove host hardware | ||
620 | * @host: mmc host | ||
621 | * | ||
622 | * Unregister and remove all cards associated with this host, | ||
623 | * and power down the MMC bus. | ||
624 | */ | ||
625 | void mmc_remove_host(struct mmc_host *host) | ||
626 | { | ||
627 | #ifdef CONFIG_MMC_DEBUG | ||
628 | mmc_claim_host(host); | ||
629 | host->removed = 1; | ||
630 | mmc_release_host(host); | ||
631 | #endif | ||
632 | |||
633 | mmc_flush_scheduled_work(); | ||
634 | |||
635 | mmc_bus_get(host); | ||
636 | if (host->bus_ops && !host->bus_dead) { | ||
637 | if (host->bus_ops->remove) | ||
638 | host->bus_ops->remove(host); | ||
639 | |||
640 | mmc_claim_host(host); | ||
641 | mmc_detach_bus(host); | ||
642 | mmc_release_host(host); | ||
643 | } | ||
644 | mmc_bus_put(host); | ||
645 | |||
646 | BUG_ON(host->card); | ||
647 | |||
648 | mmc_power_off(host); | ||
649 | mmc_remove_host_sysfs(host); | ||
650 | } | ||
651 | |||
652 | EXPORT_SYMBOL(mmc_remove_host); | ||
653 | |||
654 | /** | ||
655 | * mmc_free_host - free the host structure | ||
656 | * @host: mmc host | ||
657 | * | ||
658 | * Free the host once all references to it have been dropped. | ||
659 | */ | ||
660 | void mmc_free_host(struct mmc_host *host) | ||
661 | { | ||
662 | mmc_free_host_sysfs(host); | ||
663 | } | ||
664 | |||
665 | EXPORT_SYMBOL(mmc_free_host); | ||
666 | |||
667 | #ifdef CONFIG_PM | ||
668 | |||
669 | /** | ||
670 | * mmc_suspend_host - suspend a host | ||
671 | * @host: mmc host | ||
672 | * @state: suspend mode (PM_SUSPEND_xxx) | ||
673 | */ | ||
674 | int mmc_suspend_host(struct mmc_host *host, pm_message_t state) | ||
675 | { | ||
676 | mmc_flush_scheduled_work(); | ||
677 | |||
678 | mmc_bus_get(host); | ||
679 | if (host->bus_ops && !host->bus_dead) { | ||
680 | if (host->bus_ops->suspend) | ||
681 | host->bus_ops->suspend(host); | ||
682 | if (!host->bus_ops->resume) { | ||
683 | if (host->bus_ops->remove) | ||
684 | host->bus_ops->remove(host); | ||
685 | |||
686 | mmc_claim_host(host); | ||
687 | mmc_detach_bus(host); | ||
688 | mmc_release_host(host); | ||
689 | } | ||
690 | } | ||
691 | mmc_bus_put(host); | ||
692 | |||
693 | mmc_power_off(host); | ||
694 | |||
695 | return 0; | ||
696 | } | ||
697 | |||
698 | EXPORT_SYMBOL(mmc_suspend_host); | ||
699 | |||
700 | /** | ||
701 | * mmc_resume_host - resume a previously suspended host | ||
702 | * @host: mmc host | ||
703 | */ | ||
704 | int mmc_resume_host(struct mmc_host *host) | ||
705 | { | ||
706 | mmc_bus_get(host); | ||
707 | if (host->bus_ops && !host->bus_dead) { | ||
708 | mmc_power_up(host); | ||
709 | BUG_ON(!host->bus_ops->resume); | ||
710 | host->bus_ops->resume(host); | ||
711 | } | ||
712 | mmc_bus_put(host); | ||
713 | |||
714 | /* | ||
715 | * We add a slight delay here so that resume can progress | ||
716 | * in parallel. | ||
717 | */ | ||
718 | mmc_detect_change(host, 1); | ||
719 | |||
720 | return 0; | ||
721 | } | ||
722 | |||
723 | EXPORT_SYMBOL(mmc_resume_host); | ||
724 | |||
725 | #endif | ||
726 | |||
727 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/mmc/core/core.h b/drivers/mmc/core/core.h new file mode 100644 index 000000000000..177264d090ac --- /dev/null +++ b/drivers/mmc/core/core.h | |||
@@ -0,0 +1,70 @@ | |||
1 | /* | ||
2 | * linux/drivers/mmc/core/core.h | ||
3 | * | ||
4 | * Copyright (C) 2003 Russell King, All Rights Reserved. | ||
5 | * Copyright 2007 Pierre Ossman | ||
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 | #ifndef _MMC_CORE_CORE_H | ||
12 | #define _MMC_CORE_CORE_H | ||
13 | |||
14 | #include <linux/delay.h> | ||
15 | |||
16 | #define MMC_CMD_RETRIES 3 | ||
17 | |||
18 | struct mmc_bus_ops { | ||
19 | void (*remove)(struct mmc_host *); | ||
20 | void (*detect)(struct mmc_host *); | ||
21 | void (*suspend)(struct mmc_host *); | ||
22 | void (*resume)(struct mmc_host *); | ||
23 | }; | ||
24 | |||
25 | void mmc_attach_bus(struct mmc_host *host, const struct mmc_bus_ops *ops); | ||
26 | void mmc_detach_bus(struct mmc_host *host); | ||
27 | |||
28 | void __mmc_release_bus(struct mmc_host *host); | ||
29 | |||
30 | static inline void mmc_bus_get(struct mmc_host *host) | ||
31 | { | ||
32 | unsigned long flags; | ||
33 | |||
34 | spin_lock_irqsave(&host->lock, flags); | ||
35 | host->bus_refs++; | ||
36 | spin_unlock_irqrestore(&host->lock, flags); | ||
37 | } | ||
38 | |||
39 | static inline void mmc_bus_put(struct mmc_host *host) | ||
40 | { | ||
41 | unsigned long flags; | ||
42 | |||
43 | spin_lock_irqsave(&host->lock, flags); | ||
44 | host->bus_refs--; | ||
45 | if ((host->bus_refs == 0) && host->bus_ops) | ||
46 | __mmc_release_bus(host); | ||
47 | spin_unlock_irqrestore(&host->lock, flags); | ||
48 | } | ||
49 | |||
50 | void mmc_set_chip_select(struct mmc_host *host, int mode); | ||
51 | void mmc_set_clock(struct mmc_host *host, unsigned int hz); | ||
52 | void mmc_set_bus_mode(struct mmc_host *host, unsigned int mode); | ||
53 | void mmc_set_bus_width(struct mmc_host *host, unsigned int width); | ||
54 | u32 mmc_select_voltage(struct mmc_host *host, u32 ocr); | ||
55 | void mmc_set_timing(struct mmc_host *host, unsigned int timing); | ||
56 | |||
57 | struct mmc_card *mmc_alloc_card(struct mmc_host *host); | ||
58 | |||
59 | static inline void mmc_delay(unsigned int ms) | ||
60 | { | ||
61 | if (ms < 1000 / HZ) { | ||
62 | cond_resched(); | ||
63 | mdelay(ms); | ||
64 | } else { | ||
65 | msleep(ms); | ||
66 | } | ||
67 | } | ||
68 | |||
69 | #endif | ||
70 | |||
diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c new file mode 100644 index 000000000000..42cc2867ed7d --- /dev/null +++ b/drivers/mmc/core/mmc.c | |||
@@ -0,0 +1,537 @@ | |||
1 | /* | ||
2 | * linux/drivers/mmc/mmc.c | ||
3 | * | ||
4 | * Copyright (C) 2003-2004 Russell King, All Rights Reserved. | ||
5 | * Copyright (C) 2005-2007 Pierre Ossman, All Rights Reserved. | ||
6 | * MMCv4 support Copyright (C) 2006 Philip Langdale, All Rights Reserved. | ||
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 version 2 as | ||
10 | * published by the Free Software Foundation. | ||
11 | */ | ||
12 | |||
13 | #include <linux/err.h> | ||
14 | |||
15 | #include <linux/mmc/host.h> | ||
16 | #include <linux/mmc/card.h> | ||
17 | #include <linux/mmc/mmc.h> | ||
18 | |||
19 | #include "core.h" | ||
20 | #include "sysfs.h" | ||
21 | #include "mmc_ops.h" | ||
22 | |||
23 | static const unsigned int tran_exp[] = { | ||
24 | 10000, 100000, 1000000, 10000000, | ||
25 | 0, 0, 0, 0 | ||
26 | }; | ||
27 | |||
28 | static const unsigned char tran_mant[] = { | ||
29 | 0, 10, 12, 13, 15, 20, 25, 30, | ||
30 | 35, 40, 45, 50, 55, 60, 70, 80, | ||
31 | }; | ||
32 | |||
33 | static const unsigned int tacc_exp[] = { | ||
34 | 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, | ||
35 | }; | ||
36 | |||
37 | static const unsigned int tacc_mant[] = { | ||
38 | 0, 10, 12, 13, 15, 20, 25, 30, | ||
39 | 35, 40, 45, 50, 55, 60, 70, 80, | ||
40 | }; | ||
41 | |||
42 | #define UNSTUFF_BITS(resp,start,size) \ | ||
43 | ({ \ | ||
44 | const int __size = size; \ | ||
45 | const u32 __mask = (__size < 32 ? 1 << __size : 0) - 1; \ | ||
46 | const int __off = 3 - ((start) / 32); \ | ||
47 | const int __shft = (start) & 31; \ | ||
48 | u32 __res; \ | ||
49 | \ | ||
50 | __res = resp[__off] >> __shft; \ | ||
51 | if (__size + __shft > 32) \ | ||
52 | __res |= resp[__off-1] << ((32 - __shft) % 32); \ | ||
53 | __res & __mask; \ | ||
54 | }) | ||
55 | |||
56 | /* | ||
57 | * Given the decoded CSD structure, decode the raw CID to our CID structure. | ||
58 | */ | ||
59 | static int mmc_decode_cid(struct mmc_card *card) | ||
60 | { | ||
61 | u32 *resp = card->raw_cid; | ||
62 | |||
63 | /* | ||
64 | * The selection of the format here is based upon published | ||
65 | * specs from sandisk and from what people have reported. | ||
66 | */ | ||
67 | switch (card->csd.mmca_vsn) { | ||
68 | case 0: /* MMC v1.0 - v1.2 */ | ||
69 | case 1: /* MMC v1.4 */ | ||
70 | card->cid.manfid = UNSTUFF_BITS(resp, 104, 24); | ||
71 | card->cid.prod_name[0] = UNSTUFF_BITS(resp, 96, 8); | ||
72 | card->cid.prod_name[1] = UNSTUFF_BITS(resp, 88, 8); | ||
73 | card->cid.prod_name[2] = UNSTUFF_BITS(resp, 80, 8); | ||
74 | card->cid.prod_name[3] = UNSTUFF_BITS(resp, 72, 8); | ||
75 | card->cid.prod_name[4] = UNSTUFF_BITS(resp, 64, 8); | ||
76 | card->cid.prod_name[5] = UNSTUFF_BITS(resp, 56, 8); | ||
77 | card->cid.prod_name[6] = UNSTUFF_BITS(resp, 48, 8); | ||
78 | card->cid.hwrev = UNSTUFF_BITS(resp, 44, 4); | ||
79 | card->cid.fwrev = UNSTUFF_BITS(resp, 40, 4); | ||
80 | card->cid.serial = UNSTUFF_BITS(resp, 16, 24); | ||
81 | card->cid.month = UNSTUFF_BITS(resp, 12, 4); | ||
82 | card->cid.year = UNSTUFF_BITS(resp, 8, 4) + 1997; | ||
83 | break; | ||
84 | |||
85 | case 2: /* MMC v2.0 - v2.2 */ | ||
86 | case 3: /* MMC v3.1 - v3.3 */ | ||
87 | case 4: /* MMC v4 */ | ||
88 | card->cid.manfid = UNSTUFF_BITS(resp, 120, 8); | ||
89 | card->cid.oemid = UNSTUFF_BITS(resp, 104, 16); | ||
90 | card->cid.prod_name[0] = UNSTUFF_BITS(resp, 96, 8); | ||
91 | card->cid.prod_name[1] = UNSTUFF_BITS(resp, 88, 8); | ||
92 | card->cid.prod_name[2] = UNSTUFF_BITS(resp, 80, 8); | ||
93 | card->cid.prod_name[3] = UNSTUFF_BITS(resp, 72, 8); | ||
94 | card->cid.prod_name[4] = UNSTUFF_BITS(resp, 64, 8); | ||
95 | card->cid.prod_name[5] = UNSTUFF_BITS(resp, 56, 8); | ||
96 | card->cid.serial = UNSTUFF_BITS(resp, 16, 32); | ||
97 | card->cid.month = UNSTUFF_BITS(resp, 12, 4); | ||
98 | card->cid.year = UNSTUFF_BITS(resp, 8, 4) + 1997; | ||
99 | break; | ||
100 | |||
101 | default: | ||
102 | printk("%s: card has unknown MMCA version %d\n", | ||
103 | mmc_hostname(card->host), card->csd.mmca_vsn); | ||
104 | return -EINVAL; | ||
105 | } | ||
106 | |||
107 | return 0; | ||
108 | } | ||
109 | |||
110 | /* | ||
111 | * Given a 128-bit response, decode to our card CSD structure. | ||
112 | */ | ||
113 | static int mmc_decode_csd(struct mmc_card *card) | ||
114 | { | ||
115 | struct mmc_csd *csd = &card->csd; | ||
116 | unsigned int e, m, csd_struct; | ||
117 | u32 *resp = card->raw_csd; | ||
118 | |||
119 | /* | ||
120 | * We only understand CSD structure v1.1 and v1.2. | ||
121 | * v1.2 has extra information in bits 15, 11 and 10. | ||
122 | */ | ||
123 | csd_struct = UNSTUFF_BITS(resp, 126, 2); | ||
124 | if (csd_struct != 1 && csd_struct != 2) { | ||
125 | printk("%s: unrecognised CSD structure version %d\n", | ||
126 | mmc_hostname(card->host), csd_struct); | ||
127 | return -EINVAL; | ||
128 | } | ||
129 | |||
130 | csd->mmca_vsn = UNSTUFF_BITS(resp, 122, 4); | ||
131 | m = UNSTUFF_BITS(resp, 115, 4); | ||
132 | e = UNSTUFF_BITS(resp, 112, 3); | ||
133 | csd->tacc_ns = (tacc_exp[e] * tacc_mant[m] + 9) / 10; | ||
134 | csd->tacc_clks = UNSTUFF_BITS(resp, 104, 8) * 100; | ||
135 | |||
136 | m = UNSTUFF_BITS(resp, 99, 4); | ||
137 | e = UNSTUFF_BITS(resp, 96, 3); | ||
138 | csd->max_dtr = tran_exp[e] * tran_mant[m]; | ||
139 | csd->cmdclass = UNSTUFF_BITS(resp, 84, 12); | ||
140 | |||
141 | e = UNSTUFF_BITS(resp, 47, 3); | ||
142 | m = UNSTUFF_BITS(resp, 62, 12); | ||
143 | csd->capacity = (1 + m) << (e + 2); | ||
144 | |||
145 | csd->read_blkbits = UNSTUFF_BITS(resp, 80, 4); | ||
146 | csd->read_partial = UNSTUFF_BITS(resp, 79, 1); | ||
147 | csd->write_misalign = UNSTUFF_BITS(resp, 78, 1); | ||
148 | csd->read_misalign = UNSTUFF_BITS(resp, 77, 1); | ||
149 | csd->r2w_factor = UNSTUFF_BITS(resp, 26, 3); | ||
150 | csd->write_blkbits = UNSTUFF_BITS(resp, 22, 4); | ||
151 | csd->write_partial = UNSTUFF_BITS(resp, 21, 1); | ||
152 | |||
153 | return 0; | ||
154 | } | ||
155 | |||
156 | /* | ||
157 | * Read and decode extended CSD. | ||
158 | */ | ||
159 | static int mmc_read_ext_csd(struct mmc_card *card) | ||
160 | { | ||
161 | int err; | ||
162 | u8 *ext_csd; | ||
163 | |||
164 | BUG_ON(!card); | ||
165 | |||
166 | err = MMC_ERR_FAILED; | ||
167 | |||
168 | if (card->csd.mmca_vsn < CSD_SPEC_VER_4) | ||
169 | return MMC_ERR_NONE; | ||
170 | |||
171 | /* | ||
172 | * As the ext_csd is so large and mostly unused, we don't store the | ||
173 | * raw block in mmc_card. | ||
174 | */ | ||
175 | ext_csd = kmalloc(512, GFP_KERNEL); | ||
176 | if (!ext_csd) { | ||
177 | printk(KERN_ERR "%s: could not allocate a buffer to " | ||
178 | "receive the ext_csd. mmc v4 cards will be " | ||
179 | "treated as v3.\n", mmc_hostname(card->host)); | ||
180 | return MMC_ERR_FAILED; | ||
181 | } | ||
182 | |||
183 | err = mmc_send_ext_csd(card, ext_csd); | ||
184 | if (err != MMC_ERR_NONE) { | ||
185 | /* | ||
186 | * High capacity cards should have this "magic" size | ||
187 | * stored in their CSD. | ||
188 | */ | ||
189 | if (card->csd.capacity == (4096 * 512)) { | ||
190 | printk(KERN_ERR "%s: unable to read EXT_CSD " | ||
191 | "on a possible high capacity card. " | ||
192 | "Card will be ignored.\n", | ||
193 | mmc_hostname(card->host)); | ||
194 | } else { | ||
195 | printk(KERN_WARNING "%s: unable to read " | ||
196 | "EXT_CSD, performance might " | ||
197 | "suffer.\n", | ||
198 | mmc_hostname(card->host)); | ||
199 | err = MMC_ERR_NONE; | ||
200 | } | ||
201 | goto out; | ||
202 | } | ||
203 | |||
204 | card->ext_csd.sectors = | ||
205 | ext_csd[EXT_CSD_SEC_CNT + 0] << 0 | | ||
206 | ext_csd[EXT_CSD_SEC_CNT + 1] << 8 | | ||
207 | ext_csd[EXT_CSD_SEC_CNT + 2] << 16 | | ||
208 | ext_csd[EXT_CSD_SEC_CNT + 3] << 24; | ||
209 | if (card->ext_csd.sectors) | ||
210 | mmc_card_set_blockaddr(card); | ||
211 | |||
212 | switch (ext_csd[EXT_CSD_CARD_TYPE]) { | ||
213 | case EXT_CSD_CARD_TYPE_52 | EXT_CSD_CARD_TYPE_26: | ||
214 | card->ext_csd.hs_max_dtr = 52000000; | ||
215 | break; | ||
216 | case EXT_CSD_CARD_TYPE_26: | ||
217 | card->ext_csd.hs_max_dtr = 26000000; | ||
218 | break; | ||
219 | default: | ||
220 | /* MMC v4 spec says this cannot happen */ | ||
221 | printk(KERN_WARNING "%s: card is mmc v4 but doesn't " | ||
222 | "support any high-speed modes.\n", | ||
223 | mmc_hostname(card->host)); | ||
224 | goto out; | ||
225 | } | ||
226 | |||
227 | out: | ||
228 | kfree(ext_csd); | ||
229 | |||
230 | return err; | ||
231 | } | ||
232 | |||
233 | /* | ||
234 | * Handle the detection and initialisation of a card. | ||
235 | * | ||
236 | * In the case of a resume, "curcard" will contain the card | ||
237 | * we're trying to reinitialise. | ||
238 | */ | ||
239 | static int mmc_sd_init_card(struct mmc_host *host, u32 ocr, | ||
240 | struct mmc_card *oldcard) | ||
241 | { | ||
242 | struct mmc_card *card; | ||
243 | int err; | ||
244 | u32 cid[4]; | ||
245 | unsigned int max_dtr; | ||
246 | |||
247 | BUG_ON(!host); | ||
248 | BUG_ON(!host->claimed); | ||
249 | |||
250 | /* | ||
251 | * Since we're changing the OCR value, we seem to | ||
252 | * need to tell some cards to go back to the idle | ||
253 | * state. We wait 1ms to give cards time to | ||
254 | * respond. | ||
255 | */ | ||
256 | mmc_go_idle(host); | ||
257 | |||
258 | /* The extra bit indicates that we support high capacity */ | ||
259 | err = mmc_send_op_cond(host, ocr | (1 << 30), NULL); | ||
260 | if (err != MMC_ERR_NONE) | ||
261 | goto err; | ||
262 | |||
263 | /* | ||
264 | * Fetch CID from card. | ||
265 | */ | ||
266 | err = mmc_all_send_cid(host, cid); | ||
267 | if (err != MMC_ERR_NONE) | ||
268 | goto err; | ||
269 | |||
270 | if (oldcard) { | ||
271 | if (memcmp(cid, oldcard->raw_cid, sizeof(cid)) != 0) | ||
272 | goto err; | ||
273 | |||
274 | card = oldcard; | ||
275 | } else { | ||
276 | /* | ||
277 | * Allocate card structure. | ||
278 | */ | ||
279 | card = mmc_alloc_card(host); | ||
280 | if (IS_ERR(card)) | ||
281 | goto err; | ||
282 | |||
283 | card->type = MMC_TYPE_MMC; | ||
284 | card->rca = 1; | ||
285 | memcpy(card->raw_cid, cid, sizeof(card->raw_cid)); | ||
286 | } | ||
287 | |||
288 | /* | ||
289 | * Set card RCA. | ||
290 | */ | ||
291 | err = mmc_set_relative_addr(card); | ||
292 | if (err != MMC_ERR_NONE) | ||
293 | goto free_card; | ||
294 | |||
295 | mmc_set_bus_mode(host, MMC_BUSMODE_PUSHPULL); | ||
296 | |||
297 | if (!oldcard) { | ||
298 | /* | ||
299 | * Fetch CSD from card. | ||
300 | */ | ||
301 | err = mmc_send_csd(card, card->raw_csd); | ||
302 | if (err != MMC_ERR_NONE) | ||
303 | goto free_card; | ||
304 | |||
305 | err = mmc_decode_csd(card); | ||
306 | if (err < 0) | ||
307 | goto free_card; | ||
308 | err = mmc_decode_cid(card); | ||
309 | if (err < 0) | ||
310 | goto free_card; | ||
311 | } | ||
312 | |||
313 | /* | ||
314 | * Select card, as all following commands rely on that. | ||
315 | */ | ||
316 | err = mmc_select_card(card); | ||
317 | if (err != MMC_ERR_NONE) | ||
318 | goto free_card; | ||
319 | |||
320 | if (!oldcard) { | ||
321 | /* | ||
322 | * Fetch and process extened CSD. | ||
323 | */ | ||
324 | err = mmc_read_ext_csd(card); | ||
325 | if (err != MMC_ERR_NONE) | ||
326 | goto free_card; | ||
327 | } | ||
328 | |||
329 | /* | ||
330 | * Activate high speed (if supported) | ||
331 | */ | ||
332 | if ((card->ext_csd.hs_max_dtr != 0) && | ||
333 | (host->caps & MMC_CAP_MMC_HIGHSPEED)) { | ||
334 | err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, | ||
335 | EXT_CSD_HS_TIMING, 1); | ||
336 | if (err != MMC_ERR_NONE) | ||
337 | goto free_card; | ||
338 | |||
339 | mmc_card_set_highspeed(card); | ||
340 | |||
341 | mmc_set_timing(card->host, MMC_TIMING_MMC_HS); | ||
342 | } | ||
343 | |||
344 | /* | ||
345 | * Compute bus speed. | ||
346 | */ | ||
347 | max_dtr = (unsigned int)-1; | ||
348 | |||
349 | if (mmc_card_highspeed(card)) { | ||
350 | if (max_dtr > card->ext_csd.hs_max_dtr) | ||
351 | max_dtr = card->ext_csd.hs_max_dtr; | ||
352 | } else if (max_dtr > card->csd.max_dtr) { | ||
353 | max_dtr = card->csd.max_dtr; | ||
354 | } | ||
355 | |||
356 | mmc_set_clock(host, max_dtr); | ||
357 | |||
358 | /* | ||
359 | * Activate wide bus (if supported). | ||
360 | */ | ||
361 | if ((card->csd.mmca_vsn >= CSD_SPEC_VER_4) && | ||
362 | (host->caps & MMC_CAP_4_BIT_DATA)) { | ||
363 | err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, | ||
364 | EXT_CSD_BUS_WIDTH, EXT_CSD_BUS_WIDTH_4); | ||
365 | if (err != MMC_ERR_NONE) | ||
366 | goto free_card; | ||
367 | |||
368 | mmc_set_bus_width(card->host, MMC_BUS_WIDTH_4); | ||
369 | } | ||
370 | |||
371 | if (!oldcard) | ||
372 | host->card = card; | ||
373 | |||
374 | return MMC_ERR_NONE; | ||
375 | |||
376 | free_card: | ||
377 | if (!oldcard) | ||
378 | mmc_remove_card(card); | ||
379 | err: | ||
380 | |||
381 | return MMC_ERR_FAILED; | ||
382 | } | ||
383 | |||
384 | /* | ||
385 | * Host is being removed. Free up the current card. | ||
386 | */ | ||
387 | static void mmc_remove(struct mmc_host *host) | ||
388 | { | ||
389 | BUG_ON(!host); | ||
390 | BUG_ON(!host->card); | ||
391 | |||
392 | mmc_remove_card(host->card); | ||
393 | host->card = NULL; | ||
394 | } | ||
395 | |||
396 | /* | ||
397 | * Card detection callback from host. | ||
398 | */ | ||
399 | static void mmc_detect(struct mmc_host *host) | ||
400 | { | ||
401 | int err; | ||
402 | |||
403 | BUG_ON(!host); | ||
404 | BUG_ON(!host->card); | ||
405 | |||
406 | mmc_claim_host(host); | ||
407 | |||
408 | /* | ||
409 | * Just check if our card has been removed. | ||
410 | */ | ||
411 | err = mmc_send_status(host->card, NULL); | ||
412 | |||
413 | mmc_release_host(host); | ||
414 | |||
415 | if (err != MMC_ERR_NONE) { | ||
416 | mmc_remove_card(host->card); | ||
417 | host->card = NULL; | ||
418 | |||
419 | mmc_claim_host(host); | ||
420 | mmc_detach_bus(host); | ||
421 | mmc_release_host(host); | ||
422 | } | ||
423 | } | ||
424 | |||
425 | #ifdef CONFIG_MMC_UNSAFE_RESUME | ||
426 | |||
427 | /* | ||
428 | * Suspend callback from host. | ||
429 | */ | ||
430 | static void mmc_suspend(struct mmc_host *host) | ||
431 | { | ||
432 | BUG_ON(!host); | ||
433 | BUG_ON(!host->card); | ||
434 | |||
435 | mmc_claim_host(host); | ||
436 | mmc_deselect_cards(host); | ||
437 | host->card->state &= ~MMC_STATE_HIGHSPEED; | ||
438 | mmc_release_host(host); | ||
439 | } | ||
440 | |||
441 | /* | ||
442 | * Resume callback from host. | ||
443 | * | ||
444 | * This function tries to determine if the same card is still present | ||
445 | * and, if so, restore all state to it. | ||
446 | */ | ||
447 | static void mmc_resume(struct mmc_host *host) | ||
448 | { | ||
449 | int err; | ||
450 | |||
451 | BUG_ON(!host); | ||
452 | BUG_ON(!host->card); | ||
453 | |||
454 | mmc_claim_host(host); | ||
455 | |||
456 | err = mmc_sd_init_card(host, host->ocr, host->card); | ||
457 | if (err != MMC_ERR_NONE) { | ||
458 | mmc_remove_card(host->card); | ||
459 | host->card = NULL; | ||
460 | |||
461 | mmc_detach_bus(host); | ||
462 | } | ||
463 | |||
464 | mmc_release_host(host); | ||
465 | } | ||
466 | |||
467 | #else | ||
468 | |||
469 | #define mmc_suspend NULL | ||
470 | #define mmc_resume NULL | ||
471 | |||
472 | #endif | ||
473 | |||
474 | static const struct mmc_bus_ops mmc_ops = { | ||
475 | .remove = mmc_remove, | ||
476 | .detect = mmc_detect, | ||
477 | .suspend = mmc_suspend, | ||
478 | .resume = mmc_resume, | ||
479 | }; | ||
480 | |||
481 | /* | ||
482 | * Starting point for MMC card init. | ||
483 | */ | ||
484 | int mmc_attach_mmc(struct mmc_host *host, u32 ocr) | ||
485 | { | ||
486 | int err; | ||
487 | |||
488 | BUG_ON(!host); | ||
489 | BUG_ON(!host->claimed); | ||
490 | |||
491 | mmc_attach_bus(host, &mmc_ops); | ||
492 | |||
493 | /* | ||
494 | * Sanity check the voltages that the card claims to | ||
495 | * support. | ||
496 | */ | ||
497 | if (ocr & 0x7F) { | ||
498 | printk(KERN_WARNING "%s: card claims to support voltages " | ||
499 | "below the defined range. These will be ignored.\n", | ||
500 | mmc_hostname(host)); | ||
501 | ocr &= ~0x7F; | ||
502 | } | ||
503 | |||
504 | host->ocr = mmc_select_voltage(host, ocr); | ||
505 | |||
506 | /* | ||
507 | * Can we support the voltage of the card? | ||
508 | */ | ||
509 | if (!host->ocr) | ||
510 | goto err; | ||
511 | |||
512 | /* | ||
513 | * Detect and init the card. | ||
514 | */ | ||
515 | err = mmc_sd_init_card(host, host->ocr, NULL); | ||
516 | if (err != MMC_ERR_NONE) | ||
517 | goto err; | ||
518 | |||
519 | mmc_release_host(host); | ||
520 | |||
521 | err = mmc_register_card(host->card); | ||
522 | if (err) | ||
523 | goto reclaim_host; | ||
524 | |||
525 | return 0; | ||
526 | |||
527 | reclaim_host: | ||
528 | mmc_claim_host(host); | ||
529 | mmc_remove_card(host->card); | ||
530 | host->card = NULL; | ||
531 | err: | ||
532 | mmc_detach_bus(host); | ||
533 | mmc_release_host(host); | ||
534 | |||
535 | return 0; | ||
536 | } | ||
537 | |||
diff --git a/drivers/mmc/core/mmc_ops.c b/drivers/mmc/core/mmc_ops.c new file mode 100644 index 000000000000..7dd720fa5895 --- /dev/null +++ b/drivers/mmc/core/mmc_ops.c | |||
@@ -0,0 +1,276 @@ | |||
1 | /* | ||
2 | * linux/drivers/mmc/mmc_ops.h | ||
3 | * | ||
4 | * Copyright 2006-2007 Pierre Ossman | ||
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 | #include <linux/types.h> | ||
13 | #include <asm/scatterlist.h> | ||
14 | #include <linux/scatterlist.h> | ||
15 | |||
16 | #include <linux/mmc/host.h> | ||
17 | #include <linux/mmc/card.h> | ||
18 | #include <linux/mmc/mmc.h> | ||
19 | |||
20 | #include "core.h" | ||
21 | #include "mmc_ops.h" | ||
22 | |||
23 | static int _mmc_select_card(struct mmc_host *host, struct mmc_card *card) | ||
24 | { | ||
25 | int err; | ||
26 | struct mmc_command cmd; | ||
27 | |||
28 | BUG_ON(!host); | ||
29 | |||
30 | memset(&cmd, 0, sizeof(struct mmc_command)); | ||
31 | |||
32 | cmd.opcode = MMC_SELECT_CARD; | ||
33 | |||
34 | if (card) { | ||
35 | cmd.arg = card->rca << 16; | ||
36 | cmd.flags = MMC_RSP_R1 | MMC_CMD_AC; | ||
37 | } else { | ||
38 | cmd.arg = 0; | ||
39 | cmd.flags = MMC_RSP_NONE | MMC_CMD_AC; | ||
40 | } | ||
41 | |||
42 | err = mmc_wait_for_cmd(host, &cmd, MMC_CMD_RETRIES); | ||
43 | if (err != MMC_ERR_NONE) | ||
44 | return err; | ||
45 | |||
46 | return MMC_ERR_NONE; | ||
47 | } | ||
48 | |||
49 | int mmc_select_card(struct mmc_card *card) | ||
50 | { | ||
51 | BUG_ON(!card); | ||
52 | |||
53 | return _mmc_select_card(card->host, card); | ||
54 | } | ||
55 | |||
56 | int mmc_deselect_cards(struct mmc_host *host) | ||
57 | { | ||
58 | return _mmc_select_card(host, NULL); | ||
59 | } | ||
60 | |||
61 | int mmc_go_idle(struct mmc_host *host) | ||
62 | { | ||
63 | int err; | ||
64 | struct mmc_command cmd; | ||
65 | |||
66 | mmc_set_chip_select(host, MMC_CS_HIGH); | ||
67 | |||
68 | mmc_delay(1); | ||
69 | |||
70 | memset(&cmd, 0, sizeof(struct mmc_command)); | ||
71 | |||
72 | cmd.opcode = MMC_GO_IDLE_STATE; | ||
73 | cmd.arg = 0; | ||
74 | cmd.flags = MMC_RSP_NONE | MMC_CMD_BC; | ||
75 | |||
76 | err = mmc_wait_for_cmd(host, &cmd, 0); | ||
77 | |||
78 | mmc_delay(1); | ||
79 | |||
80 | mmc_set_chip_select(host, MMC_CS_DONTCARE); | ||
81 | |||
82 | mmc_delay(1); | ||
83 | |||
84 | return err; | ||
85 | } | ||
86 | |||
87 | int mmc_send_op_cond(struct mmc_host *host, u32 ocr, u32 *rocr) | ||
88 | { | ||
89 | struct mmc_command cmd; | ||
90 | int i, err = 0; | ||
91 | |||
92 | BUG_ON(!host); | ||
93 | |||
94 | memset(&cmd, 0, sizeof(struct mmc_command)); | ||
95 | |||
96 | cmd.opcode = MMC_SEND_OP_COND; | ||
97 | cmd.arg = ocr; | ||
98 | cmd.flags = MMC_RSP_R3 | MMC_CMD_BCR; | ||
99 | |||
100 | for (i = 100; i; i--) { | ||
101 | err = mmc_wait_for_cmd(host, &cmd, 0); | ||
102 | if (err != MMC_ERR_NONE) | ||
103 | break; | ||
104 | |||
105 | if (cmd.resp[0] & MMC_CARD_BUSY || ocr == 0) | ||
106 | break; | ||
107 | |||
108 | err = MMC_ERR_TIMEOUT; | ||
109 | |||
110 | mmc_delay(10); | ||
111 | } | ||
112 | |||
113 | if (rocr) | ||
114 | *rocr = cmd.resp[0]; | ||
115 | |||
116 | return err; | ||
117 | } | ||
118 | |||
119 | int mmc_all_send_cid(struct mmc_host *host, u32 *cid) | ||
120 | { | ||
121 | int err; | ||
122 | struct mmc_command cmd; | ||
123 | |||
124 | BUG_ON(!host); | ||
125 | BUG_ON(!cid); | ||
126 | |||
127 | memset(&cmd, 0, sizeof(struct mmc_command)); | ||
128 | |||
129 | cmd.opcode = MMC_ALL_SEND_CID; | ||
130 | cmd.arg = 0; | ||
131 | cmd.flags = MMC_RSP_R2 | MMC_CMD_BCR; | ||
132 | |||
133 | err = mmc_wait_for_cmd(host, &cmd, MMC_CMD_RETRIES); | ||
134 | if (err != MMC_ERR_NONE) | ||
135 | return err; | ||
136 | |||
137 | memcpy(cid, cmd.resp, sizeof(u32) * 4); | ||
138 | |||
139 | return MMC_ERR_NONE; | ||
140 | } | ||
141 | |||
142 | int mmc_set_relative_addr(struct mmc_card *card) | ||
143 | { | ||
144 | int err; | ||
145 | struct mmc_command cmd; | ||
146 | |||
147 | BUG_ON(!card); | ||
148 | BUG_ON(!card->host); | ||
149 | |||
150 | memset(&cmd, 0, sizeof(struct mmc_command)); | ||
151 | |||
152 | cmd.opcode = MMC_SET_RELATIVE_ADDR; | ||
153 | cmd.arg = card->rca << 16; | ||
154 | cmd.flags = MMC_RSP_R1 | MMC_CMD_AC; | ||
155 | |||
156 | err = mmc_wait_for_cmd(card->host, &cmd, MMC_CMD_RETRIES); | ||
157 | if (err != MMC_ERR_NONE) | ||
158 | return err; | ||
159 | |||
160 | return MMC_ERR_NONE; | ||
161 | } | ||
162 | |||
163 | int mmc_send_csd(struct mmc_card *card, u32 *csd) | ||
164 | { | ||
165 | int err; | ||
166 | struct mmc_command cmd; | ||
167 | |||
168 | BUG_ON(!card); | ||
169 | BUG_ON(!card->host); | ||
170 | BUG_ON(!csd); | ||
171 | |||
172 | memset(&cmd, 0, sizeof(struct mmc_command)); | ||
173 | |||
174 | cmd.opcode = MMC_SEND_CSD; | ||
175 | cmd.arg = card->rca << 16; | ||
176 | cmd.flags = MMC_RSP_R2 | MMC_CMD_AC; | ||
177 | |||
178 | err = mmc_wait_for_cmd(card->host, &cmd, MMC_CMD_RETRIES); | ||
179 | if (err != MMC_ERR_NONE) | ||
180 | return err; | ||
181 | |||
182 | memcpy(csd, cmd.resp, sizeof(u32) * 4); | ||
183 | |||
184 | return MMC_ERR_NONE; | ||
185 | } | ||
186 | |||
187 | int mmc_send_ext_csd(struct mmc_card *card, u8 *ext_csd) | ||
188 | { | ||
189 | struct mmc_request mrq; | ||
190 | struct mmc_command cmd; | ||
191 | struct mmc_data data; | ||
192 | struct scatterlist sg; | ||
193 | |||
194 | BUG_ON(!card); | ||
195 | BUG_ON(!card->host); | ||
196 | BUG_ON(!ext_csd); | ||
197 | |||
198 | memset(&mrq, 0, sizeof(struct mmc_request)); | ||
199 | memset(&cmd, 0, sizeof(struct mmc_command)); | ||
200 | memset(&data, 0, sizeof(struct mmc_data)); | ||
201 | |||
202 | mrq.cmd = &cmd; | ||
203 | mrq.data = &data; | ||
204 | |||
205 | cmd.opcode = MMC_SEND_EXT_CSD; | ||
206 | cmd.arg = 0; | ||
207 | cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC; | ||
208 | |||
209 | data.blksz = 512; | ||
210 | data.blocks = 1; | ||
211 | data.flags = MMC_DATA_READ; | ||
212 | data.sg = &sg; | ||
213 | data.sg_len = 1; | ||
214 | |||
215 | sg_init_one(&sg, ext_csd, 512); | ||
216 | |||
217 | mmc_set_data_timeout(&data, card, 0); | ||
218 | |||
219 | mmc_wait_for_req(card->host, &mrq); | ||
220 | |||
221 | if (cmd.error != MMC_ERR_NONE) | ||
222 | return cmd.error; | ||
223 | if (data.error != MMC_ERR_NONE) | ||
224 | return data.error; | ||
225 | |||
226 | return MMC_ERR_NONE; | ||
227 | } | ||
228 | |||
229 | int mmc_switch(struct mmc_card *card, u8 set, u8 index, u8 value) | ||
230 | { | ||
231 | int err; | ||
232 | struct mmc_command cmd; | ||
233 | |||
234 | BUG_ON(!card); | ||
235 | BUG_ON(!card->host); | ||
236 | |||
237 | memset(&cmd, 0, sizeof(struct mmc_command)); | ||
238 | |||
239 | cmd.opcode = MMC_SWITCH; | ||
240 | cmd.arg = (MMC_SWITCH_MODE_WRITE_BYTE << 24) | | ||
241 | (index << 16) | | ||
242 | (value << 8) | | ||
243 | set; | ||
244 | cmd.flags = MMC_RSP_R1B | MMC_CMD_AC; | ||
245 | |||
246 | err = mmc_wait_for_cmd(card->host, &cmd, MMC_CMD_RETRIES); | ||
247 | if (err != MMC_ERR_NONE) | ||
248 | return err; | ||
249 | |||
250 | return MMC_ERR_NONE; | ||
251 | } | ||
252 | |||
253 | int mmc_send_status(struct mmc_card *card, u32 *status) | ||
254 | { | ||
255 | int err; | ||
256 | struct mmc_command cmd; | ||
257 | |||
258 | BUG_ON(!card); | ||
259 | BUG_ON(!card->host); | ||
260 | |||
261 | memset(&cmd, 0, sizeof(struct mmc_command)); | ||
262 | |||
263 | cmd.opcode = MMC_SEND_STATUS; | ||
264 | cmd.arg = card->rca << 16; | ||
265 | cmd.flags = MMC_RSP_R1 | MMC_CMD_AC; | ||
266 | |||
267 | err = mmc_wait_for_cmd(card->host, &cmd, MMC_CMD_RETRIES); | ||
268 | if (err != MMC_ERR_NONE) | ||
269 | return err; | ||
270 | |||
271 | if (status) | ||
272 | *status = cmd.resp[0]; | ||
273 | |||
274 | return MMC_ERR_NONE; | ||
275 | } | ||
276 | |||
diff --git a/drivers/mmc/core/mmc_ops.h b/drivers/mmc/core/mmc_ops.h new file mode 100644 index 000000000000..7a481e8ca5ea --- /dev/null +++ b/drivers/mmc/core/mmc_ops.h | |||
@@ -0,0 +1,27 @@ | |||
1 | /* | ||
2 | * linux/drivers/mmc/mmc_ops.h | ||
3 | * | ||
4 | * Copyright 2006-2007 Pierre Ossman | ||
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 | #ifndef _MMC_MMC_OPS_H | ||
13 | #define _MMC_MMC_OPS_H | ||
14 | |||
15 | int mmc_select_card(struct mmc_card *card); | ||
16 | int mmc_deselect_cards(struct mmc_host *host); | ||
17 | int mmc_go_idle(struct mmc_host *host); | ||
18 | int mmc_send_op_cond(struct mmc_host *host, u32 ocr, u32 *rocr); | ||
19 | int mmc_all_send_cid(struct mmc_host *host, u32 *cid); | ||
20 | int mmc_set_relative_addr(struct mmc_card *card); | ||
21 | int mmc_send_csd(struct mmc_card *card, u32 *csd); | ||
22 | int mmc_send_ext_csd(struct mmc_card *card, u8 *ext_csd); | ||
23 | int mmc_switch(struct mmc_card *card, u8 set, u8 index, u8 value); | ||
24 | int mmc_send_status(struct mmc_card *card, u32 *status); | ||
25 | |||
26 | #endif | ||
27 | |||
diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c new file mode 100644 index 000000000000..c1dfd03d559a --- /dev/null +++ b/drivers/mmc/core/sd.c | |||
@@ -0,0 +1,587 @@ | |||
1 | /* | ||
2 | * linux/drivers/mmc/sd.c | ||
3 | * | ||
4 | * Copyright (C) 2003-2004 Russell King, All Rights Reserved. | ||
5 | * SD support Copyright (C) 2004 Ian Molton, All Rights Reserved. | ||
6 | * Copyright (C) 2005-2007 Pierre Ossman, All Rights Reserved. | ||
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 version 2 as | ||
10 | * published by the Free Software Foundation. | ||
11 | */ | ||
12 | |||
13 | #include <linux/err.h> | ||
14 | |||
15 | #include <linux/mmc/host.h> | ||
16 | #include <linux/mmc/card.h> | ||
17 | #include <linux/mmc/mmc.h> | ||
18 | |||
19 | #include "core.h" | ||
20 | #include "sysfs.h" | ||
21 | #include "mmc_ops.h" | ||
22 | #include "sd_ops.h" | ||
23 | |||
24 | #include "core.h" | ||
25 | |||
26 | static const unsigned int tran_exp[] = { | ||
27 | 10000, 100000, 1000000, 10000000, | ||
28 | 0, 0, 0, 0 | ||
29 | }; | ||
30 | |||
31 | static const unsigned char tran_mant[] = { | ||
32 | 0, 10, 12, 13, 15, 20, 25, 30, | ||
33 | 35, 40, 45, 50, 55, 60, 70, 80, | ||
34 | }; | ||
35 | |||
36 | static const unsigned int tacc_exp[] = { | ||
37 | 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, | ||
38 | }; | ||
39 | |||
40 | static const unsigned int tacc_mant[] = { | ||
41 | 0, 10, 12, 13, 15, 20, 25, 30, | ||
42 | 35, 40, 45, 50, 55, 60, 70, 80, | ||
43 | }; | ||
44 | |||
45 | #define UNSTUFF_BITS(resp,start,size) \ | ||
46 | ({ \ | ||
47 | const int __size = size; \ | ||
48 | const u32 __mask = (__size < 32 ? 1 << __size : 0) - 1; \ | ||
49 | const int __off = 3 - ((start) / 32); \ | ||
50 | const int __shft = (start) & 31; \ | ||
51 | u32 __res; \ | ||
52 | \ | ||
53 | __res = resp[__off] >> __shft; \ | ||
54 | if (__size + __shft > 32) \ | ||
55 | __res |= resp[__off-1] << ((32 - __shft) % 32); \ | ||
56 | __res & __mask; \ | ||
57 | }) | ||
58 | |||
59 | /* | ||
60 | * Given the decoded CSD structure, decode the raw CID to our CID structure. | ||
61 | */ | ||
62 | static void mmc_decode_cid(struct mmc_card *card) | ||
63 | { | ||
64 | u32 *resp = card->raw_cid; | ||
65 | |||
66 | memset(&card->cid, 0, sizeof(struct mmc_cid)); | ||
67 | |||
68 | /* | ||
69 | * SD doesn't currently have a version field so we will | ||
70 | * have to assume we can parse this. | ||
71 | */ | ||
72 | card->cid.manfid = UNSTUFF_BITS(resp, 120, 8); | ||
73 | card->cid.oemid = UNSTUFF_BITS(resp, 104, 16); | ||
74 | card->cid.prod_name[0] = UNSTUFF_BITS(resp, 96, 8); | ||
75 | card->cid.prod_name[1] = UNSTUFF_BITS(resp, 88, 8); | ||
76 | card->cid.prod_name[2] = UNSTUFF_BITS(resp, 80, 8); | ||
77 | card->cid.prod_name[3] = UNSTUFF_BITS(resp, 72, 8); | ||
78 | card->cid.prod_name[4] = UNSTUFF_BITS(resp, 64, 8); | ||
79 | card->cid.hwrev = UNSTUFF_BITS(resp, 60, 4); | ||
80 | card->cid.fwrev = UNSTUFF_BITS(resp, 56, 4); | ||
81 | card->cid.serial = UNSTUFF_BITS(resp, 24, 32); | ||
82 | card->cid.year = UNSTUFF_BITS(resp, 12, 8); | ||
83 | card->cid.month = UNSTUFF_BITS(resp, 8, 4); | ||
84 | |||
85 | card->cid.year += 2000; /* SD cards year offset */ | ||
86 | } | ||
87 | |||
88 | /* | ||
89 | * Given a 128-bit response, decode to our card CSD structure. | ||
90 | */ | ||
91 | static int mmc_decode_csd(struct mmc_card *card) | ||
92 | { | ||
93 | struct mmc_csd *csd = &card->csd; | ||
94 | unsigned int e, m, csd_struct; | ||
95 | u32 *resp = card->raw_csd; | ||
96 | |||
97 | csd_struct = UNSTUFF_BITS(resp, 126, 2); | ||
98 | |||
99 | switch (csd_struct) { | ||
100 | case 0: | ||
101 | m = UNSTUFF_BITS(resp, 115, 4); | ||
102 | e = UNSTUFF_BITS(resp, 112, 3); | ||
103 | csd->tacc_ns = (tacc_exp[e] * tacc_mant[m] + 9) / 10; | ||
104 | csd->tacc_clks = UNSTUFF_BITS(resp, 104, 8) * 100; | ||
105 | |||
106 | m = UNSTUFF_BITS(resp, 99, 4); | ||
107 | e = UNSTUFF_BITS(resp, 96, 3); | ||
108 | csd->max_dtr = tran_exp[e] * tran_mant[m]; | ||
109 | csd->cmdclass = UNSTUFF_BITS(resp, 84, 12); | ||
110 | |||
111 | e = UNSTUFF_BITS(resp, 47, 3); | ||
112 | m = UNSTUFF_BITS(resp, 62, 12); | ||
113 | csd->capacity = (1 + m) << (e + 2); | ||
114 | |||
115 | csd->read_blkbits = UNSTUFF_BITS(resp, 80, 4); | ||
116 | csd->read_partial = UNSTUFF_BITS(resp, 79, 1); | ||
117 | csd->write_misalign = UNSTUFF_BITS(resp, 78, 1); | ||
118 | csd->read_misalign = UNSTUFF_BITS(resp, 77, 1); | ||
119 | csd->r2w_factor = UNSTUFF_BITS(resp, 26, 3); | ||
120 | csd->write_blkbits = UNSTUFF_BITS(resp, 22, 4); | ||
121 | csd->write_partial = UNSTUFF_BITS(resp, 21, 1); | ||
122 | break; | ||
123 | case 1: | ||
124 | /* | ||
125 | * This is a block-addressed SDHC card. Most | ||
126 | * interesting fields are unused and have fixed | ||
127 | * values. To avoid getting tripped by buggy cards, | ||
128 | * we assume those fixed values ourselves. | ||
129 | */ | ||
130 | mmc_card_set_blockaddr(card); | ||
131 | |||
132 | csd->tacc_ns = 0; /* Unused */ | ||
133 | csd->tacc_clks = 0; /* Unused */ | ||
134 | |||
135 | m = UNSTUFF_BITS(resp, 99, 4); | ||
136 | e = UNSTUFF_BITS(resp, 96, 3); | ||
137 | csd->max_dtr = tran_exp[e] * tran_mant[m]; | ||
138 | csd->cmdclass = UNSTUFF_BITS(resp, 84, 12); | ||
139 | |||
140 | m = UNSTUFF_BITS(resp, 48, 22); | ||
141 | csd->capacity = (1 + m) << 10; | ||
142 | |||
143 | csd->read_blkbits = 9; | ||
144 | csd->read_partial = 0; | ||
145 | csd->write_misalign = 0; | ||
146 | csd->read_misalign = 0; | ||
147 | csd->r2w_factor = 4; /* Unused */ | ||
148 | csd->write_blkbits = 9; | ||
149 | csd->write_partial = 0; | ||
150 | break; | ||
151 | default: | ||
152 | printk("%s: unrecognised CSD structure version %d\n", | ||
153 | mmc_hostname(card->host), csd_struct); | ||
154 | return -EINVAL; | ||
155 | } | ||
156 | |||
157 | return 0; | ||
158 | } | ||
159 | |||
160 | /* | ||
161 | * Given a 64-bit response, decode to our card SCR structure. | ||
162 | */ | ||
163 | static int mmc_decode_scr(struct mmc_card *card) | ||
164 | { | ||
165 | struct sd_scr *scr = &card->scr; | ||
166 | unsigned int scr_struct; | ||
167 | u32 resp[4]; | ||
168 | |||
169 | BUG_ON(!mmc_card_sd(card)); | ||
170 | |||
171 | resp[3] = card->raw_scr[1]; | ||
172 | resp[2] = card->raw_scr[0]; | ||
173 | |||
174 | scr_struct = UNSTUFF_BITS(resp, 60, 4); | ||
175 | if (scr_struct != 0) { | ||
176 | printk("%s: unrecognised SCR structure version %d\n", | ||
177 | mmc_hostname(card->host), scr_struct); | ||
178 | return -EINVAL; | ||
179 | } | ||
180 | |||
181 | scr->sda_vsn = UNSTUFF_BITS(resp, 56, 4); | ||
182 | scr->bus_widths = UNSTUFF_BITS(resp, 48, 4); | ||
183 | |||
184 | return 0; | ||
185 | } | ||
186 | |||
187 | /* | ||
188 | * Fetches and decodes switch information | ||
189 | */ | ||
190 | static int mmc_read_switch(struct mmc_card *card) | ||
191 | { | ||
192 | int err; | ||
193 | u8 *status; | ||
194 | |||
195 | err = MMC_ERR_FAILED; | ||
196 | |||
197 | status = kmalloc(64, GFP_KERNEL); | ||
198 | if (!status) { | ||
199 | printk("%s: could not allocate a buffer for switch " | ||
200 | "capabilities.\n", | ||
201 | mmc_hostname(card->host)); | ||
202 | return err; | ||
203 | } | ||
204 | |||
205 | err = mmc_sd_switch(card, 0, 0, 1, status); | ||
206 | if (err != MMC_ERR_NONE) { | ||
207 | /* | ||
208 | * Card not supporting high-speed will ignore the | ||
209 | * command. | ||
210 | */ | ||
211 | err = MMC_ERR_NONE; | ||
212 | goto out; | ||
213 | } | ||
214 | |||
215 | if (status[13] & 0x02) | ||
216 | card->sw_caps.hs_max_dtr = 50000000; | ||
217 | |||
218 | out: | ||
219 | kfree(status); | ||
220 | |||
221 | return err; | ||
222 | } | ||
223 | |||
224 | /* | ||
225 | * Test if the card supports high-speed mode and, if so, switch to it. | ||
226 | */ | ||
227 | static int mmc_switch_hs(struct mmc_card *card) | ||
228 | { | ||
229 | int err; | ||
230 | u8 *status; | ||
231 | |||
232 | if (!(card->host->caps & MMC_CAP_SD_HIGHSPEED)) | ||
233 | return MMC_ERR_NONE; | ||
234 | |||
235 | if (card->sw_caps.hs_max_dtr == 0) | ||
236 | return MMC_ERR_NONE; | ||
237 | |||
238 | err = MMC_ERR_FAILED; | ||
239 | |||
240 | status = kmalloc(64, GFP_KERNEL); | ||
241 | if (!status) { | ||
242 | printk("%s: could not allocate a buffer for switch " | ||
243 | "capabilities.\n", | ||
244 | mmc_hostname(card->host)); | ||
245 | return err; | ||
246 | } | ||
247 | |||
248 | err = mmc_sd_switch(card, 1, 0, 1, status); | ||
249 | if (err != MMC_ERR_NONE) | ||
250 | goto out; | ||
251 | |||
252 | if ((status[16] & 0xF) != 1) { | ||
253 | printk(KERN_WARNING "%s: Problem switching card " | ||
254 | "into high-speed mode!\n", | ||
255 | mmc_hostname(card->host)); | ||
256 | } else { | ||
257 | mmc_card_set_highspeed(card); | ||
258 | mmc_set_timing(card->host, MMC_TIMING_SD_HS); | ||
259 | } | ||
260 | |||
261 | out: | ||
262 | kfree(status); | ||
263 | |||
264 | return err; | ||
265 | } | ||
266 | |||
267 | /* | ||
268 | * Handle the detection and initialisation of a card. | ||
269 | * | ||
270 | * In the case of a resume, "curcard" will contain the card | ||
271 | * we're trying to reinitialise. | ||
272 | */ | ||
273 | static int mmc_sd_init_card(struct mmc_host *host, u32 ocr, | ||
274 | struct mmc_card *oldcard) | ||
275 | { | ||
276 | struct mmc_card *card; | ||
277 | int err; | ||
278 | u32 cid[4]; | ||
279 | unsigned int max_dtr; | ||
280 | |||
281 | BUG_ON(!host); | ||
282 | BUG_ON(!host->claimed); | ||
283 | |||
284 | /* | ||
285 | * Since we're changing the OCR value, we seem to | ||
286 | * need to tell some cards to go back to the idle | ||
287 | * state. We wait 1ms to give cards time to | ||
288 | * respond. | ||
289 | */ | ||
290 | mmc_go_idle(host); | ||
291 | |||
292 | /* | ||
293 | * If SD_SEND_IF_COND indicates an SD 2.0 | ||
294 | * compliant card and we should set bit 30 | ||
295 | * of the ocr to indicate that we can handle | ||
296 | * block-addressed SDHC cards. | ||
297 | */ | ||
298 | err = mmc_send_if_cond(host, ocr); | ||
299 | if (err == MMC_ERR_NONE) | ||
300 | ocr |= 1 << 30; | ||
301 | |||
302 | err = mmc_send_app_op_cond(host, ocr, NULL); | ||
303 | if (err != MMC_ERR_NONE) | ||
304 | goto err; | ||
305 | |||
306 | /* | ||
307 | * Fetch CID from card. | ||
308 | */ | ||
309 | err = mmc_all_send_cid(host, cid); | ||
310 | if (err != MMC_ERR_NONE) | ||
311 | goto err; | ||
312 | |||
313 | if (oldcard) { | ||
314 | if (memcmp(cid, oldcard->raw_cid, sizeof(cid)) != 0) | ||
315 | goto err; | ||
316 | |||
317 | card = oldcard; | ||
318 | } else { | ||
319 | /* | ||
320 | * Allocate card structure. | ||
321 | */ | ||
322 | card = mmc_alloc_card(host); | ||
323 | if (IS_ERR(card)) | ||
324 | goto err; | ||
325 | |||
326 | card->type = MMC_TYPE_SD; | ||
327 | memcpy(card->raw_cid, cid, sizeof(card->raw_cid)); | ||
328 | } | ||
329 | |||
330 | /* | ||
331 | * Set card RCA. | ||
332 | */ | ||
333 | err = mmc_send_relative_addr(host, &card->rca); | ||
334 | if (err != MMC_ERR_NONE) | ||
335 | goto free_card; | ||
336 | |||
337 | mmc_set_bus_mode(host, MMC_BUSMODE_PUSHPULL); | ||
338 | |||
339 | if (!oldcard) { | ||
340 | /* | ||
341 | * Fetch CSD from card. | ||
342 | */ | ||
343 | err = mmc_send_csd(card, card->raw_csd); | ||
344 | if (err != MMC_ERR_NONE) | ||
345 | goto free_card; | ||
346 | |||
347 | err = mmc_decode_csd(card); | ||
348 | if (err < 0) | ||
349 | goto free_card; | ||
350 | |||
351 | mmc_decode_cid(card); | ||
352 | } | ||
353 | |||
354 | /* | ||
355 | * Select card, as all following commands rely on that. | ||
356 | */ | ||
357 | err = mmc_select_card(card); | ||
358 | if (err != MMC_ERR_NONE) | ||
359 | goto free_card; | ||
360 | |||
361 | if (!oldcard) { | ||
362 | /* | ||
363 | * Fetch SCR from card. | ||
364 | */ | ||
365 | err = mmc_app_send_scr(card, card->raw_scr); | ||
366 | if (err != MMC_ERR_NONE) | ||
367 | goto free_card; | ||
368 | |||
369 | err = mmc_decode_scr(card); | ||
370 | if (err < 0) | ||
371 | goto free_card; | ||
372 | |||
373 | /* | ||
374 | * Fetch switch information from card. | ||
375 | */ | ||
376 | err = mmc_read_switch(card); | ||
377 | if (err != MMC_ERR_NONE) | ||
378 | goto free_card; | ||
379 | } | ||
380 | |||
381 | /* | ||
382 | * Attempt to change to high-speed (if supported) | ||
383 | */ | ||
384 | err = mmc_switch_hs(card); | ||
385 | if (err != MMC_ERR_NONE) | ||
386 | goto free_card; | ||
387 | |||
388 | /* | ||
389 | * Compute bus speed. | ||
390 | */ | ||
391 | max_dtr = (unsigned int)-1; | ||
392 | |||
393 | if (mmc_card_highspeed(card)) { | ||
394 | if (max_dtr > card->sw_caps.hs_max_dtr) | ||
395 | max_dtr = card->sw_caps.hs_max_dtr; | ||
396 | } else if (max_dtr > card->csd.max_dtr) { | ||
397 | max_dtr = card->csd.max_dtr; | ||
398 | } | ||
399 | |||
400 | mmc_set_clock(host, max_dtr); | ||
401 | |||
402 | /* | ||
403 | * Switch to wider bus (if supported). | ||
404 | */ | ||
405 | if ((host->caps && MMC_CAP_4_BIT_DATA) && | ||
406 | (card->scr.bus_widths & SD_SCR_BUS_WIDTH_4)) { | ||
407 | err = mmc_app_set_bus_width(card, MMC_BUS_WIDTH_4); | ||
408 | if (err != MMC_ERR_NONE) | ||
409 | goto free_card; | ||
410 | |||
411 | mmc_set_bus_width(host, MMC_BUS_WIDTH_4); | ||
412 | } | ||
413 | |||
414 | if (!oldcard) | ||
415 | host->card = card; | ||
416 | |||
417 | return MMC_ERR_NONE; | ||
418 | |||
419 | free_card: | ||
420 | if (!oldcard) | ||
421 | mmc_remove_card(card); | ||
422 | err: | ||
423 | |||
424 | return MMC_ERR_FAILED; | ||
425 | } | ||
426 | |||
427 | /* | ||
428 | * Host is being removed. Free up the current card. | ||
429 | */ | ||
430 | static void mmc_sd_remove(struct mmc_host *host) | ||
431 | { | ||
432 | BUG_ON(!host); | ||
433 | BUG_ON(!host->card); | ||
434 | |||
435 | mmc_remove_card(host->card); | ||
436 | host->card = NULL; | ||
437 | } | ||
438 | |||
439 | /* | ||
440 | * Card detection callback from host. | ||
441 | */ | ||
442 | static void mmc_sd_detect(struct mmc_host *host) | ||
443 | { | ||
444 | int err; | ||
445 | |||
446 | BUG_ON(!host); | ||
447 | BUG_ON(!host->card); | ||
448 | |||
449 | mmc_claim_host(host); | ||
450 | |||
451 | /* | ||
452 | * Just check if our card has been removed. | ||
453 | */ | ||
454 | err = mmc_send_status(host->card, NULL); | ||
455 | |||
456 | mmc_release_host(host); | ||
457 | |||
458 | if (err != MMC_ERR_NONE) { | ||
459 | mmc_remove_card(host->card); | ||
460 | host->card = NULL; | ||
461 | |||
462 | mmc_claim_host(host); | ||
463 | mmc_detach_bus(host); | ||
464 | mmc_release_host(host); | ||
465 | } | ||
466 | } | ||
467 | |||
468 | #ifdef CONFIG_MMC_UNSAFE_RESUME | ||
469 | |||
470 | /* | ||
471 | * Suspend callback from host. | ||
472 | */ | ||
473 | static void mmc_sd_suspend(struct mmc_host *host) | ||
474 | { | ||
475 | BUG_ON(!host); | ||
476 | BUG_ON(!host->card); | ||
477 | |||
478 | mmc_claim_host(host); | ||
479 | mmc_deselect_cards(host); | ||
480 | host->card->state &= ~MMC_STATE_HIGHSPEED; | ||
481 | mmc_release_host(host); | ||
482 | } | ||
483 | |||
484 | /* | ||
485 | * Resume callback from host. | ||
486 | * | ||
487 | * This function tries to determine if the same card is still present | ||
488 | * and, if so, restore all state to it. | ||
489 | */ | ||
490 | static void mmc_sd_resume(struct mmc_host *host) | ||
491 | { | ||
492 | int err; | ||
493 | |||
494 | BUG_ON(!host); | ||
495 | BUG_ON(!host->card); | ||
496 | |||
497 | mmc_claim_host(host); | ||
498 | |||
499 | err = mmc_sd_init_card(host, host->ocr, host->card); | ||
500 | if (err != MMC_ERR_NONE) { | ||
501 | mmc_remove_card(host->card); | ||
502 | host->card = NULL; | ||
503 | |||
504 | mmc_detach_bus(host); | ||
505 | } | ||
506 | |||
507 | mmc_release_host(host); | ||
508 | } | ||
509 | |||
510 | #else | ||
511 | |||
512 | #define mmc_sd_suspend NULL | ||
513 | #define mmc_sd_resume NULL | ||
514 | |||
515 | #endif | ||
516 | |||
517 | static const struct mmc_bus_ops mmc_sd_ops = { | ||
518 | .remove = mmc_sd_remove, | ||
519 | .detect = mmc_sd_detect, | ||
520 | .suspend = mmc_sd_suspend, | ||
521 | .resume = mmc_sd_resume, | ||
522 | }; | ||
523 | |||
524 | /* | ||
525 | * Starting point for SD card init. | ||
526 | */ | ||
527 | int mmc_attach_sd(struct mmc_host *host, u32 ocr) | ||
528 | { | ||
529 | int err; | ||
530 | |||
531 | BUG_ON(!host); | ||
532 | BUG_ON(!host->claimed); | ||
533 | |||
534 | mmc_attach_bus(host, &mmc_sd_ops); | ||
535 | |||
536 | /* | ||
537 | * Sanity check the voltages that the card claims to | ||
538 | * support. | ||
539 | */ | ||
540 | if (ocr & 0x7F) { | ||
541 | printk(KERN_WARNING "%s: card claims to support voltages " | ||
542 | "below the defined range. These will be ignored.\n", | ||
543 | mmc_hostname(host)); | ||
544 | ocr &= ~0x7F; | ||
545 | } | ||
546 | |||
547 | if (ocr & MMC_VDD_165_195) { | ||
548 | printk(KERN_WARNING "%s: SD card claims to support the " | ||
549 | "incompletely defined 'low voltage range'. This " | ||
550 | "will be ignored.\n", mmc_hostname(host)); | ||
551 | ocr &= ~MMC_VDD_165_195; | ||
552 | } | ||
553 | |||
554 | host->ocr = mmc_select_voltage(host, ocr); | ||
555 | |||
556 | /* | ||
557 | * Can we support the voltage(s) of the card(s)? | ||
558 | */ | ||
559 | if (!host->ocr) | ||
560 | goto err; | ||
561 | |||
562 | /* | ||
563 | * Detect and init the card. | ||
564 | */ | ||
565 | err = mmc_sd_init_card(host, host->ocr, NULL); | ||
566 | if (err != MMC_ERR_NONE) | ||
567 | goto err; | ||
568 | |||
569 | mmc_release_host(host); | ||
570 | |||
571 | err = mmc_register_card(host->card); | ||
572 | if (err) | ||
573 | goto reclaim_host; | ||
574 | |||
575 | return 0; | ||
576 | |||
577 | reclaim_host: | ||
578 | mmc_claim_host(host); | ||
579 | mmc_remove_card(host->card); | ||
580 | host->card = NULL; | ||
581 | err: | ||
582 | mmc_detach_bus(host); | ||
583 | mmc_release_host(host); | ||
584 | |||
585 | return 0; | ||
586 | } | ||
587 | |||
diff --git a/drivers/mmc/core/sd_ops.c b/drivers/mmc/core/sd_ops.c new file mode 100644 index 000000000000..9697ce581101 --- /dev/null +++ b/drivers/mmc/core/sd_ops.c | |||
@@ -0,0 +1,316 @@ | |||
1 | /* | ||
2 | * linux/drivers/mmc/sd_ops.h | ||
3 | * | ||
4 | * Copyright 2006-2007 Pierre Ossman | ||
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 | #include <linux/types.h> | ||
13 | #include <asm/scatterlist.h> | ||
14 | #include <linux/scatterlist.h> | ||
15 | |||
16 | #include <linux/mmc/host.h> | ||
17 | #include <linux/mmc/card.h> | ||
18 | #include <linux/mmc/mmc.h> | ||
19 | #include <linux/mmc/sd.h> | ||
20 | |||
21 | #include "core.h" | ||
22 | #include "sd_ops.h" | ||
23 | |||
24 | /** | ||
25 | * mmc_wait_for_app_cmd - start an application command and wait for | ||
26 | completion | ||
27 | * @host: MMC host to start command | ||
28 | * @rca: RCA to send MMC_APP_CMD to | ||
29 | * @cmd: MMC command to start | ||
30 | * @retries: maximum number of retries | ||
31 | * | ||
32 | * Sends a MMC_APP_CMD, checks the card response, sends the command | ||
33 | * in the parameter and waits for it to complete. Return any error | ||
34 | * that occurred while the command was executing. Do not attempt to | ||
35 | * parse the response. | ||
36 | */ | ||
37 | int mmc_wait_for_app_cmd(struct mmc_host *host, struct mmc_card *card, | ||
38 | struct mmc_command *cmd, int retries) | ||
39 | { | ||
40 | struct mmc_request mrq; | ||
41 | |||
42 | int i, err; | ||
43 | |||
44 | BUG_ON(!cmd); | ||
45 | BUG_ON(retries < 0); | ||
46 | |||
47 | err = MMC_ERR_INVALID; | ||
48 | |||
49 | /* | ||
50 | * We have to resend MMC_APP_CMD for each attempt so | ||
51 | * we cannot use the retries field in mmc_command. | ||
52 | */ | ||
53 | for (i = 0;i <= retries;i++) { | ||
54 | memset(&mrq, 0, sizeof(struct mmc_request)); | ||
55 | |||
56 | err = mmc_app_cmd(host, card); | ||
57 | if (err != MMC_ERR_NONE) | ||
58 | continue; | ||
59 | |||
60 | memset(&mrq, 0, sizeof(struct mmc_request)); | ||
61 | |||
62 | memset(cmd->resp, 0, sizeof(cmd->resp)); | ||
63 | cmd->retries = 0; | ||
64 | |||
65 | mrq.cmd = cmd; | ||
66 | cmd->data = NULL; | ||
67 | |||
68 | mmc_wait_for_req(host, &mrq); | ||
69 | |||
70 | err = cmd->error; | ||
71 | if (cmd->error == MMC_ERR_NONE) | ||
72 | break; | ||
73 | } | ||
74 | |||
75 | return err; | ||
76 | } | ||
77 | |||
78 | EXPORT_SYMBOL(mmc_wait_for_app_cmd); | ||
79 | |||
80 | int mmc_app_cmd(struct mmc_host *host, struct mmc_card *card) | ||
81 | { | ||
82 | int err; | ||
83 | struct mmc_command cmd; | ||
84 | |||
85 | BUG_ON(!host); | ||
86 | BUG_ON(card && (card->host != host)); | ||
87 | |||
88 | cmd.opcode = MMC_APP_CMD; | ||
89 | |||
90 | if (card) { | ||
91 | cmd.arg = card->rca << 16; | ||
92 | cmd.flags = MMC_RSP_R1 | MMC_CMD_AC; | ||
93 | } else { | ||
94 | cmd.arg = 0; | ||
95 | cmd.flags = MMC_RSP_R1 | MMC_CMD_BCR; | ||
96 | } | ||
97 | |||
98 | err = mmc_wait_for_cmd(host, &cmd, 0); | ||
99 | if (err != MMC_ERR_NONE) | ||
100 | return err; | ||
101 | |||
102 | /* Check that card supported application commands */ | ||
103 | if (!(cmd.resp[0] & R1_APP_CMD)) | ||
104 | return MMC_ERR_FAILED; | ||
105 | |||
106 | return MMC_ERR_NONE; | ||
107 | } | ||
108 | |||
109 | int mmc_app_set_bus_width(struct mmc_card *card, int width) | ||
110 | { | ||
111 | int err; | ||
112 | struct mmc_command cmd; | ||
113 | |||
114 | BUG_ON(!card); | ||
115 | BUG_ON(!card->host); | ||
116 | |||
117 | memset(&cmd, 0, sizeof(struct mmc_command)); | ||
118 | |||
119 | cmd.opcode = SD_APP_SET_BUS_WIDTH; | ||
120 | cmd.flags = MMC_RSP_R1 | MMC_CMD_AC; | ||
121 | |||
122 | switch (width) { | ||
123 | case MMC_BUS_WIDTH_1: | ||
124 | cmd.arg = SD_BUS_WIDTH_1; | ||
125 | break; | ||
126 | case MMC_BUS_WIDTH_4: | ||
127 | cmd.arg = SD_BUS_WIDTH_4; | ||
128 | break; | ||
129 | default: | ||
130 | return MMC_ERR_INVALID; | ||
131 | } | ||
132 | |||
133 | err = mmc_wait_for_app_cmd(card->host, card, &cmd, MMC_CMD_RETRIES); | ||
134 | if (err != MMC_ERR_NONE) | ||
135 | return err; | ||
136 | |||
137 | return MMC_ERR_NONE; | ||
138 | } | ||
139 | |||
140 | int mmc_send_app_op_cond(struct mmc_host *host, u32 ocr, u32 *rocr) | ||
141 | { | ||
142 | struct mmc_command cmd; | ||
143 | int i, err = 0; | ||
144 | |||
145 | BUG_ON(!host); | ||
146 | |||
147 | memset(&cmd, 0, sizeof(struct mmc_command)); | ||
148 | |||
149 | cmd.opcode = SD_APP_OP_COND; | ||
150 | cmd.arg = ocr; | ||
151 | cmd.flags = MMC_RSP_R3 | MMC_CMD_BCR; | ||
152 | |||
153 | for (i = 100; i; i--) { | ||
154 | err = mmc_wait_for_app_cmd(host, NULL, &cmd, MMC_CMD_RETRIES); | ||
155 | if (err != MMC_ERR_NONE) | ||
156 | break; | ||
157 | |||
158 | if (cmd.resp[0] & MMC_CARD_BUSY || ocr == 0) | ||
159 | break; | ||
160 | |||
161 | err = MMC_ERR_TIMEOUT; | ||
162 | |||
163 | mmc_delay(10); | ||
164 | } | ||
165 | |||
166 | if (rocr) | ||
167 | *rocr = cmd.resp[0]; | ||
168 | |||
169 | return err; | ||
170 | } | ||
171 | |||
172 | int mmc_send_if_cond(struct mmc_host *host, u32 ocr) | ||
173 | { | ||
174 | struct mmc_command cmd; | ||
175 | int err; | ||
176 | static const u8 test_pattern = 0xAA; | ||
177 | |||
178 | /* | ||
179 | * To support SD 2.0 cards, we must always invoke SD_SEND_IF_COND | ||
180 | * before SD_APP_OP_COND. This command will harmlessly fail for | ||
181 | * SD 1.0 cards. | ||
182 | */ | ||
183 | cmd.opcode = SD_SEND_IF_COND; | ||
184 | cmd.arg = ((ocr & 0xFF8000) != 0) << 8 | test_pattern; | ||
185 | cmd.flags = MMC_RSP_R7 | MMC_CMD_BCR; | ||
186 | |||
187 | err = mmc_wait_for_cmd(host, &cmd, 0); | ||
188 | if (err != MMC_ERR_NONE) | ||
189 | return err; | ||
190 | |||
191 | if ((cmd.resp[0] & 0xFF) != test_pattern) | ||
192 | return MMC_ERR_FAILED; | ||
193 | |||
194 | return MMC_ERR_NONE; | ||
195 | } | ||
196 | |||
197 | int mmc_send_relative_addr(struct mmc_host *host, unsigned int *rca) | ||
198 | { | ||
199 | int err; | ||
200 | struct mmc_command cmd; | ||
201 | |||
202 | BUG_ON(!host); | ||
203 | BUG_ON(!rca); | ||
204 | |||
205 | memset(&cmd, 0, sizeof(struct mmc_command)); | ||
206 | |||
207 | cmd.opcode = SD_SEND_RELATIVE_ADDR; | ||
208 | cmd.arg = 0; | ||
209 | cmd.flags = MMC_RSP_R6 | MMC_CMD_BCR; | ||
210 | |||
211 | err = mmc_wait_for_cmd(host, &cmd, MMC_CMD_RETRIES); | ||
212 | if (err != MMC_ERR_NONE) | ||
213 | return err; | ||
214 | |||
215 | *rca = cmd.resp[0] >> 16; | ||
216 | |||
217 | return MMC_ERR_NONE; | ||
218 | } | ||
219 | |||
220 | int mmc_app_send_scr(struct mmc_card *card, u32 *scr) | ||
221 | { | ||
222 | int err; | ||
223 | struct mmc_request mrq; | ||
224 | struct mmc_command cmd; | ||
225 | struct mmc_data data; | ||
226 | struct scatterlist sg; | ||
227 | |||
228 | BUG_ON(!card); | ||
229 | BUG_ON(!card->host); | ||
230 | BUG_ON(!scr); | ||
231 | |||
232 | err = mmc_app_cmd(card->host, card); | ||
233 | if (err != MMC_ERR_NONE) | ||
234 | return err; | ||
235 | |||
236 | memset(&mrq, 0, sizeof(struct mmc_request)); | ||
237 | memset(&cmd, 0, sizeof(struct mmc_command)); | ||
238 | memset(&data, 0, sizeof(struct mmc_data)); | ||
239 | |||
240 | mrq.cmd = &cmd; | ||
241 | mrq.data = &data; | ||
242 | |||
243 | cmd.opcode = SD_APP_SEND_SCR; | ||
244 | cmd.arg = 0; | ||
245 | cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC; | ||
246 | |||
247 | data.blksz = 8; | ||
248 | data.blocks = 1; | ||
249 | data.flags = MMC_DATA_READ; | ||
250 | data.sg = &sg; | ||
251 | data.sg_len = 1; | ||
252 | |||
253 | sg_init_one(&sg, scr, 8); | ||
254 | |||
255 | mmc_set_data_timeout(&data, card, 0); | ||
256 | |||
257 | mmc_wait_for_req(card->host, &mrq); | ||
258 | |||
259 | if (cmd.error != MMC_ERR_NONE) | ||
260 | return cmd.error; | ||
261 | if (data.error != MMC_ERR_NONE) | ||
262 | return data.error; | ||
263 | |||
264 | scr[0] = ntohl(scr[0]); | ||
265 | scr[1] = ntohl(scr[1]); | ||
266 | |||
267 | return MMC_ERR_NONE; | ||
268 | } | ||
269 | |||
270 | int mmc_sd_switch(struct mmc_card *card, int mode, int group, | ||
271 | u8 value, u8 *resp) | ||
272 | { | ||
273 | struct mmc_request mrq; | ||
274 | struct mmc_command cmd; | ||
275 | struct mmc_data data; | ||
276 | struct scatterlist sg; | ||
277 | |||
278 | BUG_ON(!card); | ||
279 | BUG_ON(!card->host); | ||
280 | |||
281 | mode = !!mode; | ||
282 | value &= 0xF; | ||
283 | |||
284 | memset(&mrq, 0, sizeof(struct mmc_request)); | ||
285 | memset(&cmd, 0, sizeof(struct mmc_command)); | ||
286 | memset(&data, 0, sizeof(struct mmc_data)); | ||
287 | |||
288 | mrq.cmd = &cmd; | ||
289 | mrq.data = &data; | ||
290 | |||
291 | cmd.opcode = SD_SWITCH; | ||
292 | cmd.arg = mode << 31 | 0x00FFFFFF; | ||
293 | cmd.arg &= ~(0xF << (group * 4)); | ||
294 | cmd.arg |= value << (group * 4); | ||
295 | cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC; | ||
296 | |||
297 | data.blksz = 64; | ||
298 | data.blocks = 1; | ||
299 | data.flags = MMC_DATA_READ; | ||
300 | data.sg = &sg; | ||
301 | data.sg_len = 1; | ||
302 | |||
303 | sg_init_one(&sg, resp, 64); | ||
304 | |||
305 | mmc_set_data_timeout(&data, card, 0); | ||
306 | |||
307 | mmc_wait_for_req(card->host, &mrq); | ||
308 | |||
309 | if (cmd.error != MMC_ERR_NONE) | ||
310 | return cmd.error; | ||
311 | if (data.error != MMC_ERR_NONE) | ||
312 | return data.error; | ||
313 | |||
314 | return MMC_ERR_NONE; | ||
315 | } | ||
316 | |||
diff --git a/drivers/mmc/core/sd_ops.h b/drivers/mmc/core/sd_ops.h new file mode 100644 index 000000000000..1240fddba5e3 --- /dev/null +++ b/drivers/mmc/core/sd_ops.h | |||
@@ -0,0 +1,25 @@ | |||
1 | /* | ||
2 | * linux/drivers/mmc/sd_ops.h | ||
3 | * | ||
4 | * Copyright 2006-2007 Pierre Ossman | ||
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 | #ifndef _MMC_SD_OPS_H | ||
13 | #define _MMC_SD_OPS_H | ||
14 | |||
15 | int mmc_app_cmd(struct mmc_host *host, struct mmc_card *card); | ||
16 | int mmc_app_set_bus_width(struct mmc_card *card, int width); | ||
17 | int mmc_send_app_op_cond(struct mmc_host *host, u32 ocr, u32 *rocr); | ||
18 | int mmc_send_if_cond(struct mmc_host *host, u32 ocr); | ||
19 | int mmc_send_relative_addr(struct mmc_host *host, unsigned int *rca); | ||
20 | int mmc_app_send_scr(struct mmc_card *card, u32 *scr); | ||
21 | int mmc_sd_switch(struct mmc_card *card, int mode, int group, | ||
22 | u8 value, u8 *resp); | ||
23 | |||
24 | #endif | ||
25 | |||
diff --git a/drivers/mmc/core/sysfs.c b/drivers/mmc/core/sysfs.c new file mode 100644 index 000000000000..843b1fbba557 --- /dev/null +++ b/drivers/mmc/core/sysfs.c | |||
@@ -0,0 +1,360 @@ | |||
1 | /* | ||
2 | * linux/drivers/mmc/core/sysfs.c | ||
3 | * | ||
4 | * Copyright (C) 2003 Russell King, 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 version 2 as | ||
8 | * published by the Free Software Foundation. | ||
9 | * | ||
10 | * MMC sysfs/driver model support. | ||
11 | */ | ||
12 | #include <linux/module.h> | ||
13 | #include <linux/init.h> | ||
14 | #include <linux/device.h> | ||
15 | #include <linux/idr.h> | ||
16 | #include <linux/workqueue.h> | ||
17 | |||
18 | #include <linux/mmc/card.h> | ||
19 | #include <linux/mmc/host.h> | ||
20 | |||
21 | #include "sysfs.h" | ||
22 | |||
23 | #define dev_to_mmc_card(d) container_of(d, struct mmc_card, dev) | ||
24 | #define to_mmc_driver(d) container_of(d, struct mmc_driver, drv) | ||
25 | #define cls_dev_to_mmc_host(d) container_of(d, struct mmc_host, class_dev) | ||
26 | |||
27 | #define MMC_ATTR(name, fmt, args...) \ | ||
28 | static ssize_t mmc_##name##_show (struct device *dev, struct device_attribute *attr, char *buf) \ | ||
29 | { \ | ||
30 | struct mmc_card *card = dev_to_mmc_card(dev); \ | ||
31 | return sprintf(buf, fmt, args); \ | ||
32 | } | ||
33 | |||
34 | MMC_ATTR(cid, "%08x%08x%08x%08x\n", card->raw_cid[0], card->raw_cid[1], | ||
35 | card->raw_cid[2], card->raw_cid[3]); | ||
36 | MMC_ATTR(csd, "%08x%08x%08x%08x\n", card->raw_csd[0], card->raw_csd[1], | ||
37 | card->raw_csd[2], card->raw_csd[3]); | ||
38 | MMC_ATTR(scr, "%08x%08x\n", card->raw_scr[0], card->raw_scr[1]); | ||
39 | MMC_ATTR(date, "%02d/%04d\n", card->cid.month, card->cid.year); | ||
40 | MMC_ATTR(fwrev, "0x%x\n", card->cid.fwrev); | ||
41 | MMC_ATTR(hwrev, "0x%x\n", card->cid.hwrev); | ||
42 | MMC_ATTR(manfid, "0x%06x\n", card->cid.manfid); | ||
43 | MMC_ATTR(name, "%s\n", card->cid.prod_name); | ||
44 | MMC_ATTR(oemid, "0x%04x\n", card->cid.oemid); | ||
45 | MMC_ATTR(serial, "0x%08x\n", card->cid.serial); | ||
46 | |||
47 | #define MMC_ATTR_RO(name) __ATTR(name, S_IRUGO, mmc_##name##_show, NULL) | ||
48 | |||
49 | static struct device_attribute mmc_dev_attrs[] = { | ||
50 | MMC_ATTR_RO(cid), | ||
51 | MMC_ATTR_RO(csd), | ||
52 | MMC_ATTR_RO(date), | ||
53 | MMC_ATTR_RO(fwrev), | ||
54 | MMC_ATTR_RO(hwrev), | ||
55 | MMC_ATTR_RO(manfid), | ||
56 | MMC_ATTR_RO(name), | ||
57 | MMC_ATTR_RO(oemid), | ||
58 | MMC_ATTR_RO(serial), | ||
59 | __ATTR_NULL | ||
60 | }; | ||
61 | |||
62 | static struct device_attribute mmc_dev_attr_scr = MMC_ATTR_RO(scr); | ||
63 | |||
64 | |||
65 | static void mmc_release_card(struct device *dev) | ||
66 | { | ||
67 | struct mmc_card *card = dev_to_mmc_card(dev); | ||
68 | |||
69 | kfree(card); | ||
70 | } | ||
71 | |||
72 | /* | ||
73 | * This currently matches any MMC driver to any MMC card - drivers | ||
74 | * themselves make the decision whether to drive this card in their | ||
75 | * probe method. | ||
76 | */ | ||
77 | static int mmc_bus_match(struct device *dev, struct device_driver *drv) | ||
78 | { | ||
79 | return 1; | ||
80 | } | ||
81 | |||
82 | static int | ||
83 | mmc_bus_uevent(struct device *dev, char **envp, int num_envp, char *buf, | ||
84 | int buf_size) | ||
85 | { | ||
86 | struct mmc_card *card = dev_to_mmc_card(dev); | ||
87 | char ccc[13]; | ||
88 | int retval = 0, i = 0, length = 0; | ||
89 | |||
90 | #define add_env(fmt,val) do { \ | ||
91 | retval = add_uevent_var(envp, num_envp, &i, \ | ||
92 | buf, buf_size, &length, \ | ||
93 | fmt, val); \ | ||
94 | if (retval) \ | ||
95 | return retval; \ | ||
96 | } while (0); | ||
97 | |||
98 | for (i = 0; i < 12; i++) | ||
99 | ccc[i] = card->csd.cmdclass & (1 << i) ? '1' : '0'; | ||
100 | ccc[12] = '\0'; | ||
101 | |||
102 | add_env("MMC_CCC=%s", ccc); | ||
103 | add_env("MMC_MANFID=%06x", card->cid.manfid); | ||
104 | add_env("MMC_NAME=%s", mmc_card_name(card)); | ||
105 | add_env("MMC_OEMID=%04x", card->cid.oemid); | ||
106 | #undef add_env | ||
107 | envp[i] = NULL; | ||
108 | |||
109 | return 0; | ||
110 | } | ||
111 | |||
112 | static int mmc_bus_suspend(struct device *dev, pm_message_t state) | ||
113 | { | ||
114 | struct mmc_driver *drv = to_mmc_driver(dev->driver); | ||
115 | struct mmc_card *card = dev_to_mmc_card(dev); | ||
116 | int ret = 0; | ||
117 | |||
118 | if (dev->driver && drv->suspend) | ||
119 | ret = drv->suspend(card, state); | ||
120 | return ret; | ||
121 | } | ||
122 | |||
123 | static int mmc_bus_resume(struct device *dev) | ||
124 | { | ||
125 | struct mmc_driver *drv = to_mmc_driver(dev->driver); | ||
126 | struct mmc_card *card = dev_to_mmc_card(dev); | ||
127 | int ret = 0; | ||
128 | |||
129 | if (dev->driver && drv->resume) | ||
130 | ret = drv->resume(card); | ||
131 | return ret; | ||
132 | } | ||
133 | |||
134 | static int mmc_bus_probe(struct device *dev) | ||
135 | { | ||
136 | struct mmc_driver *drv = to_mmc_driver(dev->driver); | ||
137 | struct mmc_card *card = dev_to_mmc_card(dev); | ||
138 | |||
139 | return drv->probe(card); | ||
140 | } | ||
141 | |||
142 | static int mmc_bus_remove(struct device *dev) | ||
143 | { | ||
144 | struct mmc_driver *drv = to_mmc_driver(dev->driver); | ||
145 | struct mmc_card *card = dev_to_mmc_card(dev); | ||
146 | |||
147 | drv->remove(card); | ||
148 | |||
149 | return 0; | ||
150 | } | ||
151 | |||
152 | static struct bus_type mmc_bus_type = { | ||
153 | .name = "mmc", | ||
154 | .dev_attrs = mmc_dev_attrs, | ||
155 | .match = mmc_bus_match, | ||
156 | .uevent = mmc_bus_uevent, | ||
157 | .probe = mmc_bus_probe, | ||
158 | .remove = mmc_bus_remove, | ||
159 | .suspend = mmc_bus_suspend, | ||
160 | .resume = mmc_bus_resume, | ||
161 | }; | ||
162 | |||
163 | /** | ||
164 | * mmc_register_driver - register a media driver | ||
165 | * @drv: MMC media driver | ||
166 | */ | ||
167 | int mmc_register_driver(struct mmc_driver *drv) | ||
168 | { | ||
169 | drv->drv.bus = &mmc_bus_type; | ||
170 | return driver_register(&drv->drv); | ||
171 | } | ||
172 | |||
173 | EXPORT_SYMBOL(mmc_register_driver); | ||
174 | |||
175 | /** | ||
176 | * mmc_unregister_driver - unregister a media driver | ||
177 | * @drv: MMC media driver | ||
178 | */ | ||
179 | void mmc_unregister_driver(struct mmc_driver *drv) | ||
180 | { | ||
181 | drv->drv.bus = &mmc_bus_type; | ||
182 | driver_unregister(&drv->drv); | ||
183 | } | ||
184 | |||
185 | EXPORT_SYMBOL(mmc_unregister_driver); | ||
186 | |||
187 | |||
188 | /* | ||
189 | * Internal function. Initialise a MMC card structure. | ||
190 | */ | ||
191 | void mmc_init_card(struct mmc_card *card, struct mmc_host *host) | ||
192 | { | ||
193 | memset(card, 0, sizeof(struct mmc_card)); | ||
194 | card->host = host; | ||
195 | device_initialize(&card->dev); | ||
196 | card->dev.parent = mmc_classdev(host); | ||
197 | card->dev.bus = &mmc_bus_type; | ||
198 | card->dev.release = mmc_release_card; | ||
199 | } | ||
200 | |||
201 | /* | ||
202 | * Internal function. Register a new MMC card with the driver model. | ||
203 | */ | ||
204 | int mmc_register_card(struct mmc_card *card) | ||
205 | { | ||
206 | int ret; | ||
207 | |||
208 | snprintf(card->dev.bus_id, sizeof(card->dev.bus_id), | ||
209 | "%s:%04x", mmc_hostname(card->host), card->rca); | ||
210 | |||
211 | ret = device_add(&card->dev); | ||
212 | if (ret == 0) { | ||
213 | if (mmc_card_sd(card)) { | ||
214 | ret = device_create_file(&card->dev, &mmc_dev_attr_scr); | ||
215 | if (ret) | ||
216 | device_del(&card->dev); | ||
217 | } | ||
218 | } | ||
219 | if (ret == 0) | ||
220 | mmc_card_set_present(card); | ||
221 | return ret; | ||
222 | } | ||
223 | |||
224 | /* | ||
225 | * Internal function. Unregister a new MMC card with the | ||
226 | * driver model, and (eventually) free it. | ||
227 | */ | ||
228 | void mmc_remove_card(struct mmc_card *card) | ||
229 | { | ||
230 | if (mmc_card_present(card)) { | ||
231 | if (mmc_card_sd(card)) | ||
232 | device_remove_file(&card->dev, &mmc_dev_attr_scr); | ||
233 | |||
234 | device_del(&card->dev); | ||
235 | } | ||
236 | |||
237 | put_device(&card->dev); | ||
238 | } | ||
239 | |||
240 | |||
241 | static void mmc_host_classdev_release(struct device *dev) | ||
242 | { | ||
243 | struct mmc_host *host = cls_dev_to_mmc_host(dev); | ||
244 | kfree(host); | ||
245 | } | ||
246 | |||
247 | static struct class mmc_host_class = { | ||
248 | .name = "mmc_host", | ||
249 | .dev_release = mmc_host_classdev_release, | ||
250 | }; | ||
251 | |||
252 | static DEFINE_IDR(mmc_host_idr); | ||
253 | static DEFINE_SPINLOCK(mmc_host_lock); | ||
254 | |||
255 | /* | ||
256 | * Internal function. Allocate a new MMC host. | ||
257 | */ | ||
258 | struct mmc_host *mmc_alloc_host_sysfs(int extra, struct device *dev) | ||
259 | { | ||
260 | struct mmc_host *host; | ||
261 | |||
262 | host = kmalloc(sizeof(struct mmc_host) + extra, GFP_KERNEL); | ||
263 | if (host) { | ||
264 | memset(host, 0, sizeof(struct mmc_host) + extra); | ||
265 | |||
266 | host->parent = dev; | ||
267 | host->class_dev.parent = dev; | ||
268 | host->class_dev.class = &mmc_host_class; | ||
269 | device_initialize(&host->class_dev); | ||
270 | } | ||
271 | |||
272 | return host; | ||
273 | } | ||
274 | |||
275 | /* | ||
276 | * Internal function. Register a new MMC host with the MMC class. | ||
277 | */ | ||
278 | int mmc_add_host_sysfs(struct mmc_host *host) | ||
279 | { | ||
280 | int err; | ||
281 | |||
282 | if (!idr_pre_get(&mmc_host_idr, GFP_KERNEL)) | ||
283 | return -ENOMEM; | ||
284 | |||
285 | spin_lock(&mmc_host_lock); | ||
286 | err = idr_get_new(&mmc_host_idr, host, &host->index); | ||
287 | spin_unlock(&mmc_host_lock); | ||
288 | if (err) | ||
289 | return err; | ||
290 | |||
291 | snprintf(host->class_dev.bus_id, BUS_ID_SIZE, | ||
292 | "mmc%d", host->index); | ||
293 | |||
294 | return device_add(&host->class_dev); | ||
295 | } | ||
296 | |||
297 | /* | ||
298 | * Internal function. Unregister a MMC host with the MMC class. | ||
299 | */ | ||
300 | void mmc_remove_host_sysfs(struct mmc_host *host) | ||
301 | { | ||
302 | device_del(&host->class_dev); | ||
303 | |||
304 | spin_lock(&mmc_host_lock); | ||
305 | idr_remove(&mmc_host_idr, host->index); | ||
306 | spin_unlock(&mmc_host_lock); | ||
307 | } | ||
308 | |||
309 | /* | ||
310 | * Internal function. Free a MMC host. | ||
311 | */ | ||
312 | void mmc_free_host_sysfs(struct mmc_host *host) | ||
313 | { | ||
314 | put_device(&host->class_dev); | ||
315 | } | ||
316 | |||
317 | static struct workqueue_struct *workqueue; | ||
318 | |||
319 | /* | ||
320 | * Internal function. Schedule delayed work in the MMC work queue. | ||
321 | */ | ||
322 | int mmc_schedule_delayed_work(struct delayed_work *work, unsigned long delay) | ||
323 | { | ||
324 | return queue_delayed_work(workqueue, work, delay); | ||
325 | } | ||
326 | |||
327 | /* | ||
328 | * Internal function. Flush all scheduled work from the MMC work queue. | ||
329 | */ | ||
330 | void mmc_flush_scheduled_work(void) | ||
331 | { | ||
332 | flush_workqueue(workqueue); | ||
333 | } | ||
334 | |||
335 | static int __init mmc_init(void) | ||
336 | { | ||
337 | int ret; | ||
338 | |||
339 | workqueue = create_singlethread_workqueue("kmmcd"); | ||
340 | if (!workqueue) | ||
341 | return -ENOMEM; | ||
342 | |||
343 | ret = bus_register(&mmc_bus_type); | ||
344 | if (ret == 0) { | ||
345 | ret = class_register(&mmc_host_class); | ||
346 | if (ret) | ||
347 | bus_unregister(&mmc_bus_type); | ||
348 | } | ||
349 | return ret; | ||
350 | } | ||
351 | |||
352 | static void __exit mmc_exit(void) | ||
353 | { | ||
354 | class_unregister(&mmc_host_class); | ||
355 | bus_unregister(&mmc_bus_type); | ||
356 | destroy_workqueue(workqueue); | ||
357 | } | ||
358 | |||
359 | module_init(mmc_init); | ||
360 | module_exit(mmc_exit); | ||
diff --git a/drivers/mmc/core/sysfs.h b/drivers/mmc/core/sysfs.h new file mode 100644 index 000000000000..80e29b358282 --- /dev/null +++ b/drivers/mmc/core/sysfs.h | |||
@@ -0,0 +1,27 @@ | |||
1 | /* | ||
2 | * linux/drivers/mmc/core/sysfs.h | ||
3 | * | ||
4 | * Copyright (C) 2003 Russell King, All Rights Reserved. | ||
5 | * Copyright 2007 Pierre Ossman | ||
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 | #ifndef _MMC_CORE_SYSFS_H | ||
12 | #define _MMC_CORE_SYSFS_H | ||
13 | |||
14 | void mmc_init_card(struct mmc_card *card, struct mmc_host *host); | ||
15 | int mmc_register_card(struct mmc_card *card); | ||
16 | void mmc_remove_card(struct mmc_card *card); | ||
17 | |||
18 | struct mmc_host *mmc_alloc_host_sysfs(int extra, struct device *dev); | ||
19 | int mmc_add_host_sysfs(struct mmc_host *host); | ||
20 | void mmc_remove_host_sysfs(struct mmc_host *host); | ||
21 | void mmc_free_host_sysfs(struct mmc_host *host); | ||
22 | |||
23 | int mmc_schedule_work(struct work_struct *work); | ||
24 | int mmc_schedule_delayed_work(struct delayed_work *work, unsigned long delay); | ||
25 | void mmc_flush_scheduled_work(void); | ||
26 | |||
27 | #endif | ||