diff options
author | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-07-26 17:00:56 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-07-26 17:00:56 -0400 |
commit | d941cf5e373c356723fa648b9f0302a11c9b1770 (patch) | |
tree | f79c2cab0e6223e452cbb6599859eaeec4ba8188 /drivers | |
parent | 9f5577d8158d8190174d95cbf21713251cc8a044 (diff) | |
parent | 393618510d5349e07d71dc28fb6fc49baf0d96a0 (diff) |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/drzeus/mmc
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/drzeus/mmc:
drivers/mmc/core/: make 3 functions static
mmc: add missing printk levels
mmc: remove redundant debug information from sdhci and wbsd
mmc: proper debugging output in core
mmc: be more verbose about card insertions/removal
mmc: Don't hold lock when releasing an added card
mmc: add a might_sleep() to mmc_claim_host()
mmc: update kerneldoc
mmc: update header file paths
sdhci: add support to ENE-CB714
mmc: check error bits before command completion
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/mmc/card/queue.c | 2 | ||||
-rw-r--r-- | drivers/mmc/core/bus.c | 23 | ||||
-rw-r--r-- | drivers/mmc/core/core.c | 144 | ||||
-rw-r--r-- | drivers/mmc/core/core.h | 22 | ||||
-rw-r--r-- | drivers/mmc/core/host.c | 7 | ||||
-rw-r--r-- | drivers/mmc/core/mmc.c | 26 | ||||
-rw-r--r-- | drivers/mmc/core/mmc_ops.c | 2 | ||||
-rw-r--r-- | drivers/mmc/core/mmc_ops.h | 2 | ||||
-rw-r--r-- | drivers/mmc/core/sd.c | 36 | ||||
-rw-r--r-- | drivers/mmc/core/sd_ops.c | 62 | ||||
-rw-r--r-- | drivers/mmc/core/sd_ops.h | 3 | ||||
-rw-r--r-- | drivers/mmc/host/at91_mci.c | 2 | ||||
-rw-r--r-- | drivers/mmc/host/au1xmmc.c | 2 | ||||
-rw-r--r-- | drivers/mmc/host/imxmmc.c | 2 | ||||
-rw-r--r-- | drivers/mmc/host/mmci.c | 2 | ||||
-rw-r--r-- | drivers/mmc/host/mmci.h | 2 | ||||
-rw-r--r-- | drivers/mmc/host/omap.c | 2 | ||||
-rw-r--r-- | drivers/mmc/host/pxamci.c | 2 | ||||
-rw-r--r-- | drivers/mmc/host/sdhci.c | 63 | ||||
-rw-r--r-- | drivers/mmc/host/sdhci.h | 2 | ||||
-rw-r--r-- | drivers/mmc/host/wbsd.c | 15 | ||||
-rw-r--r-- | drivers/mmc/host/wbsd.h | 2 |
22 files changed, 250 insertions, 175 deletions
diff --git a/drivers/mmc/card/queue.c b/drivers/mmc/card/queue.c index e02eac876362..c9a289c6c139 100644 --- a/drivers/mmc/card/queue.c +++ b/drivers/mmc/card/queue.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * linux/drivers/mmc/queue.c | 2 | * linux/drivers/mmc/card/queue.c |
3 | * | 3 | * |
4 | * Copyright (C) 2003 Russell King, All Rights Reserved. | 4 | * Copyright (C) 2003 Russell King, All Rights Reserved. |
5 | * Copyright 2006-2007 Pierre Ossman | 5 | * Copyright 2006-2007 Pierre Ossman |
diff --git a/drivers/mmc/core/bus.c b/drivers/mmc/core/bus.c index 348b566bf4fd..fe0e785ed7d2 100644 --- a/drivers/mmc/core/bus.c +++ b/drivers/mmc/core/bus.c | |||
@@ -209,10 +209,30 @@ struct mmc_card *mmc_alloc_card(struct mmc_host *host) | |||
209 | int mmc_add_card(struct mmc_card *card) | 209 | int mmc_add_card(struct mmc_card *card) |
210 | { | 210 | { |
211 | int ret; | 211 | int ret; |
212 | const char *type; | ||
212 | 213 | ||
213 | snprintf(card->dev.bus_id, sizeof(card->dev.bus_id), | 214 | snprintf(card->dev.bus_id, sizeof(card->dev.bus_id), |
214 | "%s:%04x", mmc_hostname(card->host), card->rca); | 215 | "%s:%04x", mmc_hostname(card->host), card->rca); |
215 | 216 | ||
217 | switch (card->type) { | ||
218 | case MMC_TYPE_MMC: | ||
219 | type = "MMC"; | ||
220 | break; | ||
221 | case MMC_TYPE_SD: | ||
222 | type = "SD"; | ||
223 | if (mmc_card_blockaddr(card)) | ||
224 | type = "SDHC"; | ||
225 | break; | ||
226 | default: | ||
227 | type = "?"; | ||
228 | break; | ||
229 | } | ||
230 | |||
231 | printk(KERN_INFO "%s: new %s%s card at address %04x\n", | ||
232 | mmc_hostname(card->host), | ||
233 | mmc_card_highspeed(card) ? "high speed " : "", | ||
234 | type, card->rca); | ||
235 | |||
216 | card->dev.uevent_suppress = 1; | 236 | card->dev.uevent_suppress = 1; |
217 | 237 | ||
218 | ret = device_add(&card->dev); | 238 | ret = device_add(&card->dev); |
@@ -243,6 +263,9 @@ int mmc_add_card(struct mmc_card *card) | |||
243 | void mmc_remove_card(struct mmc_card *card) | 263 | void mmc_remove_card(struct mmc_card *card) |
244 | { | 264 | { |
245 | if (mmc_card_present(card)) { | 265 | if (mmc_card_present(card)) { |
266 | printk(KERN_INFO "%s: card %04x removed\n", | ||
267 | mmc_hostname(card->host), card->rca); | ||
268 | |||
246 | if (card->host->bus_ops->sysfs_remove) | 269 | if (card->host->bus_ops->sysfs_remove) |
247 | card->host->bus_ops->sysfs_remove(card->host, card); | 270 | card->host->bus_ops->sysfs_remove(card->host, card); |
248 | device_del(&card->dev); | 271 | device_del(&card->dev); |
diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c index b5d8a6d90cca..bfd2ae5bd669 100644 --- a/drivers/mmc/core/core.c +++ b/drivers/mmc/core/core.c | |||
@@ -68,32 +68,41 @@ void mmc_request_done(struct mmc_host *host, struct mmc_request *mrq) | |||
68 | struct mmc_command *cmd = mrq->cmd; | 68 | struct mmc_command *cmd = mrq->cmd; |
69 | int err = cmd->error; | 69 | int err = cmd->error; |
70 | 70 | ||
71 | pr_debug("%s: req done (CMD%u): %d/%d/%d: %08x %08x %08x %08x\n", | ||
72 | mmc_hostname(host), cmd->opcode, err, | ||
73 | mrq->data ? mrq->data->error : 0, | ||
74 | mrq->stop ? mrq->stop->error : 0, | ||
75 | cmd->resp[0], cmd->resp[1], cmd->resp[2], cmd->resp[3]); | ||
76 | |||
77 | if (err && cmd->retries) { | 71 | if (err && cmd->retries) { |
72 | pr_debug("%s: req failed (CMD%u): %d, retrying...\n", | ||
73 | mmc_hostname(host), cmd->opcode, err); | ||
74 | |||
78 | cmd->retries--; | 75 | cmd->retries--; |
79 | cmd->error = 0; | 76 | cmd->error = 0; |
80 | host->ops->request(host, mrq); | 77 | host->ops->request(host, mrq); |
81 | } else if (mrq->done) { | 78 | } else { |
82 | mrq->done(mrq); | 79 | pr_debug("%s: req done (CMD%u): %d: %08x %08x %08x %08x\n", |
80 | mmc_hostname(host), cmd->opcode, err, | ||
81 | cmd->resp[0], cmd->resp[1], | ||
82 | cmd->resp[2], cmd->resp[3]); | ||
83 | |||
84 | if (mrq->data) { | ||
85 | pr_debug("%s: %d bytes transferred: %d\n", | ||
86 | mmc_hostname(host), | ||
87 | mrq->data->bytes_xfered, mrq->data->error); | ||
88 | } | ||
89 | |||
90 | if (mrq->stop) { | ||
91 | pr_debug("%s: (CMD%u): %d: %08x %08x %08x %08x\n", | ||
92 | mmc_hostname(host), mrq->stop->opcode, | ||
93 | mrq->stop->error, | ||
94 | mrq->stop->resp[0], mrq->stop->resp[1], | ||
95 | mrq->stop->resp[2], mrq->stop->resp[3]); | ||
96 | } | ||
97 | |||
98 | if (mrq->done) | ||
99 | mrq->done(mrq); | ||
83 | } | 100 | } |
84 | } | 101 | } |
85 | 102 | ||
86 | EXPORT_SYMBOL(mmc_request_done); | 103 | EXPORT_SYMBOL(mmc_request_done); |
87 | 104 | ||
88 | /** | 105 | static void |
89 | * mmc_start_request - start a command on a host | ||
90 | * @host: MMC host to start command on | ||
91 | * @mrq: MMC request to start | ||
92 | * | ||
93 | * Queue a command on the specified host. We expect the | ||
94 | * caller to be holding the host lock with interrupts disabled. | ||
95 | */ | ||
96 | void | ||
97 | mmc_start_request(struct mmc_host *host, struct mmc_request *mrq) | 106 | mmc_start_request(struct mmc_host *host, struct mmc_request *mrq) |
98 | { | 107 | { |
99 | #ifdef CONFIG_MMC_DEBUG | 108 | #ifdef CONFIG_MMC_DEBUG |
@@ -104,6 +113,21 @@ mmc_start_request(struct mmc_host *host, struct mmc_request *mrq) | |||
104 | mmc_hostname(host), mrq->cmd->opcode, | 113 | mmc_hostname(host), mrq->cmd->opcode, |
105 | mrq->cmd->arg, mrq->cmd->flags); | 114 | mrq->cmd->arg, mrq->cmd->flags); |
106 | 115 | ||
116 | if (mrq->data) { | ||
117 | pr_debug("%s: blksz %d blocks %d flags %08x " | ||
118 | "tsac %d ms nsac %d\n", | ||
119 | mmc_hostname(host), mrq->data->blksz, | ||
120 | mrq->data->blocks, mrq->data->flags, | ||
121 | mrq->data->timeout_ns / 10000000, | ||
122 | mrq->data->timeout_clks); | ||
123 | } | ||
124 | |||
125 | if (mrq->stop) { | ||
126 | pr_debug("%s: CMD%u arg %08x flags %08x\n", | ||
127 | mmc_hostname(host), mrq->stop->opcode, | ||
128 | mrq->stop->arg, mrq->stop->flags); | ||
129 | } | ||
130 | |||
107 | WARN_ON(!host->claimed); | 131 | WARN_ON(!host->claimed); |
108 | 132 | ||
109 | mrq->cmd->error = 0; | 133 | mrq->cmd->error = 0; |
@@ -133,14 +157,21 @@ mmc_start_request(struct mmc_host *host, struct mmc_request *mrq) | |||
133 | host->ops->request(host, mrq); | 157 | host->ops->request(host, mrq); |
134 | } | 158 | } |
135 | 159 | ||
136 | EXPORT_SYMBOL(mmc_start_request); | ||
137 | |||
138 | static void mmc_wait_done(struct mmc_request *mrq) | 160 | static void mmc_wait_done(struct mmc_request *mrq) |
139 | { | 161 | { |
140 | complete(mrq->done_data); | 162 | complete(mrq->done_data); |
141 | } | 163 | } |
142 | 164 | ||
143 | int mmc_wait_for_req(struct mmc_host *host, struct mmc_request *mrq) | 165 | /** |
166 | * mmc_wait_for_req - start a request and wait for completion | ||
167 | * @host: MMC host to start command | ||
168 | * @mrq: MMC request to start | ||
169 | * | ||
170 | * Start a new MMC custom command request for a host, and wait | ||
171 | * for the command to complete. Does not attempt to parse the | ||
172 | * response. | ||
173 | */ | ||
174 | void mmc_wait_for_req(struct mmc_host *host, struct mmc_request *mrq) | ||
144 | { | 175 | { |
145 | DECLARE_COMPLETION_ONSTACK(complete); | 176 | DECLARE_COMPLETION_ONSTACK(complete); |
146 | 177 | ||
@@ -150,8 +181,6 @@ int mmc_wait_for_req(struct mmc_host *host, struct mmc_request *mrq) | |||
150 | mmc_start_request(host, mrq); | 181 | mmc_start_request(host, mrq); |
151 | 182 | ||
152 | wait_for_completion(&complete); | 183 | wait_for_completion(&complete); |
153 | |||
154 | return 0; | ||
155 | } | 184 | } |
156 | 185 | ||
157 | EXPORT_SYMBOL(mmc_wait_for_req); | 186 | EXPORT_SYMBOL(mmc_wait_for_req); |
@@ -192,6 +221,9 @@ EXPORT_SYMBOL(mmc_wait_for_cmd); | |||
192 | * @data: data phase for command | 221 | * @data: data phase for command |
193 | * @card: the MMC card associated with the data transfer | 222 | * @card: the MMC card associated with the data transfer |
194 | * @write: flag to differentiate reads from writes | 223 | * @write: flag to differentiate reads from writes |
224 | * | ||
225 | * Computes the data timeout parameters according to the | ||
226 | * correct algorithm given the card type. | ||
195 | */ | 227 | */ |
196 | void mmc_set_data_timeout(struct mmc_data *data, const struct mmc_card *card, | 228 | void mmc_set_data_timeout(struct mmc_data *data, const struct mmc_card *card, |
197 | int write) | 229 | int write) |
@@ -240,21 +272,18 @@ void mmc_set_data_timeout(struct mmc_data *data, const struct mmc_card *card, | |||
240 | EXPORT_SYMBOL(mmc_set_data_timeout); | 272 | EXPORT_SYMBOL(mmc_set_data_timeout); |
241 | 273 | ||
242 | /** | 274 | /** |
243 | * __mmc_claim_host - exclusively claim a host | 275 | * mmc_claim_host - exclusively claim a host |
244 | * @host: mmc host to claim | 276 | * @host: mmc host to claim |
245 | * @card: mmc card to claim host for | ||
246 | * | ||
247 | * Claim a host for a set of operations. If a valid card | ||
248 | * is passed and this wasn't the last card selected, select | ||
249 | * the card before returning. | ||
250 | * | 277 | * |
251 | * Note: you should use mmc_card_claim_host or mmc_claim_host. | 278 | * Claim a host for a set of operations. |
252 | */ | 279 | */ |
253 | void mmc_claim_host(struct mmc_host *host) | 280 | void mmc_claim_host(struct mmc_host *host) |
254 | { | 281 | { |
255 | DECLARE_WAITQUEUE(wait, current); | 282 | DECLARE_WAITQUEUE(wait, current); |
256 | unsigned long flags; | 283 | unsigned long flags; |
257 | 284 | ||
285 | might_sleep(); | ||
286 | |||
258 | add_wait_queue(&host->wq, &wait); | 287 | add_wait_queue(&host->wq, &wait); |
259 | spin_lock_irqsave(&host->lock, flags); | 288 | spin_lock_irqsave(&host->lock, flags); |
260 | while (1) { | 289 | while (1) { |
@@ -433,6 +462,45 @@ static void mmc_power_off(struct mmc_host *host) | |||
433 | } | 462 | } |
434 | 463 | ||
435 | /* | 464 | /* |
465 | * Cleanup when the last reference to the bus operator is dropped. | ||
466 | */ | ||
467 | void __mmc_release_bus(struct mmc_host *host) | ||
468 | { | ||
469 | BUG_ON(!host); | ||
470 | BUG_ON(host->bus_refs); | ||
471 | BUG_ON(!host->bus_dead); | ||
472 | |||
473 | host->bus_ops = NULL; | ||
474 | } | ||
475 | |||
476 | /* | ||
477 | * Increase reference count of bus operator | ||
478 | */ | ||
479 | static inline void mmc_bus_get(struct mmc_host *host) | ||
480 | { | ||
481 | unsigned long flags; | ||
482 | |||
483 | spin_lock_irqsave(&host->lock, flags); | ||
484 | host->bus_refs++; | ||
485 | spin_unlock_irqrestore(&host->lock, flags); | ||
486 | } | ||
487 | |||
488 | /* | ||
489 | * Decrease reference count of bus operator and free it if | ||
490 | * it is the last reference. | ||
491 | */ | ||
492 | static inline void mmc_bus_put(struct mmc_host *host) | ||
493 | { | ||
494 | unsigned long flags; | ||
495 | |||
496 | spin_lock_irqsave(&host->lock, flags); | ||
497 | host->bus_refs--; | ||
498 | if ((host->bus_refs == 0) && host->bus_ops) | ||
499 | __mmc_release_bus(host); | ||
500 | spin_unlock_irqrestore(&host->lock, flags); | ||
501 | } | ||
502 | |||
503 | /* | ||
436 | * Assign a mmc bus handler to a host. Only one bus handler may control a | 504 | * Assign a mmc bus handler to a host. Only one bus handler may control a |
437 | * host at any given time. | 505 | * host at any given time. |
438 | */ | 506 | */ |
@@ -481,25 +549,15 @@ void mmc_detach_bus(struct mmc_host *host) | |||
481 | mmc_bus_put(host); | 549 | mmc_bus_put(host); |
482 | } | 550 | } |
483 | 551 | ||
484 | /* | ||
485 | * Cleanup when the last reference to the bus operator is dropped. | ||
486 | */ | ||
487 | void __mmc_release_bus(struct mmc_host *host) | ||
488 | { | ||
489 | BUG_ON(!host); | ||
490 | BUG_ON(host->bus_refs); | ||
491 | BUG_ON(!host->bus_dead); | ||
492 | |||
493 | host->bus_ops = NULL; | ||
494 | } | ||
495 | |||
496 | /** | 552 | /** |
497 | * mmc_detect_change - process change of state on a MMC socket | 553 | * mmc_detect_change - process change of state on a MMC socket |
498 | * @host: host which changed state. | 554 | * @host: host which changed state. |
499 | * @delay: optional delay to wait before detection (jiffies) | 555 | * @delay: optional delay to wait before detection (jiffies) |
500 | * | 556 | * |
501 | * All we know is that card(s) have been inserted or removed | 557 | * MMC drivers should call this when they detect a card has been |
502 | * from the socket(s). We don't know which socket or cards. | 558 | * inserted or removed. The MMC layer will confirm that any |
559 | * present card is still functional, and initialize any newly | ||
560 | * inserted. | ||
503 | */ | 561 | */ |
504 | void mmc_detect_change(struct mmc_host *host, unsigned long delay) | 562 | void mmc_detect_change(struct mmc_host *host, unsigned long delay) |
505 | { | 563 | { |
diff --git a/drivers/mmc/core/core.h b/drivers/mmc/core/core.h index ae006b30dd86..bb2774af9ea9 100644 --- a/drivers/mmc/core/core.h +++ b/drivers/mmc/core/core.h | |||
@@ -27,28 +27,6 @@ struct mmc_bus_ops { | |||
27 | void mmc_attach_bus(struct mmc_host *host, const struct mmc_bus_ops *ops); | 27 | void mmc_attach_bus(struct mmc_host *host, const struct mmc_bus_ops *ops); |
28 | void mmc_detach_bus(struct mmc_host *host); | 28 | void mmc_detach_bus(struct mmc_host *host); |
29 | 29 | ||
30 | void __mmc_release_bus(struct mmc_host *host); | ||
31 | |||
32 | static inline void mmc_bus_get(struct mmc_host *host) | ||
33 | { | ||
34 | unsigned long flags; | ||
35 | |||
36 | spin_lock_irqsave(&host->lock, flags); | ||
37 | host->bus_refs++; | ||
38 | spin_unlock_irqrestore(&host->lock, flags); | ||
39 | } | ||
40 | |||
41 | static inline void mmc_bus_put(struct mmc_host *host) | ||
42 | { | ||
43 | unsigned long flags; | ||
44 | |||
45 | spin_lock_irqsave(&host->lock, flags); | ||
46 | host->bus_refs--; | ||
47 | if ((host->bus_refs == 0) && host->bus_ops) | ||
48 | __mmc_release_bus(host); | ||
49 | spin_unlock_irqrestore(&host->lock, flags); | ||
50 | } | ||
51 | |||
52 | void mmc_set_chip_select(struct mmc_host *host, int mode); | 30 | void mmc_set_chip_select(struct mmc_host *host, int mode); |
53 | void mmc_set_clock(struct mmc_host *host, unsigned int hz); | 31 | void mmc_set_clock(struct mmc_host *host, unsigned int hz); |
54 | void mmc_set_bus_mode(struct mmc_host *host, unsigned int mode); | 32 | void mmc_set_bus_mode(struct mmc_host *host, unsigned int mode); |
diff --git a/drivers/mmc/core/host.c b/drivers/mmc/core/host.c index 1433d95c40bb..6a7e29849603 100644 --- a/drivers/mmc/core/host.c +++ b/drivers/mmc/core/host.c | |||
@@ -93,6 +93,10 @@ EXPORT_SYMBOL(mmc_alloc_host); | |||
93 | /** | 93 | /** |
94 | * mmc_add_host - initialise host hardware | 94 | * mmc_add_host - initialise host hardware |
95 | * @host: mmc host | 95 | * @host: mmc host |
96 | * | ||
97 | * Register the host with the driver model. The host must be | ||
98 | * prepared to start servicing requests before this function | ||
99 | * completes. | ||
96 | */ | 100 | */ |
97 | int mmc_add_host(struct mmc_host *host) | 101 | int mmc_add_host(struct mmc_host *host) |
98 | { | 102 | { |
@@ -126,7 +130,8 @@ EXPORT_SYMBOL(mmc_add_host); | |||
126 | * @host: mmc host | 130 | * @host: mmc host |
127 | * | 131 | * |
128 | * Unregister and remove all cards associated with this host, | 132 | * Unregister and remove all cards associated with this host, |
129 | * and power down the MMC bus. | 133 | * and power down the MMC bus. No new requests will be issued |
134 | * after this function has returned. | ||
130 | */ | 135 | */ |
131 | void mmc_remove_host(struct mmc_host *host) | 136 | void mmc_remove_host(struct mmc_host *host) |
132 | { | 137 | { |
diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c index 66f85bfa8dbb..21d7f48e1d4e 100644 --- a/drivers/mmc/core/mmc.c +++ b/drivers/mmc/core/mmc.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * linux/drivers/mmc/mmc.c | 2 | * linux/drivers/mmc/core/mmc.c |
3 | * | 3 | * |
4 | * Copyright (C) 2003-2004 Russell King, All Rights Reserved. | 4 | * Copyright (C) 2003-2004 Russell King, All Rights Reserved. |
5 | * Copyright (C) 2005-2007 Pierre Ossman, All Rights Reserved. | 5 | * Copyright (C) 2005-2007 Pierre Ossman, All Rights Reserved. |
@@ -100,7 +100,7 @@ static int mmc_decode_cid(struct mmc_card *card) | |||
100 | break; | 100 | break; |
101 | 101 | ||
102 | default: | 102 | default: |
103 | printk("%s: card has unknown MMCA version %d\n", | 103 | printk(KERN_ERR "%s: card has unknown MMCA version %d\n", |
104 | mmc_hostname(card->host), card->csd.mmca_vsn); | 104 | mmc_hostname(card->host), card->csd.mmca_vsn); |
105 | return -EINVAL; | 105 | return -EINVAL; |
106 | } | 106 | } |
@@ -123,7 +123,7 @@ static int mmc_decode_csd(struct mmc_card *card) | |||
123 | */ | 123 | */ |
124 | csd_struct = UNSTUFF_BITS(resp, 126, 2); | 124 | csd_struct = UNSTUFF_BITS(resp, 126, 2); |
125 | if (csd_struct != 1 && csd_struct != 2) { | 125 | if (csd_struct != 1 && csd_struct != 2) { |
126 | printk("%s: unrecognised CSD structure version %d\n", | 126 | printk(KERN_ERR "%s: unrecognised CSD structure version %d\n", |
127 | mmc_hostname(card->host), csd_struct); | 127 | mmc_hostname(card->host), csd_struct); |
128 | return -EINVAL; | 128 | return -EINVAL; |
129 | } | 129 | } |
@@ -499,14 +499,17 @@ static void mmc_resume(struct mmc_host *host) | |||
499 | BUG_ON(!host->card); | 499 | BUG_ON(!host->card); |
500 | 500 | ||
501 | mmc_claim_host(host); | 501 | mmc_claim_host(host); |
502 | |||
503 | err = mmc_init_card(host, host->ocr, host->card); | 502 | err = mmc_init_card(host, host->ocr, host->card); |
503 | mmc_release_host(host); | ||
504 | |||
504 | if (err != MMC_ERR_NONE) { | 505 | if (err != MMC_ERR_NONE) { |
505 | mmc_remove(host); | 506 | mmc_remove(host); |
507 | |||
508 | mmc_claim_host(host); | ||
506 | mmc_detach_bus(host); | 509 | mmc_detach_bus(host); |
510 | mmc_release_host(host); | ||
507 | } | 511 | } |
508 | 512 | ||
509 | mmc_release_host(host); | ||
510 | } | 513 | } |
511 | 514 | ||
512 | #else | 515 | #else |
@@ -553,8 +556,10 @@ int mmc_attach_mmc(struct mmc_host *host, u32 ocr) | |||
553 | /* | 556 | /* |
554 | * Can we support the voltage of the card? | 557 | * Can we support the voltage of the card? |
555 | */ | 558 | */ |
556 | if (!host->ocr) | 559 | if (!host->ocr) { |
560 | err = -EINVAL; | ||
557 | goto err; | 561 | goto err; |
562 | } | ||
558 | 563 | ||
559 | /* | 564 | /* |
560 | * Detect and init the card. | 565 | * Detect and init the card. |
@@ -567,18 +572,21 @@ int mmc_attach_mmc(struct mmc_host *host, u32 ocr) | |||
567 | 572 | ||
568 | err = mmc_add_card(host->card); | 573 | err = mmc_add_card(host->card); |
569 | if (err) | 574 | if (err) |
570 | goto reclaim_host; | 575 | goto remove_card; |
571 | 576 | ||
572 | return 0; | 577 | return 0; |
573 | 578 | ||
574 | reclaim_host: | 579 | remove_card: |
575 | mmc_claim_host(host); | ||
576 | mmc_remove_card(host->card); | 580 | mmc_remove_card(host->card); |
577 | host->card = NULL; | 581 | host->card = NULL; |
582 | mmc_claim_host(host); | ||
578 | err: | 583 | err: |
579 | mmc_detach_bus(host); | 584 | mmc_detach_bus(host); |
580 | mmc_release_host(host); | 585 | mmc_release_host(host); |
581 | 586 | ||
587 | printk(KERN_ERR "%s: error %d whilst initialising MMC card\n", | ||
588 | mmc_hostname(host), err); | ||
589 | |||
582 | return 0; | 590 | return 0; |
583 | } | 591 | } |
584 | 592 | ||
diff --git a/drivers/mmc/core/mmc_ops.c b/drivers/mmc/core/mmc_ops.c index 7dd720fa5895..913e75f00843 100644 --- a/drivers/mmc/core/mmc_ops.c +++ b/drivers/mmc/core/mmc_ops.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * linux/drivers/mmc/mmc_ops.h | 2 | * linux/drivers/mmc/core/mmc_ops.h |
3 | * | 3 | * |
4 | * Copyright 2006-2007 Pierre Ossman | 4 | * Copyright 2006-2007 Pierre Ossman |
5 | * | 5 | * |
diff --git a/drivers/mmc/core/mmc_ops.h b/drivers/mmc/core/mmc_ops.h index 7a481e8ca5ea..76d09a93c5d6 100644 --- a/drivers/mmc/core/mmc_ops.h +++ b/drivers/mmc/core/mmc_ops.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * linux/drivers/mmc/mmc_ops.h | 2 | * linux/drivers/mmc/core/mmc_ops.h |
3 | * | 3 | * |
4 | * Copyright 2006-2007 Pierre Ossman | 4 | * Copyright 2006-2007 Pierre Ossman |
5 | * | 5 | * |
diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c index 1240684083f1..1edc62b1e5c6 100644 --- a/drivers/mmc/core/sd.c +++ b/drivers/mmc/core/sd.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * linux/drivers/mmc/sd.c | 2 | * linux/drivers/mmc/core/sd.c |
3 | * | 3 | * |
4 | * Copyright (C) 2003-2004 Russell King, All Rights Reserved. | 4 | * Copyright (C) 2003-2004 Russell King, All Rights Reserved. |
5 | * SD support Copyright (C) 2004 Ian Molton, All Rights Reserved. | 5 | * SD support Copyright (C) 2004 Ian Molton, All Rights Reserved. |
@@ -149,7 +149,7 @@ static int mmc_decode_csd(struct mmc_card *card) | |||
149 | csd->write_partial = 0; | 149 | csd->write_partial = 0; |
150 | break; | 150 | break; |
151 | default: | 151 | default: |
152 | printk("%s: unrecognised CSD structure version %d\n", | 152 | printk(KERN_ERR "%s: unrecognised CSD structure version %d\n", |
153 | mmc_hostname(card->host), csd_struct); | 153 | mmc_hostname(card->host), csd_struct); |
154 | return -EINVAL; | 154 | return -EINVAL; |
155 | } | 155 | } |
@@ -173,7 +173,7 @@ static int mmc_decode_scr(struct mmc_card *card) | |||
173 | 173 | ||
174 | scr_struct = UNSTUFF_BITS(resp, 60, 4); | 174 | scr_struct = UNSTUFF_BITS(resp, 60, 4); |
175 | if (scr_struct != 0) { | 175 | if (scr_struct != 0) { |
176 | printk("%s: unrecognised SCR structure version %d\n", | 176 | printk(KERN_ERR "%s: unrecognised SCR structure version %d\n", |
177 | mmc_hostname(card->host), scr_struct); | 177 | mmc_hostname(card->host), scr_struct); |
178 | return -EINVAL; | 178 | return -EINVAL; |
179 | } | 179 | } |
@@ -206,9 +206,8 @@ static int mmc_read_switch(struct mmc_card *card) | |||
206 | 206 | ||
207 | status = kmalloc(64, GFP_KERNEL); | 207 | status = kmalloc(64, GFP_KERNEL); |
208 | if (!status) { | 208 | if (!status) { |
209 | printk("%s: could not allocate a buffer for switch " | 209 | printk(KERN_ERR "%s: could not allocate a buffer for " |
210 | "capabilities.\n", | 210 | "switch capabilities.\n", mmc_hostname(card->host)); |
211 | mmc_hostname(card->host)); | ||
212 | return err; | 211 | return err; |
213 | } | 212 | } |
214 | 213 | ||
@@ -254,9 +253,8 @@ static int mmc_switch_hs(struct mmc_card *card) | |||
254 | 253 | ||
255 | status = kmalloc(64, GFP_KERNEL); | 254 | status = kmalloc(64, GFP_KERNEL); |
256 | if (!status) { | 255 | if (!status) { |
257 | printk("%s: could not allocate a buffer for switch " | 256 | printk(KERN_ERR "%s: could not allocate a buffer for " |
258 | "capabilities.\n", | 257 | "switch capabilities.\n", mmc_hostname(card->host)); |
259 | mmc_hostname(card->host)); | ||
260 | return err; | 258 | return err; |
261 | } | 259 | } |
262 | 260 | ||
@@ -573,14 +571,17 @@ static void mmc_sd_resume(struct mmc_host *host) | |||
573 | BUG_ON(!host->card); | 571 | BUG_ON(!host->card); |
574 | 572 | ||
575 | mmc_claim_host(host); | 573 | mmc_claim_host(host); |
576 | |||
577 | err = mmc_sd_init_card(host, host->ocr, host->card); | 574 | err = mmc_sd_init_card(host, host->ocr, host->card); |
575 | mmc_release_host(host); | ||
576 | |||
578 | if (err != MMC_ERR_NONE) { | 577 | if (err != MMC_ERR_NONE) { |
579 | mmc_sd_remove(host); | 578 | mmc_sd_remove(host); |
579 | |||
580 | mmc_claim_host(host); | ||
580 | mmc_detach_bus(host); | 581 | mmc_detach_bus(host); |
582 | mmc_release_host(host); | ||
581 | } | 583 | } |
582 | 584 | ||
583 | mmc_release_host(host); | ||
584 | } | 585 | } |
585 | 586 | ||
586 | #else | 587 | #else |
@@ -634,8 +635,10 @@ int mmc_attach_sd(struct mmc_host *host, u32 ocr) | |||
634 | /* | 635 | /* |
635 | * Can we support the voltage(s) of the card(s)? | 636 | * Can we support the voltage(s) of the card(s)? |
636 | */ | 637 | */ |
637 | if (!host->ocr) | 638 | if (!host->ocr) { |
639 | err = -EINVAL; | ||
638 | goto err; | 640 | goto err; |
641 | } | ||
639 | 642 | ||
640 | /* | 643 | /* |
641 | * Detect and init the card. | 644 | * Detect and init the card. |
@@ -648,18 +651,21 @@ int mmc_attach_sd(struct mmc_host *host, u32 ocr) | |||
648 | 651 | ||
649 | err = mmc_add_card(host->card); | 652 | err = mmc_add_card(host->card); |
650 | if (err) | 653 | if (err) |
651 | goto reclaim_host; | 654 | goto remove_card; |
652 | 655 | ||
653 | return 0; | 656 | return 0; |
654 | 657 | ||
655 | reclaim_host: | 658 | remove_card: |
656 | mmc_claim_host(host); | ||
657 | mmc_remove_card(host->card); | 659 | mmc_remove_card(host->card); |
658 | host->card = NULL; | 660 | host->card = NULL; |
661 | mmc_claim_host(host); | ||
659 | err: | 662 | err: |
660 | mmc_detach_bus(host); | 663 | mmc_detach_bus(host); |
661 | mmc_release_host(host); | 664 | mmc_release_host(host); |
662 | 665 | ||
666 | printk(KERN_ERR "%s: error %d whilst initialising SD card\n", | ||
667 | mmc_hostname(host), err); | ||
668 | |||
663 | return 0; | 669 | return 0; |
664 | } | 670 | } |
665 | 671 | ||
diff --git a/drivers/mmc/core/sd_ops.c b/drivers/mmc/core/sd_ops.c index 9697ce581101..342f340ebc25 100644 --- a/drivers/mmc/core/sd_ops.c +++ b/drivers/mmc/core/sd_ops.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * linux/drivers/mmc/sd_ops.h | 2 | * linux/drivers/mmc/core/sd_ops.h |
3 | * | 3 | * |
4 | * Copyright 2006-2007 Pierre Ossman | 4 | * Copyright 2006-2007 Pierre Ossman |
5 | * | 5 | * |
@@ -21,11 +21,40 @@ | |||
21 | #include "core.h" | 21 | #include "core.h" |
22 | #include "sd_ops.h" | 22 | #include "sd_ops.h" |
23 | 23 | ||
24 | static int mmc_app_cmd(struct mmc_host *host, struct mmc_card *card) | ||
25 | { | ||
26 | int err; | ||
27 | struct mmc_command cmd; | ||
28 | |||
29 | BUG_ON(!host); | ||
30 | BUG_ON(card && (card->host != host)); | ||
31 | |||
32 | cmd.opcode = MMC_APP_CMD; | ||
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_R1 | MMC_CMD_BCR; | ||
40 | } | ||
41 | |||
42 | err = mmc_wait_for_cmd(host, &cmd, 0); | ||
43 | if (err != MMC_ERR_NONE) | ||
44 | return err; | ||
45 | |||
46 | /* Check that card supported application commands */ | ||
47 | if (!(cmd.resp[0] & R1_APP_CMD)) | ||
48 | return MMC_ERR_FAILED; | ||
49 | |||
50 | return MMC_ERR_NONE; | ||
51 | } | ||
52 | |||
24 | /** | 53 | /** |
25 | * mmc_wait_for_app_cmd - start an application command and wait for | 54 | * mmc_wait_for_app_cmd - start an application command and wait for |
26 | completion | 55 | completion |
27 | * @host: MMC host to start command | 56 | * @host: MMC host to start command |
28 | * @rca: RCA to send MMC_APP_CMD to | 57 | * @card: Card to send MMC_APP_CMD to |
29 | * @cmd: MMC command to start | 58 | * @cmd: MMC command to start |
30 | * @retries: maximum number of retries | 59 | * @retries: maximum number of retries |
31 | * | 60 | * |
@@ -77,35 +106,6 @@ int mmc_wait_for_app_cmd(struct mmc_host *host, struct mmc_card *card, | |||
77 | 106 | ||
78 | EXPORT_SYMBOL(mmc_wait_for_app_cmd); | 107 | EXPORT_SYMBOL(mmc_wait_for_app_cmd); |
79 | 108 | ||
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) | 109 | int mmc_app_set_bus_width(struct mmc_card *card, int width) |
110 | { | 110 | { |
111 | int err; | 111 | int err; |
diff --git a/drivers/mmc/core/sd_ops.h b/drivers/mmc/core/sd_ops.h index 1240fddba5e3..9742d8a30664 100644 --- a/drivers/mmc/core/sd_ops.h +++ b/drivers/mmc/core/sd_ops.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * linux/drivers/mmc/sd_ops.h | 2 | * linux/drivers/mmc/core/sd_ops.h |
3 | * | 3 | * |
4 | * Copyright 2006-2007 Pierre Ossman | 4 | * Copyright 2006-2007 Pierre Ossman |
5 | * | 5 | * |
@@ -12,7 +12,6 @@ | |||
12 | #ifndef _MMC_SD_OPS_H | 12 | #ifndef _MMC_SD_OPS_H |
13 | #define _MMC_SD_OPS_H | 13 | #define _MMC_SD_OPS_H |
14 | 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); | 15 | 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); | 16 | 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); | 17 | int mmc_send_if_cond(struct mmc_host *host, u32 ocr); |
diff --git a/drivers/mmc/host/at91_mci.c b/drivers/mmc/host/at91_mci.c index 15aab374127e..62564ccde03a 100644 --- a/drivers/mmc/host/at91_mci.c +++ b/drivers/mmc/host/at91_mci.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * linux/drivers/mmc/at91_mci.c - ATMEL AT91 MCI Driver | 2 | * linux/drivers/mmc/host/at91_mci.c - ATMEL AT91 MCI Driver |
3 | * | 3 | * |
4 | * Copyright (C) 2005 Cougar Creek Computing Devices Ltd, All Rights Reserved | 4 | * Copyright (C) 2005 Cougar Creek Computing Devices Ltd, All Rights Reserved |
5 | * | 5 | * |
diff --git a/drivers/mmc/host/au1xmmc.c b/drivers/mmc/host/au1xmmc.c index 52b63f11ddd6..34c99d4ea041 100644 --- a/drivers/mmc/host/au1xmmc.c +++ b/drivers/mmc/host/au1xmmc.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * linux/drivers/mmc/au1xmmc.c - AU1XX0 MMC driver | 2 | * linux/drivers/mmc/host/au1xmmc.c - AU1XX0 MMC driver |
3 | * | 3 | * |
4 | * Copyright (c) 2005, Advanced Micro Devices, Inc. | 4 | * Copyright (c) 2005, Advanced Micro Devices, Inc. |
5 | * | 5 | * |
diff --git a/drivers/mmc/host/imxmmc.c b/drivers/mmc/host/imxmmc.c index 7ee2045acbef..54bfc9f25596 100644 --- a/drivers/mmc/host/imxmmc.c +++ b/drivers/mmc/host/imxmmc.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * linux/drivers/mmc/imxmmc.c - Motorola i.MX MMCI driver | 2 | * linux/drivers/mmc/host/imxmmc.c - Motorola i.MX MMCI driver |
3 | * | 3 | * |
4 | * Copyright (C) 2004 Sascha Hauer, Pengutronix <sascha@saschahauer.de> | 4 | * Copyright (C) 2004 Sascha Hauer, Pengutronix <sascha@saschahauer.de> |
5 | * Copyright (C) 2006 Pavel Pisa, PiKRON <ppisa@pikron.com> | 5 | * Copyright (C) 2006 Pavel Pisa, PiKRON <ppisa@pikron.com> |
diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c index d11c2d23ceea..be730c0a0352 100644 --- a/drivers/mmc/host/mmci.c +++ b/drivers/mmc/host/mmci.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * linux/drivers/mmc/mmci.c - ARM PrimeCell MMCI PL180/1 driver | 2 | * linux/drivers/mmc/host/mmci.c - ARM PrimeCell MMCI PL180/1 driver |
3 | * | 3 | * |
4 | * Copyright (C) 2003 Deep Blue Solutions, Ltd, All Rights Reserved. | 4 | * Copyright (C) 2003 Deep Blue Solutions, Ltd, All Rights Reserved. |
5 | * | 5 | * |
diff --git a/drivers/mmc/host/mmci.h b/drivers/mmc/host/mmci.h index 6d7eadc9a678..000e6a919782 100644 --- a/drivers/mmc/host/mmci.h +++ b/drivers/mmc/host/mmci.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * linux/drivers/mmc/mmci.h - ARM PrimeCell MMCI PL180/1 driver | 2 | * linux/drivers/mmc/host/mmci.h - ARM PrimeCell MMCI PL180/1 driver |
3 | * | 3 | * |
4 | * Copyright (C) 2003 Deep Blue Solutions, Ltd, All Rights Reserved. | 4 | * Copyright (C) 2003 Deep Blue Solutions, Ltd, All Rights Reserved. |
5 | * | 5 | * |
diff --git a/drivers/mmc/host/omap.c b/drivers/mmc/host/omap.c index b0824a38f425..0cf97edc5f58 100644 --- a/drivers/mmc/host/omap.c +++ b/drivers/mmc/host/omap.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * linux/drivers/media/mmc/omap.c | 2 | * linux/drivers/mmc/host/omap.c |
3 | * | 3 | * |
4 | * Copyright (C) 2004 Nokia Corporation | 4 | * Copyright (C) 2004 Nokia Corporation |
5 | * Written by Tuukka Tikkanen and Juha Yrjölä<juha.yrjola@nokia.com> | 5 | * Written by Tuukka Tikkanen and Juha Yrjölä<juha.yrjola@nokia.com> |
diff --git a/drivers/mmc/host/pxamci.c b/drivers/mmc/host/pxamci.c index f8985c508bb9..ff960334b337 100644 --- a/drivers/mmc/host/pxamci.c +++ b/drivers/mmc/host/pxamci.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * linux/drivers/mmc/pxa.c - PXA MMCI driver | 2 | * linux/drivers/mmc/host/pxa.c - PXA MMCI driver |
3 | * | 3 | * |
4 | * Copyright (C) 2003 Russell King, All Rights Reserved. | 4 | * Copyright (C) 2003 Russell King, All Rights Reserved. |
5 | * | 5 | * |
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index 4a24db028d87..f2bc87ac24f7 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * linux/drivers/mmc/sdhci.c - Secure Digital Host Controller Interface driver | 2 | * linux/drivers/mmc/host/sdhci.c - Secure Digital Host Controller Interface driver |
3 | * | 3 | * |
4 | * Copyright (C) 2005-2007 Pierre Ossman, All Rights Reserved. | 4 | * Copyright (C) 2005-2007 Pierre Ossman, All Rights Reserved. |
5 | * | 5 | * |
@@ -34,6 +34,7 @@ static unsigned int debug_quirks = 0; | |||
34 | /* Controller doesn't like some resets when there is no card inserted. */ | 34 | /* Controller doesn't like some resets when there is no card inserted. */ |
35 | #define SDHCI_QUIRK_NO_CARD_NO_RESET (1<<2) | 35 | #define SDHCI_QUIRK_NO_CARD_NO_RESET (1<<2) |
36 | #define SDHCI_QUIRK_SINGLE_POWER_WRITE (1<<3) | 36 | #define SDHCI_QUIRK_SINGLE_POWER_WRITE (1<<3) |
37 | #define SDHCI_QUIRK_RESET_CMD_DATA_ON_IOS (1<<4) | ||
37 | 38 | ||
38 | static const struct pci_device_id pci_ids[] __devinitdata = { | 39 | static const struct pci_device_id pci_ids[] __devinitdata = { |
39 | { | 40 | { |
@@ -78,6 +79,24 @@ static const struct pci_device_id pci_ids[] __devinitdata = { | |||
78 | .driver_data = SDHCI_QUIRK_SINGLE_POWER_WRITE, | 79 | .driver_data = SDHCI_QUIRK_SINGLE_POWER_WRITE, |
79 | }, | 80 | }, |
80 | 81 | ||
82 | { | ||
83 | .vendor = PCI_VENDOR_ID_ENE, | ||
84 | .device = PCI_DEVICE_ID_ENE_CB714_SD, | ||
85 | .subvendor = PCI_ANY_ID, | ||
86 | .subdevice = PCI_ANY_ID, | ||
87 | .driver_data = SDHCI_QUIRK_SINGLE_POWER_WRITE | | ||
88 | SDHCI_QUIRK_RESET_CMD_DATA_ON_IOS, | ||
89 | }, | ||
90 | |||
91 | { | ||
92 | .vendor = PCI_VENDOR_ID_ENE, | ||
93 | .device = PCI_DEVICE_ID_ENE_CB714_SD_2, | ||
94 | .subvendor = PCI_ANY_ID, | ||
95 | .subdevice = PCI_ANY_ID, | ||
96 | .driver_data = SDHCI_QUIRK_SINGLE_POWER_WRITE | | ||
97 | SDHCI_QUIRK_RESET_CMD_DATA_ON_IOS, | ||
98 | }, | ||
99 | |||
81 | { /* Generic SD host controller */ | 100 | { /* Generic SD host controller */ |
82 | PCI_DEVICE_CLASS((PCI_CLASS_SYSTEM_SDHCI << 8), 0xFFFF00) | 101 | PCI_DEVICE_CLASS((PCI_CLASS_SYSTEM_SDHCI << 8), 0xFFFF00) |
83 | }, | 102 | }, |
@@ -361,11 +380,6 @@ static void sdhci_prepare_data(struct sdhci_host *host, struct mmc_data *data) | |||
361 | if (data == NULL) | 380 | if (data == NULL) |
362 | return; | 381 | return; |
363 | 382 | ||
364 | DBG("blksz %04x blks %04x flags %08x\n", | ||
365 | data->blksz, data->blocks, data->flags); | ||
366 | DBG("tsac %d ms nsac %d clk\n", | ||
367 | data->timeout_ns / 1000000, data->timeout_clks); | ||
368 | |||
369 | /* Sanity checks */ | 383 | /* Sanity checks */ |
370 | BUG_ON(data->blksz * data->blocks > 524288); | 384 | BUG_ON(data->blksz * data->blocks > 524288); |
371 | BUG_ON(data->blksz > host->mmc->max_blk_size); | 385 | BUG_ON(data->blksz > host->mmc->max_blk_size); |
@@ -476,8 +490,6 @@ static void sdhci_finish_data(struct sdhci_host *host) | |||
476 | data->error = MMC_ERR_FAILED; | 490 | data->error = MMC_ERR_FAILED; |
477 | } | 491 | } |
478 | 492 | ||
479 | DBG("Ending data transfer (%d bytes)\n", data->bytes_xfered); | ||
480 | |||
481 | if (data->stop) { | 493 | if (data->stop) { |
482 | /* | 494 | /* |
483 | * The controller needs a reset of internal state machines | 495 | * The controller needs a reset of internal state machines |
@@ -501,8 +513,6 @@ static void sdhci_send_command(struct sdhci_host *host, struct mmc_command *cmd) | |||
501 | 513 | ||
502 | WARN_ON(host->cmd); | 514 | WARN_ON(host->cmd); |
503 | 515 | ||
504 | DBG("Sending cmd (%x)\n", cmd->opcode); | ||
505 | |||
506 | /* Wait max 10 ms */ | 516 | /* Wait max 10 ms */ |
507 | timeout = 10; | 517 | timeout = 10; |
508 | 518 | ||
@@ -590,8 +600,6 @@ static void sdhci_finish_command(struct sdhci_host *host) | |||
590 | 600 | ||
591 | host->cmd->error = MMC_ERR_NONE; | 601 | host->cmd->error = MMC_ERR_NONE; |
592 | 602 | ||
593 | DBG("Ending cmd (%x)\n", host->cmd->opcode); | ||
594 | |||
595 | if (host->cmd->data) | 603 | if (host->cmd->data) |
596 | host->data = host->cmd->data; | 604 | host->data = host->cmd->data; |
597 | else | 605 | else |
@@ -759,6 +767,14 @@ static void sdhci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) | |||
759 | 767 | ||
760 | writeb(ctrl, host->ioaddr + SDHCI_HOST_CONTROL); | 768 | writeb(ctrl, host->ioaddr + SDHCI_HOST_CONTROL); |
761 | 769 | ||
770 | /* | ||
771 | * Some (ENE) controllers go apeshit on some ios operation, | ||
772 | * signalling timeout and CRC errors even on CMD0. Resetting | ||
773 | * it on each ios seems to solve the problem. | ||
774 | */ | ||
775 | if(host->chip->quirks & SDHCI_QUIRK_RESET_CMD_DATA_ON_IOS) | ||
776 | sdhci_reset(host, SDHCI_RESET_CMD | SDHCI_RESET_DATA); | ||
777 | |||
762 | mmiowb(); | 778 | mmiowb(); |
763 | spin_unlock_irqrestore(&host->lock, flags); | 779 | spin_unlock_irqrestore(&host->lock, flags); |
764 | } | 780 | } |
@@ -835,8 +851,6 @@ static void sdhci_tasklet_finish(unsigned long param) | |||
835 | 851 | ||
836 | mrq = host->mrq; | 852 | mrq = host->mrq; |
837 | 853 | ||
838 | DBG("Ending request, cmd (%x)\n", mrq->cmd->opcode); | ||
839 | |||
840 | /* | 854 | /* |
841 | * The controller needs a reset of internal state machines | 855 | * The controller needs a reset of internal state machines |
842 | * upon error conditions. | 856 | * upon error conditions. |
@@ -922,20 +936,17 @@ static void sdhci_cmd_irq(struct sdhci_host *host, u32 intmask) | |||
922 | return; | 936 | return; |
923 | } | 937 | } |
924 | 938 | ||
925 | if (intmask & SDHCI_INT_RESPONSE) | 939 | if (intmask & SDHCI_INT_TIMEOUT) |
926 | sdhci_finish_command(host); | 940 | host->cmd->error = MMC_ERR_TIMEOUT; |
927 | else { | 941 | else if (intmask & SDHCI_INT_CRC) |
928 | if (intmask & SDHCI_INT_TIMEOUT) | 942 | host->cmd->error = MMC_ERR_BADCRC; |
929 | host->cmd->error = MMC_ERR_TIMEOUT; | 943 | else if (intmask & (SDHCI_INT_END_BIT | SDHCI_INT_INDEX)) |
930 | else if (intmask & SDHCI_INT_CRC) | 944 | host->cmd->error = MMC_ERR_FAILED; |
931 | host->cmd->error = MMC_ERR_BADCRC; | ||
932 | else if (intmask & (SDHCI_INT_END_BIT | SDHCI_INT_INDEX)) | ||
933 | host->cmd->error = MMC_ERR_FAILED; | ||
934 | else | ||
935 | host->cmd->error = MMC_ERR_INVALID; | ||
936 | 945 | ||
946 | if (host->cmd->error != MMC_ERR_NONE) | ||
937 | tasklet_schedule(&host->finish_tasklet); | 947 | tasklet_schedule(&host->finish_tasklet); |
938 | } | 948 | else if (intmask & SDHCI_INT_RESPONSE) |
949 | sdhci_finish_command(host); | ||
939 | } | 950 | } |
940 | 951 | ||
941 | static void sdhci_data_irq(struct sdhci_host *host, u32 intmask) | 952 | static void sdhci_data_irq(struct sdhci_host *host, u32 intmask) |
diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h index a6c870480b8a..d157776c1149 100644 --- a/drivers/mmc/host/sdhci.h +++ b/drivers/mmc/host/sdhci.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * linux/drivers/mmc/sdhci.h - Secure Digital Host Controller Interface driver | 2 | * linux/drivers/mmc/host/sdhci.h - Secure Digital Host Controller Interface driver |
3 | * | 3 | * |
4 | * Copyright (C) 2005-2007 Pierre Ossman, All Rights Reserved. | 4 | * Copyright (C) 2005-2007 Pierre Ossman, All Rights Reserved. |
5 | * | 5 | * |
diff --git a/drivers/mmc/host/wbsd.c b/drivers/mmc/host/wbsd.c index 867ca6a69298..e0c9808fd424 100644 --- a/drivers/mmc/host/wbsd.c +++ b/drivers/mmc/host/wbsd.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * linux/drivers/mmc/wbsd.c - Winbond W83L51xD SD/MMC driver | 2 | * linux/drivers/mmc/host/wbsd.c - Winbond W83L51xD SD/MMC driver |
3 | * | 3 | * |
4 | * Copyright (C) 2004-2007 Pierre Ossman, All Rights Reserved. | 4 | * Copyright (C) 2004-2007 Pierre Ossman, All Rights Reserved. |
5 | * | 5 | * |
@@ -207,8 +207,6 @@ static void wbsd_request_end(struct wbsd_host *host, struct mmc_request *mrq) | |||
207 | { | 207 | { |
208 | unsigned long dmaflags; | 208 | unsigned long dmaflags; |
209 | 209 | ||
210 | DBGF("Ending request, cmd (%x)\n", mrq->cmd->opcode); | ||
211 | |||
212 | if (host->dma >= 0) { | 210 | if (host->dma >= 0) { |
213 | /* | 211 | /* |
214 | * Release ISA DMA controller. | 212 | * Release ISA DMA controller. |
@@ -360,8 +358,6 @@ static void wbsd_send_command(struct wbsd_host *host, struct mmc_command *cmd) | |||
360 | int i; | 358 | int i; |
361 | u8 status, isr; | 359 | u8 status, isr; |
362 | 360 | ||
363 | DBGF("Sending cmd (%x)\n", cmd->opcode); | ||
364 | |||
365 | /* | 361 | /* |
366 | * Clear accumulated ISR. The interrupt routine | 362 | * Clear accumulated ISR. The interrupt routine |
367 | * will fill this one with events that occur during | 363 | * will fill this one with events that occur during |
@@ -411,8 +407,6 @@ static void wbsd_send_command(struct wbsd_host *host, struct mmc_command *cmd) | |||
411 | wbsd_get_short_reply(host, cmd); | 407 | wbsd_get_short_reply(host, cmd); |
412 | } | 408 | } |
413 | } | 409 | } |
414 | |||
415 | DBGF("Sent cmd (%x), res %d\n", cmd->opcode, cmd->error); | ||
416 | } | 410 | } |
417 | 411 | ||
418 | /* | 412 | /* |
@@ -550,11 +544,6 @@ static void wbsd_prepare_data(struct wbsd_host *host, struct mmc_data *data) | |||
550 | unsigned long dmaflags; | 544 | unsigned long dmaflags; |
551 | unsigned int size; | 545 | unsigned int size; |
552 | 546 | ||
553 | DBGF("blksz %04x blks %04x flags %08x\n", | ||
554 | data->blksz, data->blocks, data->flags); | ||
555 | DBGF("tsac %d ms nsac %d clk\n", | ||
556 | data->timeout_ns / 1000000, data->timeout_clks); | ||
557 | |||
558 | /* | 547 | /* |
559 | * Calculate size. | 548 | * Calculate size. |
560 | */ | 549 | */ |
@@ -752,8 +741,6 @@ static void wbsd_finish_data(struct wbsd_host *host, struct mmc_data *data) | |||
752 | } | 741 | } |
753 | } | 742 | } |
754 | 743 | ||
755 | DBGF("Ending data transfer (%d bytes)\n", data->bytes_xfered); | ||
756 | |||
757 | wbsd_request_end(host, host->mrq); | 744 | wbsd_request_end(host, host->mrq); |
758 | } | 745 | } |
759 | 746 | ||
diff --git a/drivers/mmc/host/wbsd.h b/drivers/mmc/host/wbsd.h index 873bda1e59b4..0877866f8d28 100644 --- a/drivers/mmc/host/wbsd.h +++ b/drivers/mmc/host/wbsd.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * linux/drivers/mmc/wbsd.h - Winbond W83L51xD SD/MMC driver | 2 | * linux/drivers/mmc/host/wbsd.h - Winbond W83L51xD SD/MMC driver |
3 | * | 3 | * |
4 | * Copyright (C) 2004-2007 Pierre Ossman, All Rights Reserved. | 4 | * Copyright (C) 2004-2007 Pierre Ossman, All Rights Reserved. |
5 | * | 5 | * |