diff options
author | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-10-11 21:57:31 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-10-11 21:57:31 -0400 |
commit | 6abd2c860e34add677de50e8b134f5af6f4b0893 (patch) | |
tree | d201de170ca4851d66dbd02046fea7d95214fad7 /drivers/mmc/core | |
parent | d2c75f2f4b8be1c78f275c49e399d5a9b21ce924 (diff) | |
parent | 019a5f56ec195aceadada18aaaad0f67294bdaef (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: (67 commits)
mmc: don't use weight32()
pxamci: support arbitrary block size
sdio: make the IRQ thread more resilient in the presence of bad states
sdio: fix IRQ diagnostic message
sdhci: remove old dma module params
sdhci: add SDHCI_QUIRK_BROKEN_DMA quirk
sdhci: remove DMA capability check from controller's PCI Class reg
sdhci: fix a typo
mmc: Disabler for Ricoh MMC controller
sdio: adaptive interrupt polling
mmc: pxamci: add SDIO card interrupt reporting capability
mmc: pxamci: set proper buswidth capabilities according to PXA flavor
mmc: pxamci: set proper block capabilities according to PXA flavor
mmc: pxamci: better pending IRQ determination
arm: i.MX/MX1 SDHC implements SD cards read-only switch read-back
mmc: add led trigger
mmc_spi host driver
MMC core learns about SPI
MMC/SD card driver learns SPI
MMC headers learn about SPI
...
Diffstat (limited to 'drivers/mmc/core')
-rw-r--r-- | drivers/mmc/core/Makefile | 4 | ||||
-rw-r--r-- | drivers/mmc/core/bus.c | 67 | ||||
-rw-r--r-- | drivers/mmc/core/core.c | 167 | ||||
-rw-r--r-- | drivers/mmc/core/core.h | 2 | ||||
-rw-r--r-- | drivers/mmc/core/host.c | 8 | ||||
-rw-r--r-- | drivers/mmc/core/mmc.c | 134 | ||||
-rw-r--r-- | drivers/mmc/core/mmc_ops.c | 200 | ||||
-rw-r--r-- | drivers/mmc/core/mmc_ops.h | 3 | ||||
-rw-r--r-- | drivers/mmc/core/sd.c | 126 | ||||
-rw-r--r-- | drivers/mmc/core/sd_ops.c | 107 | ||||
-rw-r--r-- | drivers/mmc/core/sdio.c | 395 | ||||
-rw-r--r-- | drivers/mmc/core/sdio_bus.c | 270 | ||||
-rw-r--r-- | drivers/mmc/core/sdio_bus.h | 22 | ||||
-rw-r--r-- | drivers/mmc/core/sdio_cis.c | 346 | ||||
-rw-r--r-- | drivers/mmc/core/sdio_cis.h | 23 | ||||
-rw-r--r-- | drivers/mmc/core/sdio_io.c | 548 | ||||
-rw-r--r-- | drivers/mmc/core/sdio_irq.c | 267 | ||||
-rw-r--r-- | drivers/mmc/core/sdio_ops.c | 176 | ||||
-rw-r--r-- | drivers/mmc/core/sdio_ops.h | 22 |
19 files changed, 2653 insertions, 234 deletions
diff --git a/drivers/mmc/core/Makefile b/drivers/mmc/core/Makefile index 3fdd08c7f143..4985807257a8 100644 --- a/drivers/mmc/core/Makefile +++ b/drivers/mmc/core/Makefile | |||
@@ -8,5 +8,7 @@ endif | |||
8 | 8 | ||
9 | obj-$(CONFIG_MMC) += mmc_core.o | 9 | obj-$(CONFIG_MMC) += mmc_core.o |
10 | mmc_core-y := core.o sysfs.o bus.o host.o \ | 10 | mmc_core-y := core.o sysfs.o bus.o host.o \ |
11 | mmc.o mmc_ops.o sd.o sd_ops.o | 11 | mmc.o mmc_ops.o sd.o sd_ops.o \ |
12 | sdio.o sdio_ops.o sdio_bus.o \ | ||
13 | sdio_cis.o sdio_io.o sdio_irq.o | ||
12 | 14 | ||
diff --git a/drivers/mmc/core/bus.c b/drivers/mmc/core/bus.c index 817a79462b3d..8d6f6014870f 100644 --- a/drivers/mmc/core/bus.c +++ b/drivers/mmc/core/bus.c | |||
@@ -19,6 +19,7 @@ | |||
19 | 19 | ||
20 | #include "sysfs.h" | 20 | #include "sysfs.h" |
21 | #include "core.h" | 21 | #include "core.h" |
22 | #include "sdio_cis.h" | ||
22 | #include "bus.h" | 23 | #include "bus.h" |
23 | 24 | ||
24 | #define dev_to_mmc_card(d) container_of(d, struct mmc_card, dev) | 25 | #define dev_to_mmc_card(d) container_of(d, struct mmc_card, dev) |
@@ -34,6 +35,8 @@ static ssize_t mmc_type_show(struct device *dev, | |||
34 | return sprintf(buf, "MMC\n"); | 35 | return sprintf(buf, "MMC\n"); |
35 | case MMC_TYPE_SD: | 36 | case MMC_TYPE_SD: |
36 | return sprintf(buf, "SD\n"); | 37 | return sprintf(buf, "SD\n"); |
38 | case MMC_TYPE_SDIO: | ||
39 | return sprintf(buf, "SDIO\n"); | ||
37 | default: | 40 | default: |
38 | return -EFAULT; | 41 | return -EFAULT; |
39 | } | 42 | } |
@@ -59,28 +62,34 @@ mmc_bus_uevent(struct device *dev, char **envp, int num_envp, char *buf, | |||
59 | int buf_size) | 62 | int buf_size) |
60 | { | 63 | { |
61 | struct mmc_card *card = dev_to_mmc_card(dev); | 64 | struct mmc_card *card = dev_to_mmc_card(dev); |
62 | int retval = 0, i = 0, length = 0; | 65 | const char *type; |
63 | 66 | int i = 0, length = 0; | |
64 | #define add_env(fmt,val) do { \ | ||
65 | retval = add_uevent_var(envp, num_envp, &i, \ | ||
66 | buf, buf_size, &length, \ | ||
67 | fmt, val); \ | ||
68 | if (retval) \ | ||
69 | return retval; \ | ||
70 | } while (0); | ||
71 | 67 | ||
72 | switch (card->type) { | 68 | switch (card->type) { |
73 | case MMC_TYPE_MMC: | 69 | case MMC_TYPE_MMC: |
74 | add_env("MMC_TYPE=%s", "MMC"); | 70 | type = "MMC"; |
75 | break; | 71 | break; |
76 | case MMC_TYPE_SD: | 72 | case MMC_TYPE_SD: |
77 | add_env("MMC_TYPE=%s", "SD"); | 73 | type = "SD"; |
74 | break; | ||
75 | case MMC_TYPE_SDIO: | ||
76 | type = "SDIO"; | ||
78 | break; | 77 | break; |
78 | default: | ||
79 | type = NULL; | ||
79 | } | 80 | } |
80 | 81 | ||
81 | add_env("MMC_NAME=%s", mmc_card_name(card)); | 82 | if (type) { |
83 | if (add_uevent_var(envp, num_envp, &i, | ||
84 | buf, buf_size, &length, | ||
85 | "MMC_TYPE=%s", type)) | ||
86 | return -ENOMEM; | ||
87 | } | ||
82 | 88 | ||
83 | #undef add_env | 89 | if (add_uevent_var(envp, num_envp, &i, |
90 | buf, buf_size, &length, | ||
91 | "MMC_NAME=%s", mmc_card_name(card))) | ||
92 | return -ENOMEM; | ||
84 | 93 | ||
85 | envp[i] = NULL; | 94 | envp[i] = NULL; |
86 | 95 | ||
@@ -176,6 +185,11 @@ static void mmc_release_card(struct device *dev) | |||
176 | { | 185 | { |
177 | struct mmc_card *card = dev_to_mmc_card(dev); | 186 | struct mmc_card *card = dev_to_mmc_card(dev); |
178 | 187 | ||
188 | sdio_free_common_cis(card); | ||
189 | |||
190 | if (card->info) | ||
191 | kfree(card->info); | ||
192 | |||
179 | kfree(card); | 193 | kfree(card); |
180 | } | 194 | } |
181 | 195 | ||
@@ -221,15 +235,25 @@ int mmc_add_card(struct mmc_card *card) | |||
221 | if (mmc_card_blockaddr(card)) | 235 | if (mmc_card_blockaddr(card)) |
222 | type = "SDHC"; | 236 | type = "SDHC"; |
223 | break; | 237 | break; |
238 | case MMC_TYPE_SDIO: | ||
239 | type = "SDIO"; | ||
240 | break; | ||
224 | default: | 241 | default: |
225 | type = "?"; | 242 | type = "?"; |
226 | break; | 243 | break; |
227 | } | 244 | } |
228 | 245 | ||
229 | printk(KERN_INFO "%s: new %s%s card at address %04x\n", | 246 | if (mmc_host_is_spi(card->host)) { |
230 | mmc_hostname(card->host), | 247 | printk(KERN_INFO "%s: new %s%s card on SPI\n", |
231 | mmc_card_highspeed(card) ? "high speed " : "", | 248 | mmc_hostname(card->host), |
232 | type, card->rca); | 249 | mmc_card_highspeed(card) ? "high speed " : "", |
250 | type); | ||
251 | } else { | ||
252 | printk(KERN_INFO "%s: new %s%s card at address %04x\n", | ||
253 | mmc_hostname(card->host), | ||
254 | mmc_card_highspeed(card) ? "high speed " : "", | ||
255 | type, card->rca); | ||
256 | } | ||
233 | 257 | ||
234 | card->dev.uevent_suppress = 1; | 258 | card->dev.uevent_suppress = 1; |
235 | 259 | ||
@@ -261,8 +285,13 @@ int mmc_add_card(struct mmc_card *card) | |||
261 | void mmc_remove_card(struct mmc_card *card) | 285 | void mmc_remove_card(struct mmc_card *card) |
262 | { | 286 | { |
263 | if (mmc_card_present(card)) { | 287 | if (mmc_card_present(card)) { |
264 | printk(KERN_INFO "%s: card %04x removed\n", | 288 | if (mmc_host_is_spi(card->host)) { |
265 | mmc_hostname(card->host), card->rca); | 289 | printk(KERN_INFO "%s: SPI card removed\n", |
290 | mmc_hostname(card->host)); | ||
291 | } else { | ||
292 | printk(KERN_INFO "%s: card %04x removed\n", | ||
293 | mmc_hostname(card->host), card->rca); | ||
294 | } | ||
266 | 295 | ||
267 | if (card->host->bus_ops->sysfs_remove) | 296 | if (card->host->bus_ops->sysfs_remove) |
268 | card->host->bus_ops->sysfs_remove(card->host, card); | 297 | card->host->bus_ops->sysfs_remove(card->host, card); |
diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c index bfd2ae5bd669..09435e0ec680 100644 --- a/drivers/mmc/core/core.c +++ b/drivers/mmc/core/core.c | |||
@@ -18,6 +18,7 @@ | |||
18 | #include <linux/delay.h> | 18 | #include <linux/delay.h> |
19 | #include <linux/pagemap.h> | 19 | #include <linux/pagemap.h> |
20 | #include <linux/err.h> | 20 | #include <linux/err.h> |
21 | #include <linux/leds.h> | ||
21 | #include <asm/scatterlist.h> | 22 | #include <asm/scatterlist.h> |
22 | #include <linux/scatterlist.h> | 23 | #include <linux/scatterlist.h> |
23 | 24 | ||
@@ -29,16 +30,27 @@ | |||
29 | #include "core.h" | 30 | #include "core.h" |
30 | #include "bus.h" | 31 | #include "bus.h" |
31 | #include "host.h" | 32 | #include "host.h" |
33 | #include "sdio_bus.h" | ||
32 | 34 | ||
33 | #include "mmc_ops.h" | 35 | #include "mmc_ops.h" |
34 | #include "sd_ops.h" | 36 | #include "sd_ops.h" |
37 | #include "sdio_ops.h" | ||
35 | 38 | ||
36 | extern int mmc_attach_mmc(struct mmc_host *host, u32 ocr); | 39 | extern int mmc_attach_mmc(struct mmc_host *host, u32 ocr); |
37 | extern int mmc_attach_sd(struct mmc_host *host, u32 ocr); | 40 | extern int mmc_attach_sd(struct mmc_host *host, u32 ocr); |
41 | extern int mmc_attach_sdio(struct mmc_host *host, u32 ocr); | ||
38 | 42 | ||
39 | static struct workqueue_struct *workqueue; | 43 | static struct workqueue_struct *workqueue; |
40 | 44 | ||
41 | /* | 45 | /* |
46 | * Enabling software CRCs on the data blocks can be a significant (30%) | ||
47 | * performance cost, and for other reasons may not always be desired. | ||
48 | * So we allow it it to be disabled. | ||
49 | */ | ||
50 | int use_spi_crc = 1; | ||
51 | module_param(use_spi_crc, bool, 0); | ||
52 | |||
53 | /* | ||
42 | * Internal function. Schedule delayed work in the MMC work queue. | 54 | * Internal function. Schedule delayed work in the MMC work queue. |
43 | */ | 55 | */ |
44 | static int mmc_schedule_delayed_work(struct delayed_work *work, | 56 | static int mmc_schedule_delayed_work(struct delayed_work *work, |
@@ -68,6 +80,11 @@ void mmc_request_done(struct mmc_host *host, struct mmc_request *mrq) | |||
68 | struct mmc_command *cmd = mrq->cmd; | 80 | struct mmc_command *cmd = mrq->cmd; |
69 | int err = cmd->error; | 81 | int err = cmd->error; |
70 | 82 | ||
83 | if (err && cmd->retries && mmc_host_is_spi(host)) { | ||
84 | if (cmd->resp[0] & R1_SPI_ILLEGAL_COMMAND) | ||
85 | cmd->retries = 0; | ||
86 | } | ||
87 | |||
71 | if (err && cmd->retries) { | 88 | if (err && cmd->retries) { |
72 | pr_debug("%s: req failed (CMD%u): %d, retrying...\n", | 89 | pr_debug("%s: req failed (CMD%u): %d, retrying...\n", |
73 | mmc_hostname(host), cmd->opcode, err); | 90 | mmc_hostname(host), cmd->opcode, err); |
@@ -76,6 +93,8 @@ void mmc_request_done(struct mmc_host *host, struct mmc_request *mrq) | |||
76 | cmd->error = 0; | 93 | cmd->error = 0; |
77 | host->ops->request(host, mrq); | 94 | host->ops->request(host, mrq); |
78 | } else { | 95 | } else { |
96 | led_trigger_event(host->led, LED_OFF); | ||
97 | |||
79 | pr_debug("%s: req done (CMD%u): %d: %08x %08x %08x %08x\n", | 98 | pr_debug("%s: req done (CMD%u): %d: %08x %08x %08x %08x\n", |
80 | mmc_hostname(host), cmd->opcode, err, | 99 | mmc_hostname(host), cmd->opcode, err, |
81 | cmd->resp[0], cmd->resp[1], | 100 | cmd->resp[0], cmd->resp[1], |
@@ -118,7 +137,7 @@ mmc_start_request(struct mmc_host *host, struct mmc_request *mrq) | |||
118 | "tsac %d ms nsac %d\n", | 137 | "tsac %d ms nsac %d\n", |
119 | mmc_hostname(host), mrq->data->blksz, | 138 | mmc_hostname(host), mrq->data->blksz, |
120 | mrq->data->blocks, mrq->data->flags, | 139 | mrq->data->blocks, mrq->data->flags, |
121 | mrq->data->timeout_ns / 10000000, | 140 | mrq->data->timeout_ns / 1000000, |
122 | mrq->data->timeout_clks); | 141 | mrq->data->timeout_clks); |
123 | } | 142 | } |
124 | 143 | ||
@@ -130,6 +149,8 @@ mmc_start_request(struct mmc_host *host, struct mmc_request *mrq) | |||
130 | 149 | ||
131 | WARN_ON(!host->claimed); | 150 | WARN_ON(!host->claimed); |
132 | 151 | ||
152 | led_trigger_event(host->led, LED_FULL); | ||
153 | |||
133 | mrq->cmd->error = 0; | 154 | mrq->cmd->error = 0; |
134 | mrq->cmd->mrq = mrq; | 155 | mrq->cmd->mrq = mrq; |
135 | if (mrq->data) { | 156 | if (mrq->data) { |
@@ -199,7 +220,7 @@ int mmc_wait_for_cmd(struct mmc_host *host, struct mmc_command *cmd, int retries | |||
199 | { | 220 | { |
200 | struct mmc_request mrq; | 221 | struct mmc_request mrq; |
201 | 222 | ||
202 | BUG_ON(!host->claimed); | 223 | WARN_ON(!host->claimed); |
203 | 224 | ||
204 | memset(&mrq, 0, sizeof(struct mmc_request)); | 225 | memset(&mrq, 0, sizeof(struct mmc_request)); |
205 | 226 | ||
@@ -220,17 +241,24 @@ EXPORT_SYMBOL(mmc_wait_for_cmd); | |||
220 | * mmc_set_data_timeout - set the timeout for a data command | 241 | * mmc_set_data_timeout - set the timeout for a data command |
221 | * @data: data phase for command | 242 | * @data: data phase for command |
222 | * @card: the MMC card associated with the data transfer | 243 | * @card: the MMC card associated with the data transfer |
223 | * @write: flag to differentiate reads from writes | ||
224 | * | 244 | * |
225 | * Computes the data timeout parameters according to the | 245 | * Computes the data timeout parameters according to the |
226 | * correct algorithm given the card type. | 246 | * correct algorithm given the card type. |
227 | */ | 247 | */ |
228 | void mmc_set_data_timeout(struct mmc_data *data, const struct mmc_card *card, | 248 | void mmc_set_data_timeout(struct mmc_data *data, const struct mmc_card *card) |
229 | int write) | ||
230 | { | 249 | { |
231 | unsigned int mult; | 250 | unsigned int mult; |
232 | 251 | ||
233 | /* | 252 | /* |
253 | * SDIO cards only define an upper 1 s limit on access. | ||
254 | */ | ||
255 | if (mmc_card_sdio(card)) { | ||
256 | data->timeout_ns = 1000000000; | ||
257 | data->timeout_clks = 0; | ||
258 | return; | ||
259 | } | ||
260 | |||
261 | /* | ||
234 | * SD cards use a 100 multiplier rather than 10 | 262 | * SD cards use a 100 multiplier rather than 10 |
235 | */ | 263 | */ |
236 | mult = mmc_card_sd(card) ? 100 : 10; | 264 | mult = mmc_card_sd(card) ? 100 : 10; |
@@ -239,7 +267,7 @@ void mmc_set_data_timeout(struct mmc_data *data, const struct mmc_card *card, | |||
239 | * Scale up the multiplier (and therefore the timeout) by | 267 | * Scale up the multiplier (and therefore the timeout) by |
240 | * the r2w factor for writes. | 268 | * the r2w factor for writes. |
241 | */ | 269 | */ |
242 | if (write) | 270 | if (data->flags & MMC_DATA_WRITE) |
243 | mult <<= card->csd.r2w_factor; | 271 | mult <<= card->csd.r2w_factor; |
244 | 272 | ||
245 | data->timeout_ns = card->csd.tacc_ns * mult; | 273 | data->timeout_ns = card->csd.tacc_ns * mult; |
@@ -255,7 +283,7 @@ void mmc_set_data_timeout(struct mmc_data *data, const struct mmc_card *card, | |||
255 | timeout_us += data->timeout_clks * 1000 / | 283 | timeout_us += data->timeout_clks * 1000 / |
256 | (card->host->ios.clock / 1000); | 284 | (card->host->ios.clock / 1000); |
257 | 285 | ||
258 | if (write) | 286 | if (data->flags & MMC_DATA_WRITE) |
259 | limit_us = 250000; | 287 | limit_us = 250000; |
260 | else | 288 | else |
261 | limit_us = 100000; | 289 | limit_us = 100000; |
@@ -272,15 +300,20 @@ void mmc_set_data_timeout(struct mmc_data *data, const struct mmc_card *card, | |||
272 | EXPORT_SYMBOL(mmc_set_data_timeout); | 300 | EXPORT_SYMBOL(mmc_set_data_timeout); |
273 | 301 | ||
274 | /** | 302 | /** |
275 | * mmc_claim_host - exclusively claim a host | 303 | * __mmc_claim_host - exclusively claim a host |
276 | * @host: mmc host to claim | 304 | * @host: mmc host to claim |
305 | * @abort: whether or not the operation should be aborted | ||
277 | * | 306 | * |
278 | * Claim a host for a set of operations. | 307 | * Claim a host for a set of operations. If @abort is non null and |
308 | * dereference a non-zero value then this will return prematurely with | ||
309 | * that non-zero value without acquiring the lock. Returns zero | ||
310 | * with the lock held otherwise. | ||
279 | */ | 311 | */ |
280 | void mmc_claim_host(struct mmc_host *host) | 312 | int __mmc_claim_host(struct mmc_host *host, atomic_t *abort) |
281 | { | 313 | { |
282 | DECLARE_WAITQUEUE(wait, current); | 314 | DECLARE_WAITQUEUE(wait, current); |
283 | unsigned long flags; | 315 | unsigned long flags; |
316 | int stop; | ||
284 | 317 | ||
285 | might_sleep(); | 318 | might_sleep(); |
286 | 319 | ||
@@ -288,19 +321,24 @@ void mmc_claim_host(struct mmc_host *host) | |||
288 | spin_lock_irqsave(&host->lock, flags); | 321 | spin_lock_irqsave(&host->lock, flags); |
289 | while (1) { | 322 | while (1) { |
290 | set_current_state(TASK_UNINTERRUPTIBLE); | 323 | set_current_state(TASK_UNINTERRUPTIBLE); |
291 | if (!host->claimed) | 324 | stop = abort ? atomic_read(abort) : 0; |
325 | if (stop || !host->claimed) | ||
292 | break; | 326 | break; |
293 | spin_unlock_irqrestore(&host->lock, flags); | 327 | spin_unlock_irqrestore(&host->lock, flags); |
294 | schedule(); | 328 | schedule(); |
295 | spin_lock_irqsave(&host->lock, flags); | 329 | spin_lock_irqsave(&host->lock, flags); |
296 | } | 330 | } |
297 | set_current_state(TASK_RUNNING); | 331 | set_current_state(TASK_RUNNING); |
298 | host->claimed = 1; | 332 | if (!stop) |
333 | host->claimed = 1; | ||
334 | else | ||
335 | wake_up(&host->wq); | ||
299 | spin_unlock_irqrestore(&host->lock, flags); | 336 | spin_unlock_irqrestore(&host->lock, flags); |
300 | remove_wait_queue(&host->wq, &wait); | 337 | remove_wait_queue(&host->wq, &wait); |
338 | return stop; | ||
301 | } | 339 | } |
302 | 340 | ||
303 | EXPORT_SYMBOL(mmc_claim_host); | 341 | EXPORT_SYMBOL(__mmc_claim_host); |
304 | 342 | ||
305 | /** | 343 | /** |
306 | * mmc_release_host - release a host | 344 | * mmc_release_host - release a host |
@@ -313,7 +351,7 @@ void mmc_release_host(struct mmc_host *host) | |||
313 | { | 351 | { |
314 | unsigned long flags; | 352 | unsigned long flags; |
315 | 353 | ||
316 | BUG_ON(!host->claimed); | 354 | WARN_ON(!host->claimed); |
317 | 355 | ||
318 | spin_lock_irqsave(&host->lock, flags); | 356 | spin_lock_irqsave(&host->lock, flags); |
319 | host->claimed = 0; | 357 | host->claimed = 0; |
@@ -433,19 +471,32 @@ static void mmc_power_up(struct mmc_host *host) | |||
433 | int bit = fls(host->ocr_avail) - 1; | 471 | int bit = fls(host->ocr_avail) - 1; |
434 | 472 | ||
435 | host->ios.vdd = bit; | 473 | host->ios.vdd = bit; |
436 | host->ios.bus_mode = MMC_BUSMODE_OPENDRAIN; | 474 | if (mmc_host_is_spi(host)) { |
437 | host->ios.chip_select = MMC_CS_DONTCARE; | 475 | host->ios.chip_select = MMC_CS_HIGH; |
476 | host->ios.bus_mode = MMC_BUSMODE_PUSHPULL; | ||
477 | } else { | ||
478 | host->ios.chip_select = MMC_CS_DONTCARE; | ||
479 | host->ios.bus_mode = MMC_BUSMODE_OPENDRAIN; | ||
480 | } | ||
438 | host->ios.power_mode = MMC_POWER_UP; | 481 | host->ios.power_mode = MMC_POWER_UP; |
439 | host->ios.bus_width = MMC_BUS_WIDTH_1; | 482 | host->ios.bus_width = MMC_BUS_WIDTH_1; |
440 | host->ios.timing = MMC_TIMING_LEGACY; | 483 | host->ios.timing = MMC_TIMING_LEGACY; |
441 | mmc_set_ios(host); | 484 | mmc_set_ios(host); |
442 | 485 | ||
443 | mmc_delay(1); | 486 | /* |
487 | * This delay should be sufficient to allow the power supply | ||
488 | * to reach the minimum voltage. | ||
489 | */ | ||
490 | mmc_delay(2); | ||
444 | 491 | ||
445 | host->ios.clock = host->f_min; | 492 | host->ios.clock = host->f_min; |
446 | host->ios.power_mode = MMC_POWER_ON; | 493 | host->ios.power_mode = MMC_POWER_ON; |
447 | mmc_set_ios(host); | 494 | mmc_set_ios(host); |
448 | 495 | ||
496 | /* | ||
497 | * This delay must be at least 74 clock sizes, or 1 ms, or the | ||
498 | * time required to reach a stable voltage. | ||
499 | */ | ||
449 | mmc_delay(2); | 500 | mmc_delay(2); |
450 | } | 501 | } |
451 | 502 | ||
@@ -453,8 +504,10 @@ static void mmc_power_off(struct mmc_host *host) | |||
453 | { | 504 | { |
454 | host->ios.clock = 0; | 505 | host->ios.clock = 0; |
455 | host->ios.vdd = 0; | 506 | host->ios.vdd = 0; |
456 | host->ios.bus_mode = MMC_BUSMODE_OPENDRAIN; | 507 | if (!mmc_host_is_spi(host)) { |
457 | host->ios.chip_select = MMC_CS_DONTCARE; | 508 | host->ios.bus_mode = MMC_BUSMODE_OPENDRAIN; |
509 | host->ios.chip_select = MMC_CS_DONTCARE; | ||
510 | } | ||
458 | host->ios.power_mode = MMC_POWER_OFF; | 511 | host->ios.power_mode = MMC_POWER_OFF; |
459 | host->ios.bus_width = MMC_BUS_WIDTH_1; | 512 | host->ios.bus_width = MMC_BUS_WIDTH_1; |
460 | host->ios.timing = MMC_TIMING_LEGACY; | 513 | host->ios.timing = MMC_TIMING_LEGACY; |
@@ -511,7 +564,7 @@ void mmc_attach_bus(struct mmc_host *host, const struct mmc_bus_ops *ops) | |||
511 | BUG_ON(!host); | 564 | BUG_ON(!host); |
512 | BUG_ON(!ops); | 565 | BUG_ON(!ops); |
513 | 566 | ||
514 | BUG_ON(!host->claimed); | 567 | WARN_ON(!host->claimed); |
515 | 568 | ||
516 | spin_lock_irqsave(&host->lock, flags); | 569 | spin_lock_irqsave(&host->lock, flags); |
517 | 570 | ||
@@ -535,8 +588,8 @@ void mmc_detach_bus(struct mmc_host *host) | |||
535 | 588 | ||
536 | BUG_ON(!host); | 589 | BUG_ON(!host); |
537 | 590 | ||
538 | BUG_ON(!host->claimed); | 591 | WARN_ON(!host->claimed); |
539 | BUG_ON(!host->bus_ops); | 592 | WARN_ON(!host->bus_ops); |
540 | 593 | ||
541 | spin_lock_irqsave(&host->lock, flags); | 594 | spin_lock_irqsave(&host->lock, flags); |
542 | 595 | ||
@@ -564,7 +617,7 @@ void mmc_detect_change(struct mmc_host *host, unsigned long delay) | |||
564 | #ifdef CONFIG_MMC_DEBUG | 617 | #ifdef CONFIG_MMC_DEBUG |
565 | unsigned long flags; | 618 | unsigned long flags; |
566 | spin_lock_irqsave(&host->lock, flags); | 619 | spin_lock_irqsave(&host->lock, flags); |
567 | BUG_ON(host->removed); | 620 | WARN_ON(host->removed); |
568 | spin_unlock_irqrestore(&host->lock, flags); | 621 | spin_unlock_irqrestore(&host->lock, flags); |
569 | #endif | 622 | #endif |
570 | 623 | ||
@@ -597,24 +650,38 @@ void mmc_rescan(struct work_struct *work) | |||
597 | 650 | ||
598 | mmc_send_if_cond(host, host->ocr_avail); | 651 | mmc_send_if_cond(host, host->ocr_avail); |
599 | 652 | ||
653 | /* | ||
654 | * First we search for SDIO... | ||
655 | */ | ||
656 | err = mmc_send_io_op_cond(host, 0, &ocr); | ||
657 | if (!err) { | ||
658 | if (mmc_attach_sdio(host, ocr)) | ||
659 | mmc_power_off(host); | ||
660 | return; | ||
661 | } | ||
662 | |||
663 | /* | ||
664 | * ...then normal SD... | ||
665 | */ | ||
600 | err = mmc_send_app_op_cond(host, 0, &ocr); | 666 | err = mmc_send_app_op_cond(host, 0, &ocr); |
601 | if (err == MMC_ERR_NONE) { | 667 | if (!err) { |
602 | if (mmc_attach_sd(host, ocr)) | 668 | if (mmc_attach_sd(host, ocr)) |
603 | mmc_power_off(host); | 669 | mmc_power_off(host); |
604 | } else { | 670 | return; |
605 | /* | 671 | } |
606 | * If we fail to detect any SD cards then try | 672 | |
607 | * searching for MMC cards. | 673 | /* |
608 | */ | 674 | * ...and finally MMC. |
609 | err = mmc_send_op_cond(host, 0, &ocr); | 675 | */ |
610 | if (err == MMC_ERR_NONE) { | 676 | err = mmc_send_op_cond(host, 0, &ocr); |
611 | if (mmc_attach_mmc(host, ocr)) | 677 | if (!err) { |
612 | mmc_power_off(host); | 678 | if (mmc_attach_mmc(host, ocr)) |
613 | } else { | ||
614 | mmc_power_off(host); | 679 | mmc_power_off(host); |
615 | mmc_release_host(host); | 680 | return; |
616 | } | ||
617 | } | 681 | } |
682 | |||
683 | mmc_release_host(host); | ||
684 | mmc_power_off(host); | ||
618 | } else { | 685 | } else { |
619 | if (host->bus_ops->detect && !host->bus_dead) | 686 | if (host->bus_ops->detect && !host->bus_dead) |
620 | host->bus_ops->detect(host); | 687 | host->bus_ops->detect(host); |
@@ -725,22 +792,38 @@ static int __init mmc_init(void) | |||
725 | return -ENOMEM; | 792 | return -ENOMEM; |
726 | 793 | ||
727 | ret = mmc_register_bus(); | 794 | ret = mmc_register_bus(); |
728 | if (ret == 0) { | 795 | if (ret) |
729 | ret = mmc_register_host_class(); | 796 | goto destroy_workqueue; |
730 | if (ret) | 797 | |
731 | mmc_unregister_bus(); | 798 | ret = mmc_register_host_class(); |
732 | } | 799 | if (ret) |
800 | goto unregister_bus; | ||
801 | |||
802 | ret = sdio_register_bus(); | ||
803 | if (ret) | ||
804 | goto unregister_host_class; | ||
805 | |||
806 | return 0; | ||
807 | |||
808 | unregister_host_class: | ||
809 | mmc_unregister_host_class(); | ||
810 | unregister_bus: | ||
811 | mmc_unregister_bus(); | ||
812 | destroy_workqueue: | ||
813 | destroy_workqueue(workqueue); | ||
814 | |||
733 | return ret; | 815 | return ret; |
734 | } | 816 | } |
735 | 817 | ||
736 | static void __exit mmc_exit(void) | 818 | static void __exit mmc_exit(void) |
737 | { | 819 | { |
820 | sdio_unregister_bus(); | ||
738 | mmc_unregister_host_class(); | 821 | mmc_unregister_host_class(); |
739 | mmc_unregister_bus(); | 822 | mmc_unregister_bus(); |
740 | destroy_workqueue(workqueue); | 823 | destroy_workqueue(workqueue); |
741 | } | 824 | } |
742 | 825 | ||
743 | module_init(mmc_init); | 826 | subsys_initcall(mmc_init); |
744 | module_exit(mmc_exit); | 827 | module_exit(mmc_exit); |
745 | 828 | ||
746 | MODULE_LICENSE("GPL"); | 829 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/mmc/core/core.h b/drivers/mmc/core/core.h index bb2774af9ea9..39daf2fb5dc4 100644 --- a/drivers/mmc/core/core.h +++ b/drivers/mmc/core/core.h | |||
@@ -48,5 +48,7 @@ void mmc_rescan(struct work_struct *work); | |||
48 | void mmc_start_host(struct mmc_host *host); | 48 | void mmc_start_host(struct mmc_host *host); |
49 | void mmc_stop_host(struct mmc_host *host); | 49 | void mmc_stop_host(struct mmc_host *host); |
50 | 50 | ||
51 | extern int use_spi_crc; | ||
52 | |||
51 | #endif | 53 | #endif |
52 | 54 | ||
diff --git a/drivers/mmc/core/host.c b/drivers/mmc/core/host.c index 2c7ce8f43a9a..64fbc9759a30 100644 --- a/drivers/mmc/core/host.c +++ b/drivers/mmc/core/host.c | |||
@@ -15,6 +15,7 @@ | |||
15 | #include <linux/err.h> | 15 | #include <linux/err.h> |
16 | #include <linux/idr.h> | 16 | #include <linux/idr.h> |
17 | #include <linux/pagemap.h> | 17 | #include <linux/pagemap.h> |
18 | #include <linux/leds.h> | ||
18 | 19 | ||
19 | #include <linux/mmc/host.h> | 20 | #include <linux/mmc/host.h> |
20 | 21 | ||
@@ -100,6 +101,9 @@ int mmc_add_host(struct mmc_host *host) | |||
100 | { | 101 | { |
101 | int err; | 102 | int err; |
102 | 103 | ||
104 | WARN_ON((host->caps & MMC_CAP_SDIO_IRQ) && | ||
105 | !host->ops->enable_sdio_irq); | ||
106 | |||
103 | if (!idr_pre_get(&mmc_host_idr, GFP_KERNEL)) | 107 | if (!idr_pre_get(&mmc_host_idr, GFP_KERNEL)) |
104 | return -ENOMEM; | 108 | return -ENOMEM; |
105 | 109 | ||
@@ -112,6 +116,8 @@ int mmc_add_host(struct mmc_host *host) | |||
112 | snprintf(host->class_dev.bus_id, BUS_ID_SIZE, | 116 | snprintf(host->class_dev.bus_id, BUS_ID_SIZE, |
113 | "mmc%d", host->index); | 117 | "mmc%d", host->index); |
114 | 118 | ||
119 | led_trigger_register_simple(host->class_dev.bus_id, &host->led); | ||
120 | |||
115 | err = device_add(&host->class_dev); | 121 | err = device_add(&host->class_dev); |
116 | if (err) | 122 | if (err) |
117 | return err; | 123 | return err; |
@@ -137,6 +143,8 @@ void mmc_remove_host(struct mmc_host *host) | |||
137 | 143 | ||
138 | device_del(&host->class_dev); | 144 | device_del(&host->class_dev); |
139 | 145 | ||
146 | led_trigger_unregister(host->led); | ||
147 | |||
140 | spin_lock(&mmc_host_lock); | 148 | spin_lock(&mmc_host_lock); |
141 | idr_remove(&mmc_host_idr, host->index); | 149 | idr_remove(&mmc_host_idr, host->index); |
142 | spin_unlock(&mmc_host_lock); | 150 | spin_unlock(&mmc_host_lock); |
diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c index 21d7f48e1d4e..65fe28860f54 100644 --- a/drivers/mmc/core/mmc.c +++ b/drivers/mmc/core/mmc.c | |||
@@ -161,13 +161,12 @@ static int mmc_read_ext_csd(struct mmc_card *card) | |||
161 | { | 161 | { |
162 | int err; | 162 | int err; |
163 | u8 *ext_csd; | 163 | u8 *ext_csd; |
164 | unsigned int ext_csd_struct; | ||
164 | 165 | ||
165 | BUG_ON(!card); | 166 | BUG_ON(!card); |
166 | 167 | ||
167 | err = MMC_ERR_FAILED; | ||
168 | |||
169 | if (card->csd.mmca_vsn < CSD_SPEC_VER_4) | 168 | if (card->csd.mmca_vsn < CSD_SPEC_VER_4) |
170 | return MMC_ERR_NONE; | 169 | return 0; |
171 | 170 | ||
172 | /* | 171 | /* |
173 | * As the ext_csd is so large and mostly unused, we don't store the | 172 | * As the ext_csd is so large and mostly unused, we don't store the |
@@ -176,13 +175,19 @@ static int mmc_read_ext_csd(struct mmc_card *card) | |||
176 | ext_csd = kmalloc(512, GFP_KERNEL); | 175 | ext_csd = kmalloc(512, GFP_KERNEL); |
177 | if (!ext_csd) { | 176 | if (!ext_csd) { |
178 | printk(KERN_ERR "%s: could not allocate a buffer to " | 177 | printk(KERN_ERR "%s: could not allocate a buffer to " |
179 | "receive the ext_csd. mmc v4 cards will be " | 178 | "receive the ext_csd.\n", mmc_hostname(card->host)); |
180 | "treated as v3.\n", mmc_hostname(card->host)); | 179 | return -ENOMEM; |
181 | return MMC_ERR_FAILED; | ||
182 | } | 180 | } |
183 | 181 | ||
184 | err = mmc_send_ext_csd(card, ext_csd); | 182 | err = mmc_send_ext_csd(card, ext_csd); |
185 | if (err != MMC_ERR_NONE) { | 183 | if (err) { |
184 | /* | ||
185 | * We all hosts that cannot perform the command | ||
186 | * to fail more gracefully | ||
187 | */ | ||
188 | if (err != -EINVAL) | ||
189 | goto out; | ||
190 | |||
186 | /* | 191 | /* |
187 | * High capacity cards should have this "magic" size | 192 | * High capacity cards should have this "magic" size |
188 | * stored in their CSD. | 193 | * stored in their CSD. |
@@ -197,18 +202,29 @@ static int mmc_read_ext_csd(struct mmc_card *card) | |||
197 | "EXT_CSD, performance might " | 202 | "EXT_CSD, performance might " |
198 | "suffer.\n", | 203 | "suffer.\n", |
199 | mmc_hostname(card->host)); | 204 | mmc_hostname(card->host)); |
200 | err = MMC_ERR_NONE; | 205 | err = 0; |
201 | } | 206 | } |
207 | |||
202 | goto out; | 208 | goto out; |
203 | } | 209 | } |
204 | 210 | ||
205 | card->ext_csd.sectors = | 211 | ext_csd_struct = ext_csd[EXT_CSD_REV]; |
206 | ext_csd[EXT_CSD_SEC_CNT + 0] << 0 | | 212 | if (ext_csd_struct > 2) { |
207 | ext_csd[EXT_CSD_SEC_CNT + 1] << 8 | | 213 | printk(KERN_ERR "%s: unrecognised EXT_CSD structure " |
208 | ext_csd[EXT_CSD_SEC_CNT + 2] << 16 | | 214 | "version %d\n", mmc_hostname(card->host), |
209 | ext_csd[EXT_CSD_SEC_CNT + 3] << 24; | 215 | ext_csd_struct); |
210 | if (card->ext_csd.sectors) | 216 | return -EINVAL; |
211 | mmc_card_set_blockaddr(card); | 217 | } |
218 | |||
219 | if (ext_csd_struct >= 2) { | ||
220 | card->ext_csd.sectors = | ||
221 | ext_csd[EXT_CSD_SEC_CNT + 0] << 0 | | ||
222 | ext_csd[EXT_CSD_SEC_CNT + 1] << 8 | | ||
223 | ext_csd[EXT_CSD_SEC_CNT + 2] << 16 | | ||
224 | ext_csd[EXT_CSD_SEC_CNT + 3] << 24; | ||
225 | if (card->ext_csd.sectors) | ||
226 | mmc_card_set_blockaddr(card); | ||
227 | } | ||
212 | 228 | ||
213 | switch (ext_csd[EXT_CSD_CARD_TYPE]) { | 229 | switch (ext_csd[EXT_CSD_CARD_TYPE]) { |
214 | case EXT_CSD_CARD_TYPE_52 | EXT_CSD_CARD_TYPE_26: | 230 | case EXT_CSD_CARD_TYPE_52 | EXT_CSD_CARD_TYPE_26: |
@@ -246,7 +262,7 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr, | |||
246 | unsigned int max_dtr; | 262 | unsigned int max_dtr; |
247 | 263 | ||
248 | BUG_ON(!host); | 264 | BUG_ON(!host); |
249 | BUG_ON(!host->claimed); | 265 | WARN_ON(!host->claimed); |
250 | 266 | ||
251 | /* | 267 | /* |
252 | * Since we're changing the OCR value, we seem to | 268 | * Since we're changing the OCR value, we seem to |
@@ -258,19 +274,33 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr, | |||
258 | 274 | ||
259 | /* The extra bit indicates that we support high capacity */ | 275 | /* The extra bit indicates that we support high capacity */ |
260 | err = mmc_send_op_cond(host, ocr | (1 << 30), NULL); | 276 | err = mmc_send_op_cond(host, ocr | (1 << 30), NULL); |
261 | if (err != MMC_ERR_NONE) | 277 | if (err) |
262 | goto err; | 278 | goto err; |
263 | 279 | ||
264 | /* | 280 | /* |
281 | * For SPI, enable CRC as appropriate. | ||
282 | */ | ||
283 | if (mmc_host_is_spi(host)) { | ||
284 | err = mmc_spi_set_crc(host, use_spi_crc); | ||
285 | if (err) | ||
286 | goto err; | ||
287 | } | ||
288 | |||
289 | /* | ||
265 | * Fetch CID from card. | 290 | * Fetch CID from card. |
266 | */ | 291 | */ |
267 | err = mmc_all_send_cid(host, cid); | 292 | if (mmc_host_is_spi(host)) |
268 | if (err != MMC_ERR_NONE) | 293 | err = mmc_send_cid(host, cid); |
294 | else | ||
295 | err = mmc_all_send_cid(host, cid); | ||
296 | if (err) | ||
269 | goto err; | 297 | goto err; |
270 | 298 | ||
271 | if (oldcard) { | 299 | if (oldcard) { |
272 | if (memcmp(cid, oldcard->raw_cid, sizeof(cid)) != 0) | 300 | if (memcmp(cid, oldcard->raw_cid, sizeof(cid)) != 0) { |
301 | err = -ENOENT; | ||
273 | goto err; | 302 | goto err; |
303 | } | ||
274 | 304 | ||
275 | card = oldcard; | 305 | card = oldcard; |
276 | } else { | 306 | } else { |
@@ -278,8 +308,10 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr, | |||
278 | * Allocate card structure. | 308 | * Allocate card structure. |
279 | */ | 309 | */ |
280 | card = mmc_alloc_card(host); | 310 | card = mmc_alloc_card(host); |
281 | if (IS_ERR(card)) | 311 | if (IS_ERR(card)) { |
312 | err = PTR_ERR(card); | ||
282 | goto err; | 313 | goto err; |
314 | } | ||
283 | 315 | ||
284 | card->type = MMC_TYPE_MMC; | 316 | card->type = MMC_TYPE_MMC; |
285 | card->rca = 1; | 317 | card->rca = 1; |
@@ -287,43 +319,47 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr, | |||
287 | } | 319 | } |
288 | 320 | ||
289 | /* | 321 | /* |
290 | * Set card RCA. | 322 | * For native busses: set card RCA and quit open drain mode. |
291 | */ | 323 | */ |
292 | err = mmc_set_relative_addr(card); | 324 | if (!mmc_host_is_spi(host)) { |
293 | if (err != MMC_ERR_NONE) | 325 | err = mmc_set_relative_addr(card); |
294 | goto free_card; | 326 | if (err) |
327 | goto free_card; | ||
295 | 328 | ||
296 | mmc_set_bus_mode(host, MMC_BUSMODE_PUSHPULL); | 329 | mmc_set_bus_mode(host, MMC_BUSMODE_PUSHPULL); |
330 | } | ||
297 | 331 | ||
298 | if (!oldcard) { | 332 | if (!oldcard) { |
299 | /* | 333 | /* |
300 | * Fetch CSD from card. | 334 | * Fetch CSD from card. |
301 | */ | 335 | */ |
302 | err = mmc_send_csd(card, card->raw_csd); | 336 | err = mmc_send_csd(card, card->raw_csd); |
303 | if (err != MMC_ERR_NONE) | 337 | if (err) |
304 | goto free_card; | 338 | goto free_card; |
305 | 339 | ||
306 | err = mmc_decode_csd(card); | 340 | err = mmc_decode_csd(card); |
307 | if (err < 0) | 341 | if (err) |
308 | goto free_card; | 342 | goto free_card; |
309 | err = mmc_decode_cid(card); | 343 | err = mmc_decode_cid(card); |
310 | if (err < 0) | 344 | if (err) |
311 | goto free_card; | 345 | goto free_card; |
312 | } | 346 | } |
313 | 347 | ||
314 | /* | 348 | /* |
315 | * Select card, as all following commands rely on that. | 349 | * Select card, as all following commands rely on that. |
316 | */ | 350 | */ |
317 | err = mmc_select_card(card); | 351 | if (!mmc_host_is_spi(host)) { |
318 | if (err != MMC_ERR_NONE) | 352 | err = mmc_select_card(card); |
319 | goto free_card; | 353 | if (err) |
354 | goto free_card; | ||
355 | } | ||
320 | 356 | ||
321 | if (!oldcard) { | 357 | if (!oldcard) { |
322 | /* | 358 | /* |
323 | * Fetch and process extened CSD. | 359 | * Fetch and process extended CSD. |
324 | */ | 360 | */ |
325 | err = mmc_read_ext_csd(card); | 361 | err = mmc_read_ext_csd(card); |
326 | if (err != MMC_ERR_NONE) | 362 | if (err) |
327 | goto free_card; | 363 | goto free_card; |
328 | } | 364 | } |
329 | 365 | ||
@@ -334,7 +370,7 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr, | |||
334 | (host->caps & MMC_CAP_MMC_HIGHSPEED)) { | 370 | (host->caps & MMC_CAP_MMC_HIGHSPEED)) { |
335 | err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, | 371 | err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, |
336 | EXT_CSD_HS_TIMING, 1); | 372 | EXT_CSD_HS_TIMING, 1); |
337 | if (err != MMC_ERR_NONE) | 373 | if (err) |
338 | goto free_card; | 374 | goto free_card; |
339 | 375 | ||
340 | mmc_card_set_highspeed(card); | 376 | mmc_card_set_highspeed(card); |
@@ -363,7 +399,7 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr, | |||
363 | (host->caps & MMC_CAP_4_BIT_DATA)) { | 399 | (host->caps & MMC_CAP_4_BIT_DATA)) { |
364 | err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, | 400 | err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, |
365 | EXT_CSD_BUS_WIDTH, EXT_CSD_BUS_WIDTH_4); | 401 | EXT_CSD_BUS_WIDTH, EXT_CSD_BUS_WIDTH_4); |
366 | if (err != MMC_ERR_NONE) | 402 | if (err) |
367 | goto free_card; | 403 | goto free_card; |
368 | 404 | ||
369 | mmc_set_bus_width(card->host, MMC_BUS_WIDTH_4); | 405 | mmc_set_bus_width(card->host, MMC_BUS_WIDTH_4); |
@@ -372,14 +408,14 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr, | |||
372 | if (!oldcard) | 408 | if (!oldcard) |
373 | host->card = card; | 409 | host->card = card; |
374 | 410 | ||
375 | return MMC_ERR_NONE; | 411 | return 0; |
376 | 412 | ||
377 | free_card: | 413 | free_card: |
378 | if (!oldcard) | 414 | if (!oldcard) |
379 | mmc_remove_card(card); | 415 | mmc_remove_card(card); |
380 | err: | 416 | err: |
381 | 417 | ||
382 | return MMC_ERR_FAILED; | 418 | return err; |
383 | } | 419 | } |
384 | 420 | ||
385 | /* | 421 | /* |
@@ -413,7 +449,7 @@ static void mmc_detect(struct mmc_host *host) | |||
413 | 449 | ||
414 | mmc_release_host(host); | 450 | mmc_release_host(host); |
415 | 451 | ||
416 | if (err != MMC_ERR_NONE) { | 452 | if (err) { |
417 | mmc_remove(host); | 453 | mmc_remove(host); |
418 | 454 | ||
419 | mmc_claim_host(host); | 455 | mmc_claim_host(host); |
@@ -480,7 +516,8 @@ static void mmc_suspend(struct mmc_host *host) | |||
480 | BUG_ON(!host->card); | 516 | BUG_ON(!host->card); |
481 | 517 | ||
482 | mmc_claim_host(host); | 518 | mmc_claim_host(host); |
483 | mmc_deselect_cards(host); | 519 | if (!mmc_host_is_spi(host)) |
520 | mmc_deselect_cards(host); | ||
484 | host->card->state &= ~MMC_STATE_HIGHSPEED; | 521 | host->card->state &= ~MMC_STATE_HIGHSPEED; |
485 | mmc_release_host(host); | 522 | mmc_release_host(host); |
486 | } | 523 | } |
@@ -502,7 +539,7 @@ static void mmc_resume(struct mmc_host *host) | |||
502 | err = mmc_init_card(host, host->ocr, host->card); | 539 | err = mmc_init_card(host, host->ocr, host->card); |
503 | mmc_release_host(host); | 540 | mmc_release_host(host); |
504 | 541 | ||
505 | if (err != MMC_ERR_NONE) { | 542 | if (err) { |
506 | mmc_remove(host); | 543 | mmc_remove(host); |
507 | 544 | ||
508 | mmc_claim_host(host); | 545 | mmc_claim_host(host); |
@@ -536,11 +573,20 @@ int mmc_attach_mmc(struct mmc_host *host, u32 ocr) | |||
536 | int err; | 573 | int err; |
537 | 574 | ||
538 | BUG_ON(!host); | 575 | BUG_ON(!host); |
539 | BUG_ON(!host->claimed); | 576 | WARN_ON(!host->claimed); |
540 | 577 | ||
541 | mmc_attach_bus(host, &mmc_ops); | 578 | mmc_attach_bus(host, &mmc_ops); |
542 | 579 | ||
543 | /* | 580 | /* |
581 | * We need to get OCR a different way for SPI. | ||
582 | */ | ||
583 | if (mmc_host_is_spi(host)) { | ||
584 | err = mmc_spi_read_ocr(host, 1, &ocr); | ||
585 | if (err) | ||
586 | goto err; | ||
587 | } | ||
588 | |||
589 | /* | ||
544 | * Sanity check the voltages that the card claims to | 590 | * Sanity check the voltages that the card claims to |
545 | * support. | 591 | * support. |
546 | */ | 592 | */ |
@@ -565,7 +611,7 @@ int mmc_attach_mmc(struct mmc_host *host, u32 ocr) | |||
565 | * Detect and init the card. | 611 | * Detect and init the card. |
566 | */ | 612 | */ |
567 | err = mmc_init_card(host, host->ocr, NULL); | 613 | err = mmc_init_card(host, host->ocr, NULL); |
568 | if (err != MMC_ERR_NONE) | 614 | if (err) |
569 | goto err; | 615 | goto err; |
570 | 616 | ||
571 | mmc_release_host(host); | 617 | mmc_release_host(host); |
@@ -587,6 +633,6 @@ err: | |||
587 | printk(KERN_ERR "%s: error %d whilst initialising MMC card\n", | 633 | printk(KERN_ERR "%s: error %d whilst initialising MMC card\n", |
588 | mmc_hostname(host), err); | 634 | mmc_hostname(host), err); |
589 | 635 | ||
590 | return 0; | 636 | return err; |
591 | } | 637 | } |
592 | 638 | ||
diff --git a/drivers/mmc/core/mmc_ops.c b/drivers/mmc/core/mmc_ops.c index 913e75f00843..bf4bc6adcfef 100644 --- a/drivers/mmc/core/mmc_ops.c +++ b/drivers/mmc/core/mmc_ops.c | |||
@@ -40,10 +40,10 @@ static int _mmc_select_card(struct mmc_host *host, struct mmc_card *card) | |||
40 | } | 40 | } |
41 | 41 | ||
42 | err = mmc_wait_for_cmd(host, &cmd, MMC_CMD_RETRIES); | 42 | err = mmc_wait_for_cmd(host, &cmd, MMC_CMD_RETRIES); |
43 | if (err != MMC_ERR_NONE) | 43 | if (err) |
44 | return err; | 44 | return err; |
45 | 45 | ||
46 | return MMC_ERR_NONE; | 46 | return 0; |
47 | } | 47 | } |
48 | 48 | ||
49 | int mmc_select_card(struct mmc_card *card) | 49 | int mmc_select_card(struct mmc_card *card) |
@@ -63,23 +63,36 @@ int mmc_go_idle(struct mmc_host *host) | |||
63 | int err; | 63 | int err; |
64 | struct mmc_command cmd; | 64 | struct mmc_command cmd; |
65 | 65 | ||
66 | mmc_set_chip_select(host, MMC_CS_HIGH); | 66 | /* |
67 | 67 | * Non-SPI hosts need to prevent chipselect going active during | |
68 | mmc_delay(1); | 68 | * GO_IDLE; that would put chips into SPI mode. Remind them of |
69 | * that in case of hardware that won't pull up DAT3/nCS otherwise. | ||
70 | * | ||
71 | * SPI hosts ignore ios.chip_select; it's managed according to | ||
72 | * rules that must accomodate non-MMC slaves which this layer | ||
73 | * won't even know about. | ||
74 | */ | ||
75 | if (!mmc_host_is_spi(host)) { | ||
76 | mmc_set_chip_select(host, MMC_CS_HIGH); | ||
77 | mmc_delay(1); | ||
78 | } | ||
69 | 79 | ||
70 | memset(&cmd, 0, sizeof(struct mmc_command)); | 80 | memset(&cmd, 0, sizeof(struct mmc_command)); |
71 | 81 | ||
72 | cmd.opcode = MMC_GO_IDLE_STATE; | 82 | cmd.opcode = MMC_GO_IDLE_STATE; |
73 | cmd.arg = 0; | 83 | cmd.arg = 0; |
74 | cmd.flags = MMC_RSP_NONE | MMC_CMD_BC; | 84 | cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_NONE | MMC_CMD_BC; |
75 | 85 | ||
76 | err = mmc_wait_for_cmd(host, &cmd, 0); | 86 | err = mmc_wait_for_cmd(host, &cmd, 0); |
77 | 87 | ||
78 | mmc_delay(1); | 88 | mmc_delay(1); |
79 | 89 | ||
80 | mmc_set_chip_select(host, MMC_CS_DONTCARE); | 90 | if (!mmc_host_is_spi(host)) { |
91 | mmc_set_chip_select(host, MMC_CS_DONTCARE); | ||
92 | mmc_delay(1); | ||
93 | } | ||
81 | 94 | ||
82 | mmc_delay(1); | 95 | host->use_spi_crc = 0; |
83 | 96 | ||
84 | return err; | 97 | return err; |
85 | } | 98 | } |
@@ -94,23 +107,33 @@ int mmc_send_op_cond(struct mmc_host *host, u32 ocr, u32 *rocr) | |||
94 | memset(&cmd, 0, sizeof(struct mmc_command)); | 107 | memset(&cmd, 0, sizeof(struct mmc_command)); |
95 | 108 | ||
96 | cmd.opcode = MMC_SEND_OP_COND; | 109 | cmd.opcode = MMC_SEND_OP_COND; |
97 | cmd.arg = ocr; | 110 | cmd.arg = mmc_host_is_spi(host) ? 0 : ocr; |
98 | cmd.flags = MMC_RSP_R3 | MMC_CMD_BCR; | 111 | cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R3 | MMC_CMD_BCR; |
99 | 112 | ||
100 | for (i = 100; i; i--) { | 113 | for (i = 100; i; i--) { |
101 | err = mmc_wait_for_cmd(host, &cmd, 0); | 114 | err = mmc_wait_for_cmd(host, &cmd, 0); |
102 | if (err != MMC_ERR_NONE) | 115 | if (err) |
103 | break; | 116 | break; |
104 | 117 | ||
105 | if (cmd.resp[0] & MMC_CARD_BUSY || ocr == 0) | 118 | /* if we're just probing, do a single pass */ |
119 | if (ocr == 0) | ||
106 | break; | 120 | break; |
107 | 121 | ||
108 | err = MMC_ERR_TIMEOUT; | 122 | /* otherwise wait until reset completes */ |
123 | if (mmc_host_is_spi(host)) { | ||
124 | if (!(cmd.resp[0] & R1_SPI_IDLE)) | ||
125 | break; | ||
126 | } else { | ||
127 | if (cmd.resp[0] & MMC_CARD_BUSY) | ||
128 | break; | ||
129 | } | ||
130 | |||
131 | err = -ETIMEDOUT; | ||
109 | 132 | ||
110 | mmc_delay(10); | 133 | mmc_delay(10); |
111 | } | 134 | } |
112 | 135 | ||
113 | if (rocr) | 136 | if (rocr && !mmc_host_is_spi(host)) |
114 | *rocr = cmd.resp[0]; | 137 | *rocr = cmd.resp[0]; |
115 | 138 | ||
116 | return err; | 139 | return err; |
@@ -131,12 +154,12 @@ int mmc_all_send_cid(struct mmc_host *host, u32 *cid) | |||
131 | cmd.flags = MMC_RSP_R2 | MMC_CMD_BCR; | 154 | cmd.flags = MMC_RSP_R2 | MMC_CMD_BCR; |
132 | 155 | ||
133 | err = mmc_wait_for_cmd(host, &cmd, MMC_CMD_RETRIES); | 156 | err = mmc_wait_for_cmd(host, &cmd, MMC_CMD_RETRIES); |
134 | if (err != MMC_ERR_NONE) | 157 | if (err) |
135 | return err; | 158 | return err; |
136 | 159 | ||
137 | memcpy(cid, cmd.resp, sizeof(u32) * 4); | 160 | memcpy(cid, cmd.resp, sizeof(u32) * 4); |
138 | 161 | ||
139 | return MMC_ERR_NONE; | 162 | return 0; |
140 | } | 163 | } |
141 | 164 | ||
142 | int mmc_set_relative_addr(struct mmc_card *card) | 165 | int mmc_set_relative_addr(struct mmc_card *card) |
@@ -154,46 +177,52 @@ int mmc_set_relative_addr(struct mmc_card *card) | |||
154 | cmd.flags = MMC_RSP_R1 | MMC_CMD_AC; | 177 | cmd.flags = MMC_RSP_R1 | MMC_CMD_AC; |
155 | 178 | ||
156 | err = mmc_wait_for_cmd(card->host, &cmd, MMC_CMD_RETRIES); | 179 | err = mmc_wait_for_cmd(card->host, &cmd, MMC_CMD_RETRIES); |
157 | if (err != MMC_ERR_NONE) | 180 | if (err) |
158 | return err; | 181 | return err; |
159 | 182 | ||
160 | return MMC_ERR_NONE; | 183 | return 0; |
161 | } | 184 | } |
162 | 185 | ||
163 | int mmc_send_csd(struct mmc_card *card, u32 *csd) | 186 | static int |
187 | mmc_send_cxd_native(struct mmc_host *host, u32 arg, u32 *cxd, int opcode) | ||
164 | { | 188 | { |
165 | int err; | 189 | int err; |
166 | struct mmc_command cmd; | 190 | struct mmc_command cmd; |
167 | 191 | ||
168 | BUG_ON(!card); | 192 | BUG_ON(!host); |
169 | BUG_ON(!card->host); | 193 | BUG_ON(!cxd); |
170 | BUG_ON(!csd); | ||
171 | 194 | ||
172 | memset(&cmd, 0, sizeof(struct mmc_command)); | 195 | memset(&cmd, 0, sizeof(struct mmc_command)); |
173 | 196 | ||
174 | cmd.opcode = MMC_SEND_CSD; | 197 | cmd.opcode = opcode; |
175 | cmd.arg = card->rca << 16; | 198 | cmd.arg = arg; |
176 | cmd.flags = MMC_RSP_R2 | MMC_CMD_AC; | 199 | cmd.flags = MMC_RSP_R2 | MMC_CMD_AC; |
177 | 200 | ||
178 | err = mmc_wait_for_cmd(card->host, &cmd, MMC_CMD_RETRIES); | 201 | err = mmc_wait_for_cmd(host, &cmd, MMC_CMD_RETRIES); |
179 | if (err != MMC_ERR_NONE) | 202 | if (err) |
180 | return err; | 203 | return err; |
181 | 204 | ||
182 | memcpy(csd, cmd.resp, sizeof(u32) * 4); | 205 | memcpy(cxd, cmd.resp, sizeof(u32) * 4); |
183 | 206 | ||
184 | return MMC_ERR_NONE; | 207 | return 0; |
185 | } | 208 | } |
186 | 209 | ||
187 | int mmc_send_ext_csd(struct mmc_card *card, u8 *ext_csd) | 210 | static int |
211 | mmc_send_cxd_data(struct mmc_card *card, struct mmc_host *host, | ||
212 | u32 opcode, void *buf, unsigned len) | ||
188 | { | 213 | { |
189 | struct mmc_request mrq; | 214 | struct mmc_request mrq; |
190 | struct mmc_command cmd; | 215 | struct mmc_command cmd; |
191 | struct mmc_data data; | 216 | struct mmc_data data; |
192 | struct scatterlist sg; | 217 | struct scatterlist sg; |
218 | void *data_buf; | ||
193 | 219 | ||
194 | BUG_ON(!card); | 220 | /* dma onto stack is unsafe/nonportable, but callers to this |
195 | BUG_ON(!card->host); | 221 | * routine normally provide temporary on-stack buffers ... |
196 | BUG_ON(!ext_csd); | 222 | */ |
223 | data_buf = kmalloc(len, GFP_KERNEL); | ||
224 | if (data_buf == NULL) | ||
225 | return -ENOMEM; | ||
197 | 226 | ||
198 | memset(&mrq, 0, sizeof(struct mmc_request)); | 227 | memset(&mrq, 0, sizeof(struct mmc_request)); |
199 | memset(&cmd, 0, sizeof(struct mmc_command)); | 228 | memset(&cmd, 0, sizeof(struct mmc_command)); |
@@ -202,28 +231,99 @@ int mmc_send_ext_csd(struct mmc_card *card, u8 *ext_csd) | |||
202 | mrq.cmd = &cmd; | 231 | mrq.cmd = &cmd; |
203 | mrq.data = &data; | 232 | mrq.data = &data; |
204 | 233 | ||
205 | cmd.opcode = MMC_SEND_EXT_CSD; | 234 | cmd.opcode = opcode; |
206 | cmd.arg = 0; | 235 | cmd.arg = 0; |
207 | cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC; | ||
208 | 236 | ||
209 | data.blksz = 512; | 237 | /* NOTE HACK: the MMC_RSP_SPI_R1 is always correct here, but we |
238 | * rely on callers to never use this with "native" calls for reading | ||
239 | * CSD or CID. Native versions of those commands use the R2 type, | ||
240 | * not R1 plus a data block. | ||
241 | */ | ||
242 | cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_ADTC; | ||
243 | |||
244 | data.blksz = len; | ||
210 | data.blocks = 1; | 245 | data.blocks = 1; |
211 | data.flags = MMC_DATA_READ; | 246 | data.flags = MMC_DATA_READ; |
212 | data.sg = &sg; | 247 | data.sg = &sg; |
213 | data.sg_len = 1; | 248 | data.sg_len = 1; |
214 | 249 | ||
215 | sg_init_one(&sg, ext_csd, 512); | 250 | sg_init_one(&sg, data_buf, len); |
216 | 251 | ||
217 | mmc_set_data_timeout(&data, card, 0); | 252 | if (card) |
253 | mmc_set_data_timeout(&data, card); | ||
218 | 254 | ||
219 | mmc_wait_for_req(card->host, &mrq); | 255 | mmc_wait_for_req(host, &mrq); |
220 | 256 | ||
221 | if (cmd.error != MMC_ERR_NONE) | 257 | memcpy(buf, data_buf, len); |
258 | kfree(data_buf); | ||
259 | |||
260 | if (cmd.error) | ||
222 | return cmd.error; | 261 | return cmd.error; |
223 | if (data.error != MMC_ERR_NONE) | 262 | if (data.error) |
224 | return data.error; | 263 | return data.error; |
225 | 264 | ||
226 | return MMC_ERR_NONE; | 265 | return 0; |
266 | } | ||
267 | |||
268 | int mmc_send_csd(struct mmc_card *card, u32 *csd) | ||
269 | { | ||
270 | if (!mmc_host_is_spi(card->host)) | ||
271 | return mmc_send_cxd_native(card->host, card->rca << 16, | ||
272 | csd, MMC_SEND_CSD); | ||
273 | |||
274 | return mmc_send_cxd_data(card, card->host, MMC_SEND_CSD, csd, 16); | ||
275 | } | ||
276 | |||
277 | int mmc_send_cid(struct mmc_host *host, u32 *cid) | ||
278 | { | ||
279 | if (!mmc_host_is_spi(host)) { | ||
280 | if (!host->card) | ||
281 | return -EINVAL; | ||
282 | return mmc_send_cxd_native(host, host->card->rca << 16, | ||
283 | cid, MMC_SEND_CID); | ||
284 | } | ||
285 | |||
286 | return mmc_send_cxd_data(NULL, host, MMC_SEND_CID, cid, 16); | ||
287 | } | ||
288 | |||
289 | int mmc_send_ext_csd(struct mmc_card *card, u8 *ext_csd) | ||
290 | { | ||
291 | return mmc_send_cxd_data(card, card->host, MMC_SEND_EXT_CSD, | ||
292 | ext_csd, 512); | ||
293 | } | ||
294 | |||
295 | int mmc_spi_read_ocr(struct mmc_host *host, int highcap, u32 *ocrp) | ||
296 | { | ||
297 | struct mmc_command cmd; | ||
298 | int err; | ||
299 | |||
300 | memset(&cmd, 0, sizeof(struct mmc_command)); | ||
301 | |||
302 | cmd.opcode = MMC_SPI_READ_OCR; | ||
303 | cmd.arg = highcap ? (1 << 30) : 0; | ||
304 | cmd.flags = MMC_RSP_SPI_R3; | ||
305 | |||
306 | err = mmc_wait_for_cmd(host, &cmd, 0); | ||
307 | |||
308 | *ocrp = cmd.resp[1]; | ||
309 | return err; | ||
310 | } | ||
311 | |||
312 | int mmc_spi_set_crc(struct mmc_host *host, int use_crc) | ||
313 | { | ||
314 | struct mmc_command cmd; | ||
315 | int err; | ||
316 | |||
317 | memset(&cmd, 0, sizeof(struct mmc_command)); | ||
318 | |||
319 | cmd.opcode = MMC_SPI_CRC_ON_OFF; | ||
320 | cmd.flags = MMC_RSP_SPI_R1; | ||
321 | cmd.arg = use_crc; | ||
322 | |||
323 | err = mmc_wait_for_cmd(host, &cmd, 0); | ||
324 | if (!err) | ||
325 | host->use_spi_crc = use_crc; | ||
326 | return err; | ||
227 | } | 327 | } |
228 | 328 | ||
229 | int mmc_switch(struct mmc_card *card, u8 set, u8 index, u8 value) | 329 | int mmc_switch(struct mmc_card *card, u8 set, u8 index, u8 value) |
@@ -241,13 +341,13 @@ int mmc_switch(struct mmc_card *card, u8 set, u8 index, u8 value) | |||
241 | (index << 16) | | 341 | (index << 16) | |
242 | (value << 8) | | 342 | (value << 8) | |
243 | set; | 343 | set; |
244 | cmd.flags = MMC_RSP_R1B | MMC_CMD_AC; | 344 | cmd.flags = MMC_RSP_SPI_R1B | MMC_RSP_R1B | MMC_CMD_AC; |
245 | 345 | ||
246 | err = mmc_wait_for_cmd(card->host, &cmd, MMC_CMD_RETRIES); | 346 | err = mmc_wait_for_cmd(card->host, &cmd, MMC_CMD_RETRIES); |
247 | if (err != MMC_ERR_NONE) | 347 | if (err) |
248 | return err; | 348 | return err; |
249 | 349 | ||
250 | return MMC_ERR_NONE; | 350 | return 0; |
251 | } | 351 | } |
252 | 352 | ||
253 | int mmc_send_status(struct mmc_card *card, u32 *status) | 353 | int mmc_send_status(struct mmc_card *card, u32 *status) |
@@ -261,16 +361,20 @@ int mmc_send_status(struct mmc_card *card, u32 *status) | |||
261 | memset(&cmd, 0, sizeof(struct mmc_command)); | 361 | memset(&cmd, 0, sizeof(struct mmc_command)); |
262 | 362 | ||
263 | cmd.opcode = MMC_SEND_STATUS; | 363 | cmd.opcode = MMC_SEND_STATUS; |
264 | cmd.arg = card->rca << 16; | 364 | if (!mmc_host_is_spi(card->host)) |
265 | cmd.flags = MMC_RSP_R1 | MMC_CMD_AC; | 365 | cmd.arg = card->rca << 16; |
366 | cmd.flags = MMC_RSP_SPI_R2 | MMC_RSP_R1 | MMC_CMD_AC; | ||
266 | 367 | ||
267 | err = mmc_wait_for_cmd(card->host, &cmd, MMC_CMD_RETRIES); | 368 | err = mmc_wait_for_cmd(card->host, &cmd, MMC_CMD_RETRIES); |
268 | if (err != MMC_ERR_NONE) | 369 | if (err) |
269 | return err; | 370 | return err; |
270 | 371 | ||
372 | /* NOTE: callers are required to understand the difference | ||
373 | * between "native" and SPI format status words! | ||
374 | */ | ||
271 | if (status) | 375 | if (status) |
272 | *status = cmd.resp[0]; | 376 | *status = cmd.resp[0]; |
273 | 377 | ||
274 | return MMC_ERR_NONE; | 378 | return 0; |
275 | } | 379 | } |
276 | 380 | ||
diff --git a/drivers/mmc/core/mmc_ops.h b/drivers/mmc/core/mmc_ops.h index 76d09a93c5d6..17854bf7cf0d 100644 --- a/drivers/mmc/core/mmc_ops.h +++ b/drivers/mmc/core/mmc_ops.h | |||
@@ -22,6 +22,9 @@ int mmc_send_csd(struct mmc_card *card, u32 *csd); | |||
22 | int mmc_send_ext_csd(struct mmc_card *card, u8 *ext_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); | 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); | 24 | int mmc_send_status(struct mmc_card *card, u32 *status); |
25 | int mmc_send_cid(struct mmc_host *host, u32 *cid); | ||
26 | int mmc_spi_read_ocr(struct mmc_host *host, int highcap, u32 *ocrp); | ||
27 | int mmc_spi_set_crc(struct mmc_host *host, int use_crc); | ||
25 | 28 | ||
26 | #endif | 29 | #endif |
27 | 30 | ||
diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c index 1edc62b1e5c6..d1c1e0f592f1 100644 --- a/drivers/mmc/core/sd.c +++ b/drivers/mmc/core/sd.c | |||
@@ -166,8 +166,6 @@ static int mmc_decode_scr(struct mmc_card *card) | |||
166 | unsigned int scr_struct; | 166 | unsigned int scr_struct; |
167 | u32 resp[4]; | 167 | u32 resp[4]; |
168 | 168 | ||
169 | BUG_ON(!mmc_card_sd(card)); | ||
170 | |||
171 | resp[3] = card->raw_scr[1]; | 169 | resp[3] = card->raw_scr[1]; |
172 | resp[2] = card->raw_scr[0]; | 170 | resp[2] = card->raw_scr[0]; |
173 | 171 | ||
@@ -193,30 +191,38 @@ static int mmc_read_switch(struct mmc_card *card) | |||
193 | u8 *status; | 191 | u8 *status; |
194 | 192 | ||
195 | if (card->scr.sda_vsn < SCR_SPEC_VER_1) | 193 | if (card->scr.sda_vsn < SCR_SPEC_VER_1) |
196 | return MMC_ERR_NONE; | 194 | return 0; |
197 | 195 | ||
198 | if (!(card->csd.cmdclass & CCC_SWITCH)) { | 196 | if (!(card->csd.cmdclass & CCC_SWITCH)) { |
199 | printk(KERN_WARNING "%s: card lacks mandatory switch " | 197 | printk(KERN_WARNING "%s: card lacks mandatory switch " |
200 | "function, performance might suffer.\n", | 198 | "function, performance might suffer.\n", |
201 | mmc_hostname(card->host)); | 199 | mmc_hostname(card->host)); |
202 | return MMC_ERR_NONE; | 200 | return 0; |
203 | } | 201 | } |
204 | 202 | ||
205 | err = MMC_ERR_FAILED; | 203 | err = -EIO; |
206 | 204 | ||
207 | status = kmalloc(64, GFP_KERNEL); | 205 | status = kmalloc(64, GFP_KERNEL); |
208 | if (!status) { | 206 | if (!status) { |
209 | printk(KERN_ERR "%s: could not allocate a buffer for " | 207 | printk(KERN_ERR "%s: could not allocate a buffer for " |
210 | "switch capabilities.\n", mmc_hostname(card->host)); | 208 | "switch capabilities.\n", mmc_hostname(card->host)); |
211 | return err; | 209 | return -ENOMEM; |
212 | } | 210 | } |
213 | 211 | ||
214 | err = mmc_sd_switch(card, 0, 0, 1, status); | 212 | err = mmc_sd_switch(card, 0, 0, 1, status); |
215 | if (err != MMC_ERR_NONE) { | 213 | if (err) { |
214 | /* | ||
215 | * We all hosts that cannot perform the command | ||
216 | * to fail more gracefully | ||
217 | */ | ||
218 | if (err != -EINVAL) | ||
219 | goto out; | ||
220 | |||
216 | printk(KERN_WARNING "%s: problem reading switch " | 221 | printk(KERN_WARNING "%s: problem reading switch " |
217 | "capabilities, performance might suffer.\n", | 222 | "capabilities, performance might suffer.\n", |
218 | mmc_hostname(card->host)); | 223 | mmc_hostname(card->host)); |
219 | err = MMC_ERR_NONE; | 224 | err = 0; |
225 | |||
220 | goto out; | 226 | goto out; |
221 | } | 227 | } |
222 | 228 | ||
@@ -238,28 +244,28 @@ static int mmc_switch_hs(struct mmc_card *card) | |||
238 | u8 *status; | 244 | u8 *status; |
239 | 245 | ||
240 | if (card->scr.sda_vsn < SCR_SPEC_VER_1) | 246 | if (card->scr.sda_vsn < SCR_SPEC_VER_1) |
241 | return MMC_ERR_NONE; | 247 | return 0; |
242 | 248 | ||
243 | if (!(card->csd.cmdclass & CCC_SWITCH)) | 249 | if (!(card->csd.cmdclass & CCC_SWITCH)) |
244 | return MMC_ERR_NONE; | 250 | return 0; |
245 | 251 | ||
246 | if (!(card->host->caps & MMC_CAP_SD_HIGHSPEED)) | 252 | if (!(card->host->caps & MMC_CAP_SD_HIGHSPEED)) |
247 | return MMC_ERR_NONE; | 253 | return 0; |
248 | 254 | ||
249 | if (card->sw_caps.hs_max_dtr == 0) | 255 | if (card->sw_caps.hs_max_dtr == 0) |
250 | return MMC_ERR_NONE; | 256 | return 0; |
251 | 257 | ||
252 | err = MMC_ERR_FAILED; | 258 | err = -EIO; |
253 | 259 | ||
254 | status = kmalloc(64, GFP_KERNEL); | 260 | status = kmalloc(64, GFP_KERNEL); |
255 | if (!status) { | 261 | if (!status) { |
256 | printk(KERN_ERR "%s: could not allocate a buffer for " | 262 | printk(KERN_ERR "%s: could not allocate a buffer for " |
257 | "switch capabilities.\n", mmc_hostname(card->host)); | 263 | "switch capabilities.\n", mmc_hostname(card->host)); |
258 | return err; | 264 | return -ENOMEM; |
259 | } | 265 | } |
260 | 266 | ||
261 | err = mmc_sd_switch(card, 1, 0, 1, status); | 267 | err = mmc_sd_switch(card, 1, 0, 1, status); |
262 | if (err != MMC_ERR_NONE) | 268 | if (err) |
263 | goto out; | 269 | goto out; |
264 | 270 | ||
265 | if ((status[16] & 0xF) != 1) { | 271 | if ((status[16] & 0xF) != 1) { |
@@ -292,7 +298,7 @@ static int mmc_sd_init_card(struct mmc_host *host, u32 ocr, | |||
292 | unsigned int max_dtr; | 298 | unsigned int max_dtr; |
293 | 299 | ||
294 | BUG_ON(!host); | 300 | BUG_ON(!host); |
295 | BUG_ON(!host->claimed); | 301 | WARN_ON(!host->claimed); |
296 | 302 | ||
297 | /* | 303 | /* |
298 | * Since we're changing the OCR value, we seem to | 304 | * Since we're changing the OCR value, we seem to |
@@ -309,23 +315,37 @@ static int mmc_sd_init_card(struct mmc_host *host, u32 ocr, | |||
309 | * block-addressed SDHC cards. | 315 | * block-addressed SDHC cards. |
310 | */ | 316 | */ |
311 | err = mmc_send_if_cond(host, ocr); | 317 | err = mmc_send_if_cond(host, ocr); |
312 | if (err == MMC_ERR_NONE) | 318 | if (!err) |
313 | ocr |= 1 << 30; | 319 | ocr |= 1 << 30; |
314 | 320 | ||
315 | err = mmc_send_app_op_cond(host, ocr, NULL); | 321 | err = mmc_send_app_op_cond(host, ocr, NULL); |
316 | if (err != MMC_ERR_NONE) | 322 | if (err) |
317 | goto err; | 323 | goto err; |
318 | 324 | ||
319 | /* | 325 | /* |
326 | * For SPI, enable CRC as appropriate. | ||
327 | */ | ||
328 | if (mmc_host_is_spi(host)) { | ||
329 | err = mmc_spi_set_crc(host, use_spi_crc); | ||
330 | if (err) | ||
331 | goto err; | ||
332 | } | ||
333 | |||
334 | /* | ||
320 | * Fetch CID from card. | 335 | * Fetch CID from card. |
321 | */ | 336 | */ |
322 | err = mmc_all_send_cid(host, cid); | 337 | if (mmc_host_is_spi(host)) |
323 | if (err != MMC_ERR_NONE) | 338 | err = mmc_send_cid(host, cid); |
339 | else | ||
340 | err = mmc_all_send_cid(host, cid); | ||
341 | if (err) | ||
324 | goto err; | 342 | goto err; |
325 | 343 | ||
326 | if (oldcard) { | 344 | if (oldcard) { |
327 | if (memcmp(cid, oldcard->raw_cid, sizeof(cid)) != 0) | 345 | if (memcmp(cid, oldcard->raw_cid, sizeof(cid)) != 0) { |
346 | err = -ENOENT; | ||
328 | goto err; | 347 | goto err; |
348 | } | ||
329 | 349 | ||
330 | card = oldcard; | 350 | card = oldcard; |
331 | } else { | 351 | } else { |
@@ -333,32 +353,36 @@ static int mmc_sd_init_card(struct mmc_host *host, u32 ocr, | |||
333 | * Allocate card structure. | 353 | * Allocate card structure. |
334 | */ | 354 | */ |
335 | card = mmc_alloc_card(host); | 355 | card = mmc_alloc_card(host); |
336 | if (IS_ERR(card)) | 356 | if (IS_ERR(card)) { |
357 | err = PTR_ERR(card); | ||
337 | goto err; | 358 | goto err; |
359 | } | ||
338 | 360 | ||
339 | card->type = MMC_TYPE_SD; | 361 | card->type = MMC_TYPE_SD; |
340 | memcpy(card->raw_cid, cid, sizeof(card->raw_cid)); | 362 | memcpy(card->raw_cid, cid, sizeof(card->raw_cid)); |
341 | } | 363 | } |
342 | 364 | ||
343 | /* | 365 | /* |
344 | * Set card RCA. | 366 | * For native busses: get card RCA and quit open drain mode. |
345 | */ | 367 | */ |
346 | err = mmc_send_relative_addr(host, &card->rca); | 368 | if (!mmc_host_is_spi(host)) { |
347 | if (err != MMC_ERR_NONE) | 369 | err = mmc_send_relative_addr(host, &card->rca); |
348 | goto free_card; | 370 | if (err) |
371 | goto free_card; | ||
349 | 372 | ||
350 | mmc_set_bus_mode(host, MMC_BUSMODE_PUSHPULL); | 373 | mmc_set_bus_mode(host, MMC_BUSMODE_PUSHPULL); |
374 | } | ||
351 | 375 | ||
352 | if (!oldcard) { | 376 | if (!oldcard) { |
353 | /* | 377 | /* |
354 | * Fetch CSD from card. | 378 | * Fetch CSD from card. |
355 | */ | 379 | */ |
356 | err = mmc_send_csd(card, card->raw_csd); | 380 | err = mmc_send_csd(card, card->raw_csd); |
357 | if (err != MMC_ERR_NONE) | 381 | if (err) |
358 | goto free_card; | 382 | goto free_card; |
359 | 383 | ||
360 | err = mmc_decode_csd(card); | 384 | err = mmc_decode_csd(card); |
361 | if (err < 0) | 385 | if (err) |
362 | goto free_card; | 386 | goto free_card; |
363 | 387 | ||
364 | mmc_decode_cid(card); | 388 | mmc_decode_cid(card); |
@@ -367,16 +391,18 @@ static int mmc_sd_init_card(struct mmc_host *host, u32 ocr, | |||
367 | /* | 391 | /* |
368 | * Select card, as all following commands rely on that. | 392 | * Select card, as all following commands rely on that. |
369 | */ | 393 | */ |
370 | err = mmc_select_card(card); | 394 | if (!mmc_host_is_spi(host)) { |
371 | if (err != MMC_ERR_NONE) | 395 | err = mmc_select_card(card); |
372 | goto free_card; | 396 | if (err) |
397 | goto free_card; | ||
398 | } | ||
373 | 399 | ||
374 | if (!oldcard) { | 400 | if (!oldcard) { |
375 | /* | 401 | /* |
376 | * Fetch SCR from card. | 402 | * Fetch SCR from card. |
377 | */ | 403 | */ |
378 | err = mmc_app_send_scr(card, card->raw_scr); | 404 | err = mmc_app_send_scr(card, card->raw_scr); |
379 | if (err != MMC_ERR_NONE) | 405 | if (err) |
380 | goto free_card; | 406 | goto free_card; |
381 | 407 | ||
382 | err = mmc_decode_scr(card); | 408 | err = mmc_decode_scr(card); |
@@ -387,7 +413,7 @@ static int mmc_sd_init_card(struct mmc_host *host, u32 ocr, | |||
387 | * Fetch switch information from card. | 413 | * Fetch switch information from card. |
388 | */ | 414 | */ |
389 | err = mmc_read_switch(card); | 415 | err = mmc_read_switch(card); |
390 | if (err != MMC_ERR_NONE) | 416 | if (err) |
391 | goto free_card; | 417 | goto free_card; |
392 | } | 418 | } |
393 | 419 | ||
@@ -395,7 +421,7 @@ static int mmc_sd_init_card(struct mmc_host *host, u32 ocr, | |||
395 | * Attempt to change to high-speed (if supported) | 421 | * Attempt to change to high-speed (if supported) |
396 | */ | 422 | */ |
397 | err = mmc_switch_hs(card); | 423 | err = mmc_switch_hs(card); |
398 | if (err != MMC_ERR_NONE) | 424 | if (err) |
399 | goto free_card; | 425 | goto free_card; |
400 | 426 | ||
401 | /* | 427 | /* |
@@ -418,7 +444,7 @@ static int mmc_sd_init_card(struct mmc_host *host, u32 ocr, | |||
418 | if ((host->caps & MMC_CAP_4_BIT_DATA) && | 444 | if ((host->caps & MMC_CAP_4_BIT_DATA) && |
419 | (card->scr.bus_widths & SD_SCR_BUS_WIDTH_4)) { | 445 | (card->scr.bus_widths & SD_SCR_BUS_WIDTH_4)) { |
420 | err = mmc_app_set_bus_width(card, MMC_BUS_WIDTH_4); | 446 | err = mmc_app_set_bus_width(card, MMC_BUS_WIDTH_4); |
421 | if (err != MMC_ERR_NONE) | 447 | if (err) |
422 | goto free_card; | 448 | goto free_card; |
423 | 449 | ||
424 | mmc_set_bus_width(host, MMC_BUS_WIDTH_4); | 450 | mmc_set_bus_width(host, MMC_BUS_WIDTH_4); |
@@ -442,14 +468,14 @@ static int mmc_sd_init_card(struct mmc_host *host, u32 ocr, | |||
442 | if (!oldcard) | 468 | if (!oldcard) |
443 | host->card = card; | 469 | host->card = card; |
444 | 470 | ||
445 | return MMC_ERR_NONE; | 471 | return 0; |
446 | 472 | ||
447 | free_card: | 473 | free_card: |
448 | if (!oldcard) | 474 | if (!oldcard) |
449 | mmc_remove_card(card); | 475 | mmc_remove_card(card); |
450 | err: | 476 | err: |
451 | 477 | ||
452 | return MMC_ERR_FAILED; | 478 | return err; |
453 | } | 479 | } |
454 | 480 | ||
455 | /* | 481 | /* |
@@ -483,7 +509,7 @@ static void mmc_sd_detect(struct mmc_host *host) | |||
483 | 509 | ||
484 | mmc_release_host(host); | 510 | mmc_release_host(host); |
485 | 511 | ||
486 | if (err != MMC_ERR_NONE) { | 512 | if (err) { |
487 | mmc_sd_remove(host); | 513 | mmc_sd_remove(host); |
488 | 514 | ||
489 | mmc_claim_host(host); | 515 | mmc_claim_host(host); |
@@ -552,7 +578,8 @@ static void mmc_sd_suspend(struct mmc_host *host) | |||
552 | BUG_ON(!host->card); | 578 | BUG_ON(!host->card); |
553 | 579 | ||
554 | mmc_claim_host(host); | 580 | mmc_claim_host(host); |
555 | mmc_deselect_cards(host); | 581 | if (!mmc_host_is_spi(host)) |
582 | mmc_deselect_cards(host); | ||
556 | host->card->state &= ~MMC_STATE_HIGHSPEED; | 583 | host->card->state &= ~MMC_STATE_HIGHSPEED; |
557 | mmc_release_host(host); | 584 | mmc_release_host(host); |
558 | } | 585 | } |
@@ -574,7 +601,7 @@ static void mmc_sd_resume(struct mmc_host *host) | |||
574 | err = mmc_sd_init_card(host, host->ocr, host->card); | 601 | err = mmc_sd_init_card(host, host->ocr, host->card); |
575 | mmc_release_host(host); | 602 | mmc_release_host(host); |
576 | 603 | ||
577 | if (err != MMC_ERR_NONE) { | 604 | if (err) { |
578 | mmc_sd_remove(host); | 605 | mmc_sd_remove(host); |
579 | 606 | ||
580 | mmc_claim_host(host); | 607 | mmc_claim_host(host); |
@@ -608,11 +635,22 @@ int mmc_attach_sd(struct mmc_host *host, u32 ocr) | |||
608 | int err; | 635 | int err; |
609 | 636 | ||
610 | BUG_ON(!host); | 637 | BUG_ON(!host); |
611 | BUG_ON(!host->claimed); | 638 | WARN_ON(!host->claimed); |
612 | 639 | ||
613 | mmc_attach_bus(host, &mmc_sd_ops); | 640 | mmc_attach_bus(host, &mmc_sd_ops); |
614 | 641 | ||
615 | /* | 642 | /* |
643 | * We need to get OCR a different way for SPI. | ||
644 | */ | ||
645 | if (mmc_host_is_spi(host)) { | ||
646 | mmc_go_idle(host); | ||
647 | |||
648 | err = mmc_spi_read_ocr(host, 0, &ocr); | ||
649 | if (err) | ||
650 | goto err; | ||
651 | } | ||
652 | |||
653 | /* | ||
616 | * Sanity check the voltages that the card claims to | 654 | * Sanity check the voltages that the card claims to |
617 | * support. | 655 | * support. |
618 | */ | 656 | */ |
@@ -644,7 +682,7 @@ int mmc_attach_sd(struct mmc_host *host, u32 ocr) | |||
644 | * Detect and init the card. | 682 | * Detect and init the card. |
645 | */ | 683 | */ |
646 | err = mmc_sd_init_card(host, host->ocr, NULL); | 684 | err = mmc_sd_init_card(host, host->ocr, NULL); |
647 | if (err != MMC_ERR_NONE) | 685 | if (err) |
648 | goto err; | 686 | goto err; |
649 | 687 | ||
650 | mmc_release_host(host); | 688 | mmc_release_host(host); |
@@ -666,6 +704,6 @@ err: | |||
666 | printk(KERN_ERR "%s: error %d whilst initialising SD card\n", | 704 | printk(KERN_ERR "%s: error %d whilst initialising SD card\n", |
667 | mmc_hostname(host), err); | 705 | mmc_hostname(host), err); |
668 | 706 | ||
669 | return 0; | 707 | return err; |
670 | } | 708 | } |
671 | 709 | ||
diff --git a/drivers/mmc/core/sd_ops.c b/drivers/mmc/core/sd_ops.c index 342f340ebc25..ee4029a24efd 100644 --- a/drivers/mmc/core/sd_ops.c +++ b/drivers/mmc/core/sd_ops.c | |||
@@ -33,21 +33,21 @@ static int mmc_app_cmd(struct mmc_host *host, struct mmc_card *card) | |||
33 | 33 | ||
34 | if (card) { | 34 | if (card) { |
35 | cmd.arg = card->rca << 16; | 35 | cmd.arg = card->rca << 16; |
36 | cmd.flags = MMC_RSP_R1 | MMC_CMD_AC; | 36 | cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_AC; |
37 | } else { | 37 | } else { |
38 | cmd.arg = 0; | 38 | cmd.arg = 0; |
39 | cmd.flags = MMC_RSP_R1 | MMC_CMD_BCR; | 39 | cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_BCR; |
40 | } | 40 | } |
41 | 41 | ||
42 | err = mmc_wait_for_cmd(host, &cmd, 0); | 42 | err = mmc_wait_for_cmd(host, &cmd, 0); |
43 | if (err != MMC_ERR_NONE) | 43 | if (err) |
44 | return err; | 44 | return err; |
45 | 45 | ||
46 | /* Check that card supported application commands */ | 46 | /* Check that card supported application commands */ |
47 | if (!(cmd.resp[0] & R1_APP_CMD)) | 47 | if (!mmc_host_is_spi(host) && !(cmd.resp[0] & R1_APP_CMD)) |
48 | return MMC_ERR_FAILED; | 48 | return -EOPNOTSUPP; |
49 | 49 | ||
50 | return MMC_ERR_NONE; | 50 | return 0; |
51 | } | 51 | } |
52 | 52 | ||
53 | /** | 53 | /** |
@@ -73,7 +73,7 @@ int mmc_wait_for_app_cmd(struct mmc_host *host, struct mmc_card *card, | |||
73 | BUG_ON(!cmd); | 73 | BUG_ON(!cmd); |
74 | BUG_ON(retries < 0); | 74 | BUG_ON(retries < 0); |
75 | 75 | ||
76 | err = MMC_ERR_INVALID; | 76 | err = -EIO; |
77 | 77 | ||
78 | /* | 78 | /* |
79 | * We have to resend MMC_APP_CMD for each attempt so | 79 | * We have to resend MMC_APP_CMD for each attempt so |
@@ -83,8 +83,14 @@ int mmc_wait_for_app_cmd(struct mmc_host *host, struct mmc_card *card, | |||
83 | memset(&mrq, 0, sizeof(struct mmc_request)); | 83 | memset(&mrq, 0, sizeof(struct mmc_request)); |
84 | 84 | ||
85 | err = mmc_app_cmd(host, card); | 85 | err = mmc_app_cmd(host, card); |
86 | if (err != MMC_ERR_NONE) | 86 | if (err) { |
87 | /* no point in retrying; no APP commands allowed */ | ||
88 | if (mmc_host_is_spi(host)) { | ||
89 | if (cmd->resp[0] & R1_SPI_ILLEGAL_COMMAND) | ||
90 | break; | ||
91 | } | ||
87 | continue; | 92 | continue; |
93 | } | ||
88 | 94 | ||
89 | memset(&mrq, 0, sizeof(struct mmc_request)); | 95 | memset(&mrq, 0, sizeof(struct mmc_request)); |
90 | 96 | ||
@@ -97,8 +103,14 @@ int mmc_wait_for_app_cmd(struct mmc_host *host, struct mmc_card *card, | |||
97 | mmc_wait_for_req(host, &mrq); | 103 | mmc_wait_for_req(host, &mrq); |
98 | 104 | ||
99 | err = cmd->error; | 105 | err = cmd->error; |
100 | if (cmd->error == MMC_ERR_NONE) | 106 | if (!cmd->error) |
101 | break; | 107 | break; |
108 | |||
109 | /* no point in retrying illegal APP commands */ | ||
110 | if (mmc_host_is_spi(host)) { | ||
111 | if (cmd->resp[0] & R1_SPI_ILLEGAL_COMMAND) | ||
112 | break; | ||
113 | } | ||
102 | } | 114 | } |
103 | 115 | ||
104 | return err; | 116 | return err; |
@@ -127,14 +139,14 @@ int mmc_app_set_bus_width(struct mmc_card *card, int width) | |||
127 | cmd.arg = SD_BUS_WIDTH_4; | 139 | cmd.arg = SD_BUS_WIDTH_4; |
128 | break; | 140 | break; |
129 | default: | 141 | default: |
130 | return MMC_ERR_INVALID; | 142 | return -EINVAL; |
131 | } | 143 | } |
132 | 144 | ||
133 | err = mmc_wait_for_app_cmd(card->host, card, &cmd, MMC_CMD_RETRIES); | 145 | err = mmc_wait_for_app_cmd(card->host, card, &cmd, MMC_CMD_RETRIES); |
134 | if (err != MMC_ERR_NONE) | 146 | if (err) |
135 | return err; | 147 | return err; |
136 | 148 | ||
137 | return MMC_ERR_NONE; | 149 | return 0; |
138 | } | 150 | } |
139 | 151 | ||
140 | int mmc_send_app_op_cond(struct mmc_host *host, u32 ocr, u32 *rocr) | 152 | int mmc_send_app_op_cond(struct mmc_host *host, u32 ocr, u32 *rocr) |
@@ -147,23 +159,36 @@ int mmc_send_app_op_cond(struct mmc_host *host, u32 ocr, u32 *rocr) | |||
147 | memset(&cmd, 0, sizeof(struct mmc_command)); | 159 | memset(&cmd, 0, sizeof(struct mmc_command)); |
148 | 160 | ||
149 | cmd.opcode = SD_APP_OP_COND; | 161 | cmd.opcode = SD_APP_OP_COND; |
150 | cmd.arg = ocr; | 162 | if (mmc_host_is_spi(host)) |
151 | cmd.flags = MMC_RSP_R3 | MMC_CMD_BCR; | 163 | cmd.arg = ocr & (1 << 30); /* SPI only defines one bit */ |
164 | else | ||
165 | cmd.arg = ocr; | ||
166 | cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R3 | MMC_CMD_BCR; | ||
152 | 167 | ||
153 | for (i = 100; i; i--) { | 168 | for (i = 100; i; i--) { |
154 | err = mmc_wait_for_app_cmd(host, NULL, &cmd, MMC_CMD_RETRIES); | 169 | err = mmc_wait_for_app_cmd(host, NULL, &cmd, MMC_CMD_RETRIES); |
155 | if (err != MMC_ERR_NONE) | 170 | if (err) |
156 | break; | 171 | break; |
157 | 172 | ||
158 | if (cmd.resp[0] & MMC_CARD_BUSY || ocr == 0) | 173 | /* if we're just probing, do a single pass */ |
174 | if (ocr == 0) | ||
159 | break; | 175 | break; |
160 | 176 | ||
161 | err = MMC_ERR_TIMEOUT; | 177 | /* otherwise wait until reset completes */ |
178 | if (mmc_host_is_spi(host)) { | ||
179 | if (!(cmd.resp[0] & R1_SPI_IDLE)) | ||
180 | break; | ||
181 | } else { | ||
182 | if (cmd.resp[0] & MMC_CARD_BUSY) | ||
183 | break; | ||
184 | } | ||
185 | |||
186 | err = -ETIMEDOUT; | ||
162 | 187 | ||
163 | mmc_delay(10); | 188 | mmc_delay(10); |
164 | } | 189 | } |
165 | 190 | ||
166 | if (rocr) | 191 | if (rocr && !mmc_host_is_spi(host)) |
167 | *rocr = cmd.resp[0]; | 192 | *rocr = cmd.resp[0]; |
168 | 193 | ||
169 | return err; | 194 | return err; |
@@ -174,6 +199,7 @@ int mmc_send_if_cond(struct mmc_host *host, u32 ocr) | |||
174 | struct mmc_command cmd; | 199 | struct mmc_command cmd; |
175 | int err; | 200 | int err; |
176 | static const u8 test_pattern = 0xAA; | 201 | static const u8 test_pattern = 0xAA; |
202 | u8 result_pattern; | ||
177 | 203 | ||
178 | /* | 204 | /* |
179 | * To support SD 2.0 cards, we must always invoke SD_SEND_IF_COND | 205 | * To support SD 2.0 cards, we must always invoke SD_SEND_IF_COND |
@@ -182,16 +208,21 @@ int mmc_send_if_cond(struct mmc_host *host, u32 ocr) | |||
182 | */ | 208 | */ |
183 | cmd.opcode = SD_SEND_IF_COND; | 209 | cmd.opcode = SD_SEND_IF_COND; |
184 | cmd.arg = ((ocr & 0xFF8000) != 0) << 8 | test_pattern; | 210 | cmd.arg = ((ocr & 0xFF8000) != 0) << 8 | test_pattern; |
185 | cmd.flags = MMC_RSP_R7 | MMC_CMD_BCR; | 211 | cmd.flags = MMC_RSP_SPI_R7 | MMC_RSP_R7 | MMC_CMD_BCR; |
186 | 212 | ||
187 | err = mmc_wait_for_cmd(host, &cmd, 0); | 213 | err = mmc_wait_for_cmd(host, &cmd, 0); |
188 | if (err != MMC_ERR_NONE) | 214 | if (err) |
189 | return err; | 215 | return err; |
190 | 216 | ||
191 | if ((cmd.resp[0] & 0xFF) != test_pattern) | 217 | if (mmc_host_is_spi(host)) |
192 | return MMC_ERR_FAILED; | 218 | result_pattern = cmd.resp[1] & 0xFF; |
219 | else | ||
220 | result_pattern = cmd.resp[0] & 0xFF; | ||
221 | |||
222 | if (result_pattern != test_pattern) | ||
223 | return -EIO; | ||
193 | 224 | ||
194 | return MMC_ERR_NONE; | 225 | return 0; |
195 | } | 226 | } |
196 | 227 | ||
197 | int mmc_send_relative_addr(struct mmc_host *host, unsigned int *rca) | 228 | int mmc_send_relative_addr(struct mmc_host *host, unsigned int *rca) |
@@ -209,12 +240,12 @@ int mmc_send_relative_addr(struct mmc_host *host, unsigned int *rca) | |||
209 | cmd.flags = MMC_RSP_R6 | MMC_CMD_BCR; | 240 | cmd.flags = MMC_RSP_R6 | MMC_CMD_BCR; |
210 | 241 | ||
211 | err = mmc_wait_for_cmd(host, &cmd, MMC_CMD_RETRIES); | 242 | err = mmc_wait_for_cmd(host, &cmd, MMC_CMD_RETRIES); |
212 | if (err != MMC_ERR_NONE) | 243 | if (err) |
213 | return err; | 244 | return err; |
214 | 245 | ||
215 | *rca = cmd.resp[0] >> 16; | 246 | *rca = cmd.resp[0] >> 16; |
216 | 247 | ||
217 | return MMC_ERR_NONE; | 248 | return 0; |
218 | } | 249 | } |
219 | 250 | ||
220 | int mmc_app_send_scr(struct mmc_card *card, u32 *scr) | 251 | int mmc_app_send_scr(struct mmc_card *card, u32 *scr) |
@@ -229,8 +260,10 @@ int mmc_app_send_scr(struct mmc_card *card, u32 *scr) | |||
229 | BUG_ON(!card->host); | 260 | BUG_ON(!card->host); |
230 | BUG_ON(!scr); | 261 | BUG_ON(!scr); |
231 | 262 | ||
263 | /* NOTE: caller guarantees scr is heap-allocated */ | ||
264 | |||
232 | err = mmc_app_cmd(card->host, card); | 265 | err = mmc_app_cmd(card->host, card); |
233 | if (err != MMC_ERR_NONE) | 266 | if (err) |
234 | return err; | 267 | return err; |
235 | 268 | ||
236 | memset(&mrq, 0, sizeof(struct mmc_request)); | 269 | memset(&mrq, 0, sizeof(struct mmc_request)); |
@@ -242,7 +275,7 @@ int mmc_app_send_scr(struct mmc_card *card, u32 *scr) | |||
242 | 275 | ||
243 | cmd.opcode = SD_APP_SEND_SCR; | 276 | cmd.opcode = SD_APP_SEND_SCR; |
244 | cmd.arg = 0; | 277 | cmd.arg = 0; |
245 | cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC; | 278 | cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_ADTC; |
246 | 279 | ||
247 | data.blksz = 8; | 280 | data.blksz = 8; |
248 | data.blocks = 1; | 281 | data.blocks = 1; |
@@ -252,19 +285,19 @@ int mmc_app_send_scr(struct mmc_card *card, u32 *scr) | |||
252 | 285 | ||
253 | sg_init_one(&sg, scr, 8); | 286 | sg_init_one(&sg, scr, 8); |
254 | 287 | ||
255 | mmc_set_data_timeout(&data, card, 0); | 288 | mmc_set_data_timeout(&data, card); |
256 | 289 | ||
257 | mmc_wait_for_req(card->host, &mrq); | 290 | mmc_wait_for_req(card->host, &mrq); |
258 | 291 | ||
259 | if (cmd.error != MMC_ERR_NONE) | 292 | if (cmd.error) |
260 | return cmd.error; | 293 | return cmd.error; |
261 | if (data.error != MMC_ERR_NONE) | 294 | if (data.error) |
262 | return data.error; | 295 | return data.error; |
263 | 296 | ||
264 | scr[0] = ntohl(scr[0]); | 297 | scr[0] = ntohl(scr[0]); |
265 | scr[1] = ntohl(scr[1]); | 298 | scr[1] = ntohl(scr[1]); |
266 | 299 | ||
267 | return MMC_ERR_NONE; | 300 | return 0; |
268 | } | 301 | } |
269 | 302 | ||
270 | int mmc_sd_switch(struct mmc_card *card, int mode, int group, | 303 | int mmc_sd_switch(struct mmc_card *card, int mode, int group, |
@@ -278,6 +311,8 @@ int mmc_sd_switch(struct mmc_card *card, int mode, int group, | |||
278 | BUG_ON(!card); | 311 | BUG_ON(!card); |
279 | BUG_ON(!card->host); | 312 | BUG_ON(!card->host); |
280 | 313 | ||
314 | /* NOTE: caller guarantees resp is heap-allocated */ | ||
315 | |||
281 | mode = !!mode; | 316 | mode = !!mode; |
282 | value &= 0xF; | 317 | value &= 0xF; |
283 | 318 | ||
@@ -292,7 +327,7 @@ int mmc_sd_switch(struct mmc_card *card, int mode, int group, | |||
292 | cmd.arg = mode << 31 | 0x00FFFFFF; | 327 | cmd.arg = mode << 31 | 0x00FFFFFF; |
293 | cmd.arg &= ~(0xF << (group * 4)); | 328 | cmd.arg &= ~(0xF << (group * 4)); |
294 | cmd.arg |= value << (group * 4); | 329 | cmd.arg |= value << (group * 4); |
295 | cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC; | 330 | cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_ADTC; |
296 | 331 | ||
297 | data.blksz = 64; | 332 | data.blksz = 64; |
298 | data.blocks = 1; | 333 | data.blocks = 1; |
@@ -302,15 +337,15 @@ int mmc_sd_switch(struct mmc_card *card, int mode, int group, | |||
302 | 337 | ||
303 | sg_init_one(&sg, resp, 64); | 338 | sg_init_one(&sg, resp, 64); |
304 | 339 | ||
305 | mmc_set_data_timeout(&data, card, 0); | 340 | mmc_set_data_timeout(&data, card); |
306 | 341 | ||
307 | mmc_wait_for_req(card->host, &mrq); | 342 | mmc_wait_for_req(card->host, &mrq); |
308 | 343 | ||
309 | if (cmd.error != MMC_ERR_NONE) | 344 | if (cmd.error) |
310 | return cmd.error; | 345 | return cmd.error; |
311 | if (data.error != MMC_ERR_NONE) | 346 | if (data.error) |
312 | return data.error; | 347 | return data.error; |
313 | 348 | ||
314 | return MMC_ERR_NONE; | 349 | return 0; |
315 | } | 350 | } |
316 | 351 | ||
diff --git a/drivers/mmc/core/sdio.c b/drivers/mmc/core/sdio.c new file mode 100644 index 000000000000..87a50f456efc --- /dev/null +++ b/drivers/mmc/core/sdio.c | |||
@@ -0,0 +1,395 @@ | |||
1 | /* | ||
2 | * linux/drivers/mmc/sdio.c | ||
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/err.h> | ||
13 | |||
14 | #include <linux/mmc/host.h> | ||
15 | #include <linux/mmc/card.h> | ||
16 | #include <linux/mmc/sdio.h> | ||
17 | #include <linux/mmc/sdio_func.h> | ||
18 | |||
19 | #include "core.h" | ||
20 | #include "bus.h" | ||
21 | #include "sdio_bus.h" | ||
22 | #include "mmc_ops.h" | ||
23 | #include "sd_ops.h" | ||
24 | #include "sdio_ops.h" | ||
25 | #include "sdio_cis.h" | ||
26 | |||
27 | static int sdio_read_fbr(struct sdio_func *func) | ||
28 | { | ||
29 | int ret; | ||
30 | unsigned char data; | ||
31 | |||
32 | ret = mmc_io_rw_direct(func->card, 0, 0, | ||
33 | SDIO_FBR_BASE(func->num) + SDIO_FBR_STD_IF, 0, &data); | ||
34 | if (ret) | ||
35 | goto out; | ||
36 | |||
37 | data &= 0x0f; | ||
38 | |||
39 | if (data == 0x0f) { | ||
40 | ret = mmc_io_rw_direct(func->card, 0, 0, | ||
41 | SDIO_FBR_BASE(func->num) + SDIO_FBR_STD_IF_EXT, 0, &data); | ||
42 | if (ret) | ||
43 | goto out; | ||
44 | } | ||
45 | |||
46 | func->class = data; | ||
47 | |||
48 | out: | ||
49 | return ret; | ||
50 | } | ||
51 | |||
52 | static int sdio_init_func(struct mmc_card *card, unsigned int fn) | ||
53 | { | ||
54 | int ret; | ||
55 | struct sdio_func *func; | ||
56 | |||
57 | BUG_ON(fn > SDIO_MAX_FUNCS); | ||
58 | |||
59 | func = sdio_alloc_func(card); | ||
60 | if (IS_ERR(func)) | ||
61 | return PTR_ERR(func); | ||
62 | |||
63 | func->num = fn; | ||
64 | |||
65 | ret = sdio_read_fbr(func); | ||
66 | if (ret) | ||
67 | goto fail; | ||
68 | |||
69 | ret = sdio_read_func_cis(func); | ||
70 | if (ret) | ||
71 | goto fail; | ||
72 | |||
73 | card->sdio_func[fn - 1] = func; | ||
74 | |||
75 | return 0; | ||
76 | |||
77 | fail: | ||
78 | /* | ||
79 | * It is okay to remove the function here even though we hold | ||
80 | * the host lock as we haven't registered the device yet. | ||
81 | */ | ||
82 | sdio_remove_func(func); | ||
83 | return ret; | ||
84 | } | ||
85 | |||
86 | static int sdio_read_cccr(struct mmc_card *card) | ||
87 | { | ||
88 | int ret; | ||
89 | int cccr_vsn; | ||
90 | unsigned char data; | ||
91 | |||
92 | memset(&card->cccr, 0, sizeof(struct sdio_cccr)); | ||
93 | |||
94 | ret = mmc_io_rw_direct(card, 0, 0, SDIO_CCCR_CCCR, 0, &data); | ||
95 | if (ret) | ||
96 | goto out; | ||
97 | |||
98 | cccr_vsn = data & 0x0f; | ||
99 | |||
100 | if (cccr_vsn > SDIO_CCCR_REV_1_20) { | ||
101 | printk(KERN_ERR "%s: unrecognised CCCR structure version %d\n", | ||
102 | mmc_hostname(card->host), cccr_vsn); | ||
103 | return -EINVAL; | ||
104 | } | ||
105 | |||
106 | card->cccr.sdio_vsn = (data & 0xf0) >> 4; | ||
107 | |||
108 | ret = mmc_io_rw_direct(card, 0, 0, SDIO_CCCR_CAPS, 0, &data); | ||
109 | if (ret) | ||
110 | goto out; | ||
111 | |||
112 | if (data & SDIO_CCCR_CAP_SMB) | ||
113 | card->cccr.multi_block = 1; | ||
114 | if (data & SDIO_CCCR_CAP_LSC) | ||
115 | card->cccr.low_speed = 1; | ||
116 | if (data & SDIO_CCCR_CAP_4BLS) | ||
117 | card->cccr.wide_bus = 1; | ||
118 | |||
119 | if (cccr_vsn >= SDIO_CCCR_REV_1_10) { | ||
120 | ret = mmc_io_rw_direct(card, 0, 0, SDIO_CCCR_POWER, 0, &data); | ||
121 | if (ret) | ||
122 | goto out; | ||
123 | |||
124 | if (data & SDIO_POWER_SMPC) | ||
125 | card->cccr.high_power = 1; | ||
126 | } | ||
127 | |||
128 | if (cccr_vsn >= SDIO_CCCR_REV_1_20) { | ||
129 | ret = mmc_io_rw_direct(card, 0, 0, SDIO_CCCR_SPEED, 0, &data); | ||
130 | if (ret) | ||
131 | goto out; | ||
132 | |||
133 | if (data & SDIO_SPEED_SHS) | ||
134 | card->cccr.high_speed = 1; | ||
135 | } | ||
136 | |||
137 | out: | ||
138 | return ret; | ||
139 | } | ||
140 | |||
141 | static int sdio_enable_wide(struct mmc_card *card) | ||
142 | { | ||
143 | int ret; | ||
144 | u8 ctrl; | ||
145 | |||
146 | if (!(card->host->caps & MMC_CAP_4_BIT_DATA)) | ||
147 | return 0; | ||
148 | |||
149 | if (card->cccr.low_speed && !card->cccr.wide_bus) | ||
150 | return 0; | ||
151 | |||
152 | ret = mmc_io_rw_direct(card, 0, 0, SDIO_CCCR_IF, 0, &ctrl); | ||
153 | if (ret) | ||
154 | return ret; | ||
155 | |||
156 | ctrl |= SDIO_BUS_WIDTH_4BIT; | ||
157 | |||
158 | ret = mmc_io_rw_direct(card, 1, 0, SDIO_CCCR_IF, ctrl, NULL); | ||
159 | if (ret) | ||
160 | return ret; | ||
161 | |||
162 | mmc_set_bus_width(card->host, MMC_BUS_WIDTH_4); | ||
163 | |||
164 | return 0; | ||
165 | } | ||
166 | |||
167 | /* | ||
168 | * Host is being removed. Free up the current card. | ||
169 | */ | ||
170 | static void mmc_sdio_remove(struct mmc_host *host) | ||
171 | { | ||
172 | int i; | ||
173 | |||
174 | BUG_ON(!host); | ||
175 | BUG_ON(!host->card); | ||
176 | |||
177 | for (i = 0;i < host->card->sdio_funcs;i++) { | ||
178 | if (host->card->sdio_func[i]) { | ||
179 | sdio_remove_func(host->card->sdio_func[i]); | ||
180 | host->card->sdio_func[i] = NULL; | ||
181 | } | ||
182 | } | ||
183 | |||
184 | mmc_remove_card(host->card); | ||
185 | host->card = NULL; | ||
186 | } | ||
187 | |||
188 | /* | ||
189 | * Card detection callback from host. | ||
190 | */ | ||
191 | static void mmc_sdio_detect(struct mmc_host *host) | ||
192 | { | ||
193 | int err; | ||
194 | |||
195 | BUG_ON(!host); | ||
196 | BUG_ON(!host->card); | ||
197 | |||
198 | mmc_claim_host(host); | ||
199 | |||
200 | /* | ||
201 | * Just check if our card has been removed. | ||
202 | */ | ||
203 | err = mmc_select_card(host->card); | ||
204 | |||
205 | mmc_release_host(host); | ||
206 | |||
207 | if (err) { | ||
208 | mmc_sdio_remove(host); | ||
209 | |||
210 | mmc_claim_host(host); | ||
211 | mmc_detach_bus(host); | ||
212 | mmc_release_host(host); | ||
213 | } | ||
214 | } | ||
215 | |||
216 | |||
217 | static const struct mmc_bus_ops mmc_sdio_ops = { | ||
218 | .remove = mmc_sdio_remove, | ||
219 | .detect = mmc_sdio_detect, | ||
220 | }; | ||
221 | |||
222 | |||
223 | /* | ||
224 | * Starting point for SDIO card init. | ||
225 | */ | ||
226 | int mmc_attach_sdio(struct mmc_host *host, u32 ocr) | ||
227 | { | ||
228 | int err; | ||
229 | int i, funcs; | ||
230 | struct mmc_card *card; | ||
231 | |||
232 | BUG_ON(!host); | ||
233 | WARN_ON(!host->claimed); | ||
234 | |||
235 | mmc_attach_bus(host, &mmc_sdio_ops); | ||
236 | |||
237 | /* | ||
238 | * Sanity check the voltages that the card claims to | ||
239 | * support. | ||
240 | */ | ||
241 | if (ocr & 0x7F) { | ||
242 | printk(KERN_WARNING "%s: card claims to support voltages " | ||
243 | "below the defined range. These will be ignored.\n", | ||
244 | mmc_hostname(host)); | ||
245 | ocr &= ~0x7F; | ||
246 | } | ||
247 | |||
248 | if (ocr & MMC_VDD_165_195) { | ||
249 | printk(KERN_WARNING "%s: SDIO card claims to support the " | ||
250 | "incompletely defined 'low voltage range'. This " | ||
251 | "will be ignored.\n", mmc_hostname(host)); | ||
252 | ocr &= ~MMC_VDD_165_195; | ||
253 | } | ||
254 | |||
255 | host->ocr = mmc_select_voltage(host, ocr); | ||
256 | |||
257 | /* | ||
258 | * Can we support the voltage(s) of the card(s)? | ||
259 | */ | ||
260 | if (!host->ocr) { | ||
261 | err = -EINVAL; | ||
262 | goto err; | ||
263 | } | ||
264 | |||
265 | /* | ||
266 | * Inform the card of the voltage | ||
267 | */ | ||
268 | err = mmc_send_io_op_cond(host, host->ocr, &ocr); | ||
269 | if (err) | ||
270 | goto err; | ||
271 | |||
272 | /* | ||
273 | * For SPI, enable CRC as appropriate. | ||
274 | */ | ||
275 | if (mmc_host_is_spi(host)) { | ||
276 | err = mmc_spi_set_crc(host, use_spi_crc); | ||
277 | if (err) | ||
278 | goto err; | ||
279 | } | ||
280 | |||
281 | /* | ||
282 | * The number of functions on the card is encoded inside | ||
283 | * the ocr. | ||
284 | */ | ||
285 | funcs = (ocr & 0x70000000) >> 28; | ||
286 | |||
287 | /* | ||
288 | * Allocate card structure. | ||
289 | */ | ||
290 | card = mmc_alloc_card(host); | ||
291 | if (IS_ERR(card)) { | ||
292 | err = PTR_ERR(card); | ||
293 | goto err; | ||
294 | } | ||
295 | |||
296 | card->type = MMC_TYPE_SDIO; | ||
297 | card->sdio_funcs = funcs; | ||
298 | |||
299 | host->card = card; | ||
300 | |||
301 | /* | ||
302 | * For native busses: set card RCA and quit open drain mode. | ||
303 | */ | ||
304 | if (!mmc_host_is_spi(host)) { | ||
305 | err = mmc_send_relative_addr(host, &card->rca); | ||
306 | if (err) | ||
307 | goto remove; | ||
308 | |||
309 | mmc_set_bus_mode(host, MMC_BUSMODE_PUSHPULL); | ||
310 | } | ||
311 | |||
312 | /* | ||
313 | * Select card, as all following commands rely on that. | ||
314 | */ | ||
315 | if (!mmc_host_is_spi(host)) { | ||
316 | err = mmc_select_card(card); | ||
317 | if (err) | ||
318 | goto remove; | ||
319 | } | ||
320 | |||
321 | /* | ||
322 | * Read the common registers. | ||
323 | */ | ||
324 | err = sdio_read_cccr(card); | ||
325 | if (err) | ||
326 | goto remove; | ||
327 | |||
328 | /* | ||
329 | * Read the common CIS tuples. | ||
330 | */ | ||
331 | err = sdio_read_common_cis(card); | ||
332 | if (err) | ||
333 | goto remove; | ||
334 | |||
335 | /* | ||
336 | * No support for high-speed yet, so just set | ||
337 | * the card's maximum speed. | ||
338 | */ | ||
339 | mmc_set_clock(host, card->cis.max_dtr); | ||
340 | |||
341 | /* | ||
342 | * Switch to wider bus (if supported). | ||
343 | */ | ||
344 | err = sdio_enable_wide(card); | ||
345 | if (err) | ||
346 | goto remove; | ||
347 | |||
348 | /* | ||
349 | * Initialize (but don't add) all present functions. | ||
350 | */ | ||
351 | for (i = 0;i < funcs;i++) { | ||
352 | err = sdio_init_func(host->card, i + 1); | ||
353 | if (err) | ||
354 | goto remove; | ||
355 | } | ||
356 | |||
357 | mmc_release_host(host); | ||
358 | |||
359 | /* | ||
360 | * First add the card to the driver model... | ||
361 | */ | ||
362 | err = mmc_add_card(host->card); | ||
363 | if (err) | ||
364 | goto remove_added; | ||
365 | |||
366 | /* | ||
367 | * ...then the SDIO functions. | ||
368 | */ | ||
369 | for (i = 0;i < funcs;i++) { | ||
370 | err = sdio_add_func(host->card->sdio_func[i]); | ||
371 | if (err) | ||
372 | goto remove_added; | ||
373 | } | ||
374 | |||
375 | return 0; | ||
376 | |||
377 | |||
378 | remove_added: | ||
379 | /* Remove without lock if the device has been added. */ | ||
380 | mmc_sdio_remove(host); | ||
381 | mmc_claim_host(host); | ||
382 | remove: | ||
383 | /* And with lock if it hasn't been added. */ | ||
384 | if (host->card) | ||
385 | mmc_sdio_remove(host); | ||
386 | err: | ||
387 | mmc_detach_bus(host); | ||
388 | mmc_release_host(host); | ||
389 | |||
390 | printk(KERN_ERR "%s: error %d whilst initialising SDIO card\n", | ||
391 | mmc_hostname(host), err); | ||
392 | |||
393 | return err; | ||
394 | } | ||
395 | |||
diff --git a/drivers/mmc/core/sdio_bus.c b/drivers/mmc/core/sdio_bus.c new file mode 100644 index 000000000000..0713a8c71e54 --- /dev/null +++ b/drivers/mmc/core/sdio_bus.c | |||
@@ -0,0 +1,270 @@ | |||
1 | /* | ||
2 | * linux/drivers/mmc/core/sdio_bus.c | ||
3 | * | ||
4 | * Copyright 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 | * SDIO function driver model | ||
12 | */ | ||
13 | |||
14 | #include <linux/device.h> | ||
15 | #include <linux/err.h> | ||
16 | |||
17 | #include <linux/mmc/card.h> | ||
18 | #include <linux/mmc/sdio_func.h> | ||
19 | |||
20 | #include "sdio_cis.h" | ||
21 | #include "sdio_bus.h" | ||
22 | |||
23 | #define dev_to_sdio_func(d) container_of(d, struct sdio_func, dev) | ||
24 | #define to_sdio_driver(d) container_of(d, struct sdio_driver, drv) | ||
25 | |||
26 | /* show configuration fields */ | ||
27 | #define sdio_config_attr(field, format_string) \ | ||
28 | static ssize_t \ | ||
29 | field##_show(struct device *dev, struct device_attribute *attr, char *buf) \ | ||
30 | { \ | ||
31 | struct sdio_func *func; \ | ||
32 | \ | ||
33 | func = dev_to_sdio_func (dev); \ | ||
34 | return sprintf (buf, format_string, func->field); \ | ||
35 | } | ||
36 | |||
37 | sdio_config_attr(class, "0x%02x\n"); | ||
38 | sdio_config_attr(vendor, "0x%04x\n"); | ||
39 | sdio_config_attr(device, "0x%04x\n"); | ||
40 | |||
41 | static ssize_t modalias_show(struct device *dev, struct device_attribute *attr, char *buf) | ||
42 | { | ||
43 | struct sdio_func *func = dev_to_sdio_func (dev); | ||
44 | |||
45 | return sprintf(buf, "sdio:c%02Xv%04Xd%04X\n", | ||
46 | func->class, func->vendor, func->device); | ||
47 | } | ||
48 | |||
49 | static struct device_attribute sdio_dev_attrs[] = { | ||
50 | __ATTR_RO(class), | ||
51 | __ATTR_RO(vendor), | ||
52 | __ATTR_RO(device), | ||
53 | __ATTR_RO(modalias), | ||
54 | __ATTR_NULL, | ||
55 | }; | ||
56 | |||
57 | static const struct sdio_device_id *sdio_match_one(struct sdio_func *func, | ||
58 | const struct sdio_device_id *id) | ||
59 | { | ||
60 | if (id->class != (__u8)SDIO_ANY_ID && id->class != func->class) | ||
61 | return NULL; | ||
62 | if (id->vendor != (__u16)SDIO_ANY_ID && id->vendor != func->vendor) | ||
63 | return NULL; | ||
64 | if (id->device != (__u16)SDIO_ANY_ID && id->device != func->device) | ||
65 | return NULL; | ||
66 | return id; | ||
67 | } | ||
68 | |||
69 | static const struct sdio_device_id *sdio_match_device(struct sdio_func *func, | ||
70 | struct sdio_driver *sdrv) | ||
71 | { | ||
72 | const struct sdio_device_id *ids; | ||
73 | |||
74 | ids = sdrv->id_table; | ||
75 | |||
76 | if (ids) { | ||
77 | while (ids->class || ids->vendor || ids->device) { | ||
78 | if (sdio_match_one(func, ids)) | ||
79 | return ids; | ||
80 | ids++; | ||
81 | } | ||
82 | } | ||
83 | |||
84 | return NULL; | ||
85 | } | ||
86 | |||
87 | static int sdio_bus_match(struct device *dev, struct device_driver *drv) | ||
88 | { | ||
89 | struct sdio_func *func = dev_to_sdio_func(dev); | ||
90 | struct sdio_driver *sdrv = to_sdio_driver(drv); | ||
91 | |||
92 | if (sdio_match_device(func, sdrv)) | ||
93 | return 1; | ||
94 | |||
95 | return 0; | ||
96 | } | ||
97 | |||
98 | static int | ||
99 | sdio_bus_uevent(struct device *dev, char **envp, int num_envp, char *buf, | ||
100 | int buf_size) | ||
101 | { | ||
102 | struct sdio_func *func = dev_to_sdio_func(dev); | ||
103 | int i = 0, length = 0; | ||
104 | |||
105 | if (add_uevent_var(envp, num_envp, &i, | ||
106 | buf, buf_size, &length, | ||
107 | "SDIO_CLASS=%02X", func->class)) | ||
108 | return -ENOMEM; | ||
109 | |||
110 | if (add_uevent_var(envp, num_envp, &i, | ||
111 | buf, buf_size, &length, | ||
112 | "SDIO_ID=%04X:%04X", func->vendor, func->device)) | ||
113 | return -ENOMEM; | ||
114 | |||
115 | if (add_uevent_var(envp, num_envp, &i, | ||
116 | buf, buf_size, &length, | ||
117 | "MODALIAS=sdio:c%02Xv%04Xd%04X", | ||
118 | func->class, func->vendor, func->device)) | ||
119 | return -ENOMEM; | ||
120 | |||
121 | envp[i] = NULL; | ||
122 | |||
123 | return 0; | ||
124 | } | ||
125 | |||
126 | static int sdio_bus_probe(struct device *dev) | ||
127 | { | ||
128 | struct sdio_driver *drv = to_sdio_driver(dev->driver); | ||
129 | struct sdio_func *func = dev_to_sdio_func(dev); | ||
130 | const struct sdio_device_id *id; | ||
131 | int ret; | ||
132 | |||
133 | id = sdio_match_device(func, drv); | ||
134 | if (!id) | ||
135 | return -ENODEV; | ||
136 | |||
137 | /* Set the default block size so the driver is sure it's something | ||
138 | * sensible. */ | ||
139 | sdio_claim_host(func); | ||
140 | ret = sdio_set_block_size(func, 0); | ||
141 | sdio_release_host(func); | ||
142 | if (ret) | ||
143 | return ret; | ||
144 | |||
145 | return drv->probe(func, id); | ||
146 | } | ||
147 | |||
148 | static int sdio_bus_remove(struct device *dev) | ||
149 | { | ||
150 | struct sdio_driver *drv = to_sdio_driver(dev->driver); | ||
151 | struct sdio_func *func = dev_to_sdio_func(dev); | ||
152 | |||
153 | drv->remove(func); | ||
154 | |||
155 | if (func->irq_handler) { | ||
156 | printk(KERN_WARNING "WARNING: driver %s did not remove " | ||
157 | "its interrupt handler!\n", drv->name); | ||
158 | sdio_claim_host(func); | ||
159 | sdio_release_irq(func); | ||
160 | sdio_release_host(func); | ||
161 | } | ||
162 | |||
163 | return 0; | ||
164 | } | ||
165 | |||
166 | static struct bus_type sdio_bus_type = { | ||
167 | .name = "sdio", | ||
168 | .dev_attrs = sdio_dev_attrs, | ||
169 | .match = sdio_bus_match, | ||
170 | .uevent = sdio_bus_uevent, | ||
171 | .probe = sdio_bus_probe, | ||
172 | .remove = sdio_bus_remove, | ||
173 | }; | ||
174 | |||
175 | int sdio_register_bus(void) | ||
176 | { | ||
177 | return bus_register(&sdio_bus_type); | ||
178 | } | ||
179 | |||
180 | void sdio_unregister_bus(void) | ||
181 | { | ||
182 | bus_unregister(&sdio_bus_type); | ||
183 | } | ||
184 | |||
185 | /** | ||
186 | * sdio_register_driver - register a function driver | ||
187 | * @drv: SDIO function driver | ||
188 | */ | ||
189 | int sdio_register_driver(struct sdio_driver *drv) | ||
190 | { | ||
191 | drv->drv.name = drv->name; | ||
192 | drv->drv.bus = &sdio_bus_type; | ||
193 | return driver_register(&drv->drv); | ||
194 | } | ||
195 | EXPORT_SYMBOL_GPL(sdio_register_driver); | ||
196 | |||
197 | /** | ||
198 | * sdio_unregister_driver - unregister a function driver | ||
199 | * @drv: SDIO function driver | ||
200 | */ | ||
201 | void sdio_unregister_driver(struct sdio_driver *drv) | ||
202 | { | ||
203 | drv->drv.bus = &sdio_bus_type; | ||
204 | driver_unregister(&drv->drv); | ||
205 | } | ||
206 | EXPORT_SYMBOL_GPL(sdio_unregister_driver); | ||
207 | |||
208 | static void sdio_release_func(struct device *dev) | ||
209 | { | ||
210 | struct sdio_func *func = dev_to_sdio_func(dev); | ||
211 | |||
212 | sdio_free_func_cis(func); | ||
213 | |||
214 | if (func->info) | ||
215 | kfree(func->info); | ||
216 | |||
217 | kfree(func); | ||
218 | } | ||
219 | |||
220 | /* | ||
221 | * Allocate and initialise a new SDIO function structure. | ||
222 | */ | ||
223 | struct sdio_func *sdio_alloc_func(struct mmc_card *card) | ||
224 | { | ||
225 | struct sdio_func *func; | ||
226 | |||
227 | func = kzalloc(sizeof(struct sdio_func), GFP_KERNEL); | ||
228 | if (!func) | ||
229 | return ERR_PTR(-ENOMEM); | ||
230 | |||
231 | func->card = card; | ||
232 | |||
233 | device_initialize(&func->dev); | ||
234 | |||
235 | func->dev.parent = &card->dev; | ||
236 | func->dev.bus = &sdio_bus_type; | ||
237 | func->dev.release = sdio_release_func; | ||
238 | |||
239 | return func; | ||
240 | } | ||
241 | |||
242 | /* | ||
243 | * Register a new SDIO function with the driver model. | ||
244 | */ | ||
245 | int sdio_add_func(struct sdio_func *func) | ||
246 | { | ||
247 | int ret; | ||
248 | |||
249 | snprintf(func->dev.bus_id, sizeof(func->dev.bus_id), | ||
250 | "%s:%d", mmc_card_id(func->card), func->num); | ||
251 | |||
252 | ret = device_add(&func->dev); | ||
253 | if (ret == 0) | ||
254 | sdio_func_set_present(func); | ||
255 | |||
256 | return ret; | ||
257 | } | ||
258 | |||
259 | /* | ||
260 | * Unregister a SDIO function with the driver model, and | ||
261 | * (eventually) free it. | ||
262 | */ | ||
263 | void sdio_remove_func(struct sdio_func *func) | ||
264 | { | ||
265 | if (sdio_func_present(func)) | ||
266 | device_del(&func->dev); | ||
267 | |||
268 | put_device(&func->dev); | ||
269 | } | ||
270 | |||
diff --git a/drivers/mmc/core/sdio_bus.h b/drivers/mmc/core/sdio_bus.h new file mode 100644 index 000000000000..567a76821ba7 --- /dev/null +++ b/drivers/mmc/core/sdio_bus.h | |||
@@ -0,0 +1,22 @@ | |||
1 | /* | ||
2 | * linux/drivers/mmc/core/sdio_bus.h | ||
3 | * | ||
4 | * Copyright 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 | #ifndef _MMC_CORE_SDIO_BUS_H | ||
12 | #define _MMC_CORE_SDIO_BUS_H | ||
13 | |||
14 | struct sdio_func *sdio_alloc_func(struct mmc_card *card); | ||
15 | int sdio_add_func(struct sdio_func *func); | ||
16 | void sdio_remove_func(struct sdio_func *func); | ||
17 | |||
18 | int sdio_register_bus(void); | ||
19 | void sdio_unregister_bus(void); | ||
20 | |||
21 | #endif | ||
22 | |||
diff --git a/drivers/mmc/core/sdio_cis.c b/drivers/mmc/core/sdio_cis.c new file mode 100644 index 000000000000..d5e51b1c7b3f --- /dev/null +++ b/drivers/mmc/core/sdio_cis.c | |||
@@ -0,0 +1,346 @@ | |||
1 | /* | ||
2 | * linux/drivers/mmc/core/sdio_cis.c | ||
3 | * | ||
4 | * Author: Nicolas Pitre | ||
5 | * Created: June 11, 2007 | ||
6 | * Copyright: MontaVista Software Inc. | ||
7 | * | ||
8 | * Copyright 2007 Pierre Ossman | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of the GNU General Public License as published by | ||
12 | * the Free Software Foundation; either version 2 of the License, or (at | ||
13 | * your option) any later version. | ||
14 | */ | ||
15 | |||
16 | #include <linux/kernel.h> | ||
17 | |||
18 | #include <linux/mmc/host.h> | ||
19 | #include <linux/mmc/card.h> | ||
20 | #include <linux/mmc/sdio.h> | ||
21 | #include <linux/mmc/sdio_func.h> | ||
22 | |||
23 | #include "sdio_cis.h" | ||
24 | #include "sdio_ops.h" | ||
25 | |||
26 | static int cistpl_vers_1(struct mmc_card *card, struct sdio_func *func, | ||
27 | const unsigned char *buf, unsigned size) | ||
28 | { | ||
29 | unsigned i, nr_strings; | ||
30 | char **buffer, *string; | ||
31 | |||
32 | buf += 2; | ||
33 | size -= 2; | ||
34 | |||
35 | nr_strings = 0; | ||
36 | for (i = 0; i < size; i++) { | ||
37 | if (buf[i] == 0xff) | ||
38 | break; | ||
39 | if (buf[i] == 0) | ||
40 | nr_strings++; | ||
41 | } | ||
42 | |||
43 | if (buf[i-1] != '\0') { | ||
44 | printk(KERN_WARNING "SDIO: ignoring broken CISTPL_VERS_1\n"); | ||
45 | return 0; | ||
46 | } | ||
47 | |||
48 | size = i; | ||
49 | |||
50 | buffer = kzalloc(sizeof(char*) * nr_strings + size, GFP_KERNEL); | ||
51 | if (!buffer) | ||
52 | return -ENOMEM; | ||
53 | |||
54 | string = (char*)(buffer + nr_strings); | ||
55 | |||
56 | for (i = 0; i < nr_strings; i++) { | ||
57 | buffer[i] = string; | ||
58 | strcpy(string, buf); | ||
59 | string += strlen(string) + 1; | ||
60 | buf += strlen(buf) + 1; | ||
61 | } | ||
62 | |||
63 | if (func) { | ||
64 | func->num_info = nr_strings; | ||
65 | func->info = (const char**)buffer; | ||
66 | } else { | ||
67 | card->num_info = nr_strings; | ||
68 | card->info = (const char**)buffer; | ||
69 | } | ||
70 | |||
71 | return 0; | ||
72 | } | ||
73 | |||
74 | static int cistpl_manfid(struct mmc_card *card, struct sdio_func *func, | ||
75 | const unsigned char *buf, unsigned size) | ||
76 | { | ||
77 | unsigned int vendor, device; | ||
78 | |||
79 | /* TPLMID_MANF */ | ||
80 | vendor = buf[0] | (buf[1] << 8); | ||
81 | |||
82 | /* TPLMID_CARD */ | ||
83 | device = buf[2] | (buf[3] << 8); | ||
84 | |||
85 | if (func) { | ||
86 | func->vendor = vendor; | ||
87 | func->device = device; | ||
88 | } else { | ||
89 | card->cis.vendor = vendor; | ||
90 | card->cis.device = device; | ||
91 | } | ||
92 | |||
93 | return 0; | ||
94 | } | ||
95 | |||
96 | static const unsigned char speed_val[16] = | ||
97 | { 0, 10, 12, 13, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 70, 80 }; | ||
98 | static const unsigned int speed_unit[8] = | ||
99 | { 10000, 100000, 1000000, 10000000, 0, 0, 0, 0 }; | ||
100 | |||
101 | static int cistpl_funce_common(struct mmc_card *card, | ||
102 | const unsigned char *buf, unsigned size) | ||
103 | { | ||
104 | if (size < 0x04 || buf[0] != 0) | ||
105 | return -EINVAL; | ||
106 | |||
107 | /* TPLFE_FN0_BLK_SIZE */ | ||
108 | card->cis.blksize = buf[1] | (buf[2] << 8); | ||
109 | |||
110 | /* TPLFE_MAX_TRAN_SPEED */ | ||
111 | card->cis.max_dtr = speed_val[(buf[3] >> 3) & 15] * | ||
112 | speed_unit[buf[3] & 7]; | ||
113 | |||
114 | return 0; | ||
115 | } | ||
116 | |||
117 | static int cistpl_funce_func(struct sdio_func *func, | ||
118 | const unsigned char *buf, unsigned size) | ||
119 | { | ||
120 | unsigned vsn; | ||
121 | unsigned min_size; | ||
122 | |||
123 | vsn = func->card->cccr.sdio_vsn; | ||
124 | min_size = (vsn == SDIO_SDIO_REV_1_00) ? 28 : 42; | ||
125 | |||
126 | if (size < min_size || buf[0] != 1) | ||
127 | return -EINVAL; | ||
128 | |||
129 | /* TPLFE_MAX_BLK_SIZE */ | ||
130 | func->max_blksize = buf[12] | (buf[13] << 8); | ||
131 | |||
132 | return 0; | ||
133 | } | ||
134 | |||
135 | static int cistpl_funce(struct mmc_card *card, struct sdio_func *func, | ||
136 | const unsigned char *buf, unsigned size) | ||
137 | { | ||
138 | int ret; | ||
139 | |||
140 | /* | ||
141 | * There should be two versions of the CISTPL_FUNCE tuple, | ||
142 | * one for the common CIS (function 0) and a version used by | ||
143 | * the individual function's CIS (1-7). Yet, the later has a | ||
144 | * different length depending on the SDIO spec version. | ||
145 | */ | ||
146 | if (func) | ||
147 | ret = cistpl_funce_func(func, buf, size); | ||
148 | else | ||
149 | ret = cistpl_funce_common(card, buf, size); | ||
150 | |||
151 | if (ret) { | ||
152 | printk(KERN_ERR "%s: bad CISTPL_FUNCE size %u " | ||
153 | "type %u\n", mmc_hostname(card->host), size, buf[0]); | ||
154 | return ret; | ||
155 | } | ||
156 | |||
157 | return 0; | ||
158 | } | ||
159 | |||
160 | typedef int (tpl_parse_t)(struct mmc_card *, struct sdio_func *, | ||
161 | const unsigned char *, unsigned); | ||
162 | |||
163 | struct cis_tpl { | ||
164 | unsigned char code; | ||
165 | unsigned char min_size; | ||
166 | tpl_parse_t *parse; | ||
167 | }; | ||
168 | |||
169 | static const struct cis_tpl cis_tpl_list[] = { | ||
170 | { 0x15, 3, cistpl_vers_1 }, | ||
171 | { 0x20, 4, cistpl_manfid }, | ||
172 | { 0x21, 2, /* cistpl_funcid */ }, | ||
173 | { 0x22, 0, cistpl_funce }, | ||
174 | }; | ||
175 | |||
176 | static int sdio_read_cis(struct mmc_card *card, struct sdio_func *func) | ||
177 | { | ||
178 | int ret; | ||
179 | struct sdio_func_tuple *this, **prev; | ||
180 | unsigned i, ptr = 0; | ||
181 | |||
182 | /* | ||
183 | * Note that this works for the common CIS (function number 0) as | ||
184 | * well as a function's CIS * since SDIO_CCCR_CIS and SDIO_FBR_CIS | ||
185 | * have the same offset. | ||
186 | */ | ||
187 | for (i = 0; i < 3; i++) { | ||
188 | unsigned char x, fn; | ||
189 | |||
190 | if (func) | ||
191 | fn = func->num; | ||
192 | else | ||
193 | fn = 0; | ||
194 | |||
195 | ret = mmc_io_rw_direct(card, 0, 0, | ||
196 | SDIO_FBR_BASE(fn) + SDIO_FBR_CIS + i, 0, &x); | ||
197 | if (ret) | ||
198 | return ret; | ||
199 | ptr |= x << (i * 8); | ||
200 | } | ||
201 | |||
202 | if (func) | ||
203 | prev = &func->tuples; | ||
204 | else | ||
205 | prev = &card->tuples; | ||
206 | |||
207 | BUG_ON(*prev); | ||
208 | |||
209 | do { | ||
210 | unsigned char tpl_code, tpl_link; | ||
211 | |||
212 | ret = mmc_io_rw_direct(card, 0, 0, ptr++, 0, &tpl_code); | ||
213 | if (ret) | ||
214 | break; | ||
215 | |||
216 | /* 0xff means we're done */ | ||
217 | if (tpl_code == 0xff) | ||
218 | break; | ||
219 | |||
220 | ret = mmc_io_rw_direct(card, 0, 0, ptr++, 0, &tpl_link); | ||
221 | if (ret) | ||
222 | break; | ||
223 | |||
224 | this = kmalloc(sizeof(*this) + tpl_link, GFP_KERNEL); | ||
225 | if (!this) | ||
226 | return -ENOMEM; | ||
227 | |||
228 | for (i = 0; i < tpl_link; i++) { | ||
229 | ret = mmc_io_rw_direct(card, 0, 0, | ||
230 | ptr + i, 0, &this->data[i]); | ||
231 | if (ret) | ||
232 | break; | ||
233 | } | ||
234 | if (ret) { | ||
235 | kfree(this); | ||
236 | break; | ||
237 | } | ||
238 | |||
239 | for (i = 0; i < ARRAY_SIZE(cis_tpl_list); i++) | ||
240 | if (cis_tpl_list[i].code == tpl_code) | ||
241 | break; | ||
242 | if (i >= ARRAY_SIZE(cis_tpl_list)) { | ||
243 | /* this tuple is unknown to the core */ | ||
244 | this->next = NULL; | ||
245 | this->code = tpl_code; | ||
246 | this->size = tpl_link; | ||
247 | *prev = this; | ||
248 | prev = &this->next; | ||
249 | printk(KERN_DEBUG | ||
250 | "%s: queuing CIS tuple 0x%02x length %u\n", | ||
251 | mmc_hostname(card->host), tpl_code, tpl_link); | ||
252 | } else { | ||
253 | const struct cis_tpl *tpl = cis_tpl_list + i; | ||
254 | if (tpl_link < tpl->min_size) { | ||
255 | printk(KERN_ERR | ||
256 | "%s: bad CIS tuple 0x%02x (length = %u, expected >= %u)\n", | ||
257 | mmc_hostname(card->host), | ||
258 | tpl_code, tpl_link, tpl->min_size); | ||
259 | ret = -EINVAL; | ||
260 | } else if (tpl->parse) { | ||
261 | ret = tpl->parse(card, func, | ||
262 | this->data, tpl_link); | ||
263 | } | ||
264 | kfree(this); | ||
265 | } | ||
266 | |||
267 | ptr += tpl_link; | ||
268 | } while (!ret); | ||
269 | |||
270 | /* | ||
271 | * Link in all unknown tuples found in the common CIS so that | ||
272 | * drivers don't have to go digging in two places. | ||
273 | */ | ||
274 | if (func) | ||
275 | *prev = card->tuples; | ||
276 | |||
277 | return ret; | ||
278 | } | ||
279 | |||
280 | int sdio_read_common_cis(struct mmc_card *card) | ||
281 | { | ||
282 | return sdio_read_cis(card, NULL); | ||
283 | } | ||
284 | |||
285 | void sdio_free_common_cis(struct mmc_card *card) | ||
286 | { | ||
287 | struct sdio_func_tuple *tuple, *victim; | ||
288 | |||
289 | tuple = card->tuples; | ||
290 | |||
291 | while (tuple) { | ||
292 | victim = tuple; | ||
293 | tuple = tuple->next; | ||
294 | kfree(victim); | ||
295 | } | ||
296 | |||
297 | card->tuples = NULL; | ||
298 | } | ||
299 | |||
300 | int sdio_read_func_cis(struct sdio_func *func) | ||
301 | { | ||
302 | int ret; | ||
303 | |||
304 | ret = sdio_read_cis(func->card, func); | ||
305 | if (ret) | ||
306 | return ret; | ||
307 | |||
308 | /* | ||
309 | * Since we've linked to tuples in the card structure, | ||
310 | * we must make sure we have a reference to it. | ||
311 | */ | ||
312 | get_device(&func->card->dev); | ||
313 | |||
314 | /* | ||
315 | * Vendor/device id is optional for function CIS, so | ||
316 | * copy it from the card structure as needed. | ||
317 | */ | ||
318 | if (func->vendor == 0) { | ||
319 | func->vendor = func->card->cis.vendor; | ||
320 | func->device = func->card->cis.device; | ||
321 | } | ||
322 | |||
323 | return 0; | ||
324 | } | ||
325 | |||
326 | void sdio_free_func_cis(struct sdio_func *func) | ||
327 | { | ||
328 | struct sdio_func_tuple *tuple, *victim; | ||
329 | |||
330 | tuple = func->tuples; | ||
331 | |||
332 | while (tuple && tuple != func->card->tuples) { | ||
333 | victim = tuple; | ||
334 | tuple = tuple->next; | ||
335 | kfree(victim); | ||
336 | } | ||
337 | |||
338 | func->tuples = NULL; | ||
339 | |||
340 | /* | ||
341 | * We have now removed the link to the tuples in the | ||
342 | * card structure, so remove the reference. | ||
343 | */ | ||
344 | put_device(&func->card->dev); | ||
345 | } | ||
346 | |||
diff --git a/drivers/mmc/core/sdio_cis.h b/drivers/mmc/core/sdio_cis.h new file mode 100644 index 000000000000..4d903c2e425e --- /dev/null +++ b/drivers/mmc/core/sdio_cis.h | |||
@@ -0,0 +1,23 @@ | |||
1 | /* | ||
2 | * linux/drivers/mmc/core/sdio_cis.h | ||
3 | * | ||
4 | * Author: Nicolas Pitre | ||
5 | * Created: June 11, 2007 | ||
6 | * Copyright: MontaVista Software Inc. | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License as published by | ||
10 | * the Free Software Foundation; either version 2 of the License, or (at | ||
11 | * your option) any later version. | ||
12 | */ | ||
13 | |||
14 | #ifndef _MMC_SDIO_CIS_H | ||
15 | #define _MMC_SDIO_CIS_H | ||
16 | |||
17 | int sdio_read_common_cis(struct mmc_card *card); | ||
18 | void sdio_free_common_cis(struct mmc_card *card); | ||
19 | |||
20 | int sdio_read_func_cis(struct sdio_func *func); | ||
21 | void sdio_free_func_cis(struct sdio_func *func); | ||
22 | |||
23 | #endif | ||
diff --git a/drivers/mmc/core/sdio_io.c b/drivers/mmc/core/sdio_io.c new file mode 100644 index 000000000000..625b92ce9cef --- /dev/null +++ b/drivers/mmc/core/sdio_io.c | |||
@@ -0,0 +1,548 @@ | |||
1 | /* | ||
2 | * linux/drivers/mmc/core/sdio_io.c | ||
3 | * | ||
4 | * Copyright 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/mmc/host.h> | ||
13 | #include <linux/mmc/card.h> | ||
14 | #include <linux/mmc/sdio.h> | ||
15 | #include <linux/mmc/sdio_func.h> | ||
16 | |||
17 | #include "sdio_ops.h" | ||
18 | |||
19 | /** | ||
20 | * sdio_claim_host - exclusively claim a bus for a certain SDIO function | ||
21 | * @func: SDIO function that will be accessed | ||
22 | * | ||
23 | * Claim a bus for a set of operations. The SDIO function given | ||
24 | * is used to figure out which bus is relevant. | ||
25 | */ | ||
26 | void sdio_claim_host(struct sdio_func *func) | ||
27 | { | ||
28 | BUG_ON(!func); | ||
29 | BUG_ON(!func->card); | ||
30 | |||
31 | mmc_claim_host(func->card->host); | ||
32 | } | ||
33 | EXPORT_SYMBOL_GPL(sdio_claim_host); | ||
34 | |||
35 | /** | ||
36 | * sdio_release_host - release a bus for a certain SDIO function | ||
37 | * @func: SDIO function that was accessed | ||
38 | * | ||
39 | * Release a bus, allowing others to claim the bus for their | ||
40 | * operations. | ||
41 | */ | ||
42 | void sdio_release_host(struct sdio_func *func) | ||
43 | { | ||
44 | BUG_ON(!func); | ||
45 | BUG_ON(!func->card); | ||
46 | |||
47 | mmc_release_host(func->card->host); | ||
48 | } | ||
49 | EXPORT_SYMBOL_GPL(sdio_release_host); | ||
50 | |||
51 | /** | ||
52 | * sdio_enable_func - enables a SDIO function for usage | ||
53 | * @func: SDIO function to enable | ||
54 | * | ||
55 | * Powers up and activates a SDIO function so that register | ||
56 | * access is possible. | ||
57 | */ | ||
58 | int sdio_enable_func(struct sdio_func *func) | ||
59 | { | ||
60 | int ret; | ||
61 | unsigned char reg; | ||
62 | unsigned long timeout; | ||
63 | |||
64 | BUG_ON(!func); | ||
65 | BUG_ON(!func->card); | ||
66 | |||
67 | pr_debug("SDIO: Enabling device %s...\n", sdio_func_id(func)); | ||
68 | |||
69 | ret = mmc_io_rw_direct(func->card, 0, 0, SDIO_CCCR_IOEx, 0, ®); | ||
70 | if (ret) | ||
71 | goto err; | ||
72 | |||
73 | reg |= 1 << func->num; | ||
74 | |||
75 | ret = mmc_io_rw_direct(func->card, 1, 0, SDIO_CCCR_IOEx, reg, NULL); | ||
76 | if (ret) | ||
77 | goto err; | ||
78 | |||
79 | /* | ||
80 | * FIXME: This should timeout based on information in the CIS, | ||
81 | * but we don't have card to parse that yet. | ||
82 | */ | ||
83 | timeout = jiffies + HZ; | ||
84 | |||
85 | while (1) { | ||
86 | ret = mmc_io_rw_direct(func->card, 0, 0, SDIO_CCCR_IORx, 0, ®); | ||
87 | if (ret) | ||
88 | goto err; | ||
89 | if (reg & (1 << func->num)) | ||
90 | break; | ||
91 | ret = -ETIME; | ||
92 | if (time_after(jiffies, timeout)) | ||
93 | goto err; | ||
94 | } | ||
95 | |||
96 | pr_debug("SDIO: Enabled device %s\n", sdio_func_id(func)); | ||
97 | |||
98 | return 0; | ||
99 | |||
100 | err: | ||
101 | pr_debug("SDIO: Failed to enable device %s\n", sdio_func_id(func)); | ||
102 | return ret; | ||
103 | } | ||
104 | EXPORT_SYMBOL_GPL(sdio_enable_func); | ||
105 | |||
106 | /** | ||
107 | * sdio_disable_func - disable a SDIO function | ||
108 | * @func: SDIO function to disable | ||
109 | * | ||
110 | * Powers down and deactivates a SDIO function. Register access | ||
111 | * to this function will fail until the function is reenabled. | ||
112 | */ | ||
113 | int sdio_disable_func(struct sdio_func *func) | ||
114 | { | ||
115 | int ret; | ||
116 | unsigned char reg; | ||
117 | |||
118 | BUG_ON(!func); | ||
119 | BUG_ON(!func->card); | ||
120 | |||
121 | pr_debug("SDIO: Disabling device %s...\n", sdio_func_id(func)); | ||
122 | |||
123 | ret = mmc_io_rw_direct(func->card, 0, 0, SDIO_CCCR_IOEx, 0, ®); | ||
124 | if (ret) | ||
125 | goto err; | ||
126 | |||
127 | reg &= ~(1 << func->num); | ||
128 | |||
129 | ret = mmc_io_rw_direct(func->card, 1, 0, SDIO_CCCR_IOEx, reg, NULL); | ||
130 | if (ret) | ||
131 | goto err; | ||
132 | |||
133 | pr_debug("SDIO: Disabled device %s\n", sdio_func_id(func)); | ||
134 | |||
135 | return 0; | ||
136 | |||
137 | err: | ||
138 | pr_debug("SDIO: Failed to disable device %s\n", sdio_func_id(func)); | ||
139 | return -EIO; | ||
140 | } | ||
141 | EXPORT_SYMBOL_GPL(sdio_disable_func); | ||
142 | |||
143 | /** | ||
144 | * sdio_set_block_size - set the block size of an SDIO function | ||
145 | * @func: SDIO function to change | ||
146 | * @blksz: new block size or 0 to use the default. | ||
147 | * | ||
148 | * The default block size is the largest supported by both the function | ||
149 | * and the host, with a maximum of 512 to ensure that arbitrarily sized | ||
150 | * data transfer use the optimal (least) number of commands. | ||
151 | * | ||
152 | * A driver may call this to override the default block size set by the | ||
153 | * core. This can be used to set a block size greater than the maximum | ||
154 | * that reported by the card; it is the driver's responsibility to ensure | ||
155 | * it uses a value that the card supports. | ||
156 | * | ||
157 | * Returns 0 on success, -EINVAL if the host does not support the | ||
158 | * requested block size, or -EIO (etc.) if one of the resultant FBR block | ||
159 | * size register writes failed. | ||
160 | * | ||
161 | */ | ||
162 | int sdio_set_block_size(struct sdio_func *func, unsigned blksz) | ||
163 | { | ||
164 | int ret; | ||
165 | |||
166 | if (blksz > func->card->host->max_blk_size) | ||
167 | return -EINVAL; | ||
168 | |||
169 | if (blksz == 0) { | ||
170 | blksz = min(min( | ||
171 | func->max_blksize, | ||
172 | func->card->host->max_blk_size), | ||
173 | 512u); | ||
174 | } | ||
175 | |||
176 | ret = mmc_io_rw_direct(func->card, 1, 0, | ||
177 | SDIO_FBR_BASE(func->num) + SDIO_FBR_BLKSIZE, | ||
178 | blksz & 0xff, NULL); | ||
179 | if (ret) | ||
180 | return ret; | ||
181 | ret = mmc_io_rw_direct(func->card, 1, 0, | ||
182 | SDIO_FBR_BASE(func->num) + SDIO_FBR_BLKSIZE + 1, | ||
183 | (blksz >> 8) & 0xff, NULL); | ||
184 | if (ret) | ||
185 | return ret; | ||
186 | func->cur_blksize = blksz; | ||
187 | return 0; | ||
188 | } | ||
189 | |||
190 | EXPORT_SYMBOL_GPL(sdio_set_block_size); | ||
191 | |||
192 | /* Split an arbitrarily sized data transfer into several | ||
193 | * IO_RW_EXTENDED commands. */ | ||
194 | static int sdio_io_rw_ext_helper(struct sdio_func *func, int write, | ||
195 | unsigned addr, int incr_addr, u8 *buf, unsigned size) | ||
196 | { | ||
197 | unsigned remainder = size; | ||
198 | unsigned max_blocks; | ||
199 | int ret; | ||
200 | |||
201 | /* Do the bulk of the transfer using block mode (if supported). */ | ||
202 | if (func->card->cccr.multi_block) { | ||
203 | /* Blocks per command is limited by host count, host transfer | ||
204 | * size (we only use a single sg entry) and the maximum for | ||
205 | * IO_RW_EXTENDED of 511 blocks. */ | ||
206 | max_blocks = min(min( | ||
207 | func->card->host->max_blk_count, | ||
208 | func->card->host->max_seg_size / func->cur_blksize), | ||
209 | 511u); | ||
210 | |||
211 | while (remainder > func->cur_blksize) { | ||
212 | unsigned blocks; | ||
213 | |||
214 | blocks = remainder / func->cur_blksize; | ||
215 | if (blocks > max_blocks) | ||
216 | blocks = max_blocks; | ||
217 | size = blocks * func->cur_blksize; | ||
218 | |||
219 | ret = mmc_io_rw_extended(func->card, write, | ||
220 | func->num, addr, incr_addr, buf, | ||
221 | blocks, func->cur_blksize); | ||
222 | if (ret) | ||
223 | return ret; | ||
224 | |||
225 | remainder -= size; | ||
226 | buf += size; | ||
227 | if (incr_addr) | ||
228 | addr += size; | ||
229 | } | ||
230 | } | ||
231 | |||
232 | /* Write the remainder using byte mode. */ | ||
233 | while (remainder > 0) { | ||
234 | size = remainder; | ||
235 | if (size > func->cur_blksize) | ||
236 | size = func->cur_blksize; | ||
237 | if (size > 512) | ||
238 | size = 512; /* maximum size for byte mode */ | ||
239 | |||
240 | ret = mmc_io_rw_extended(func->card, write, func->num, addr, | ||
241 | incr_addr, buf, 1, size); | ||
242 | if (ret) | ||
243 | return ret; | ||
244 | |||
245 | remainder -= size; | ||
246 | buf += size; | ||
247 | if (incr_addr) | ||
248 | addr += size; | ||
249 | } | ||
250 | return 0; | ||
251 | } | ||
252 | |||
253 | /** | ||
254 | * sdio_readb - read a single byte from a SDIO function | ||
255 | * @func: SDIO function to access | ||
256 | * @addr: address to read | ||
257 | * @err_ret: optional status value from transfer | ||
258 | * | ||
259 | * Reads a single byte from the address space of a given SDIO | ||
260 | * function. If there is a problem reading the address, 0xff | ||
261 | * is returned and @err_ret will contain the error code. | ||
262 | */ | ||
263 | unsigned char sdio_readb(struct sdio_func *func, unsigned int addr, | ||
264 | int *err_ret) | ||
265 | { | ||
266 | int ret; | ||
267 | unsigned char val; | ||
268 | |||
269 | BUG_ON(!func); | ||
270 | |||
271 | if (err_ret) | ||
272 | *err_ret = 0; | ||
273 | |||
274 | ret = mmc_io_rw_direct(func->card, 0, func->num, addr, 0, &val); | ||
275 | if (ret) { | ||
276 | if (err_ret) | ||
277 | *err_ret = ret; | ||
278 | return 0xFF; | ||
279 | } | ||
280 | |||
281 | return val; | ||
282 | } | ||
283 | EXPORT_SYMBOL_GPL(sdio_readb); | ||
284 | |||
285 | /** | ||
286 | * sdio_writeb - write a single byte to a SDIO function | ||
287 | * @func: SDIO function to access | ||
288 | * @b: byte to write | ||
289 | * @addr: address to write to | ||
290 | * @err_ret: optional status value from transfer | ||
291 | * | ||
292 | * Writes a single byte to the address space of a given SDIO | ||
293 | * function. @err_ret will contain the status of the actual | ||
294 | * transfer. | ||
295 | */ | ||
296 | void sdio_writeb(struct sdio_func *func, unsigned char b, unsigned int addr, | ||
297 | int *err_ret) | ||
298 | { | ||
299 | int ret; | ||
300 | |||
301 | BUG_ON(!func); | ||
302 | |||
303 | ret = mmc_io_rw_direct(func->card, 1, func->num, addr, b, NULL); | ||
304 | if (err_ret) | ||
305 | *err_ret = ret; | ||
306 | } | ||
307 | EXPORT_SYMBOL_GPL(sdio_writeb); | ||
308 | |||
309 | /** | ||
310 | * sdio_memcpy_fromio - read a chunk of memory from a SDIO function | ||
311 | * @func: SDIO function to access | ||
312 | * @dst: buffer to store the data | ||
313 | * @addr: address to begin reading from | ||
314 | * @count: number of bytes to read | ||
315 | * | ||
316 | * Reads from the address space of a given SDIO function. Return | ||
317 | * value indicates if the transfer succeeded or not. | ||
318 | */ | ||
319 | int sdio_memcpy_fromio(struct sdio_func *func, void *dst, | ||
320 | unsigned int addr, int count) | ||
321 | { | ||
322 | return sdio_io_rw_ext_helper(func, 0, addr, 1, dst, count); | ||
323 | } | ||
324 | EXPORT_SYMBOL_GPL(sdio_memcpy_fromio); | ||
325 | |||
326 | /** | ||
327 | * sdio_memcpy_toio - write a chunk of memory to a SDIO function | ||
328 | * @func: SDIO function to access | ||
329 | * @addr: address to start writing to | ||
330 | * @src: buffer that contains the data to write | ||
331 | * @count: number of bytes to write | ||
332 | * | ||
333 | * Writes to the address space of a given SDIO function. Return | ||
334 | * value indicates if the transfer succeeded or not. | ||
335 | */ | ||
336 | int sdio_memcpy_toio(struct sdio_func *func, unsigned int addr, | ||
337 | void *src, int count) | ||
338 | { | ||
339 | return sdio_io_rw_ext_helper(func, 1, addr, 1, src, count); | ||
340 | } | ||
341 | EXPORT_SYMBOL_GPL(sdio_memcpy_toio); | ||
342 | |||
343 | /** | ||
344 | * sdio_readsb - read from a FIFO on a SDIO function | ||
345 | * @func: SDIO function to access | ||
346 | * @dst: buffer to store the data | ||
347 | * @addr: address of (single byte) FIFO | ||
348 | * @count: number of bytes to read | ||
349 | * | ||
350 | * Reads from the specified FIFO of a given SDIO function. Return | ||
351 | * value indicates if the transfer succeeded or not. | ||
352 | */ | ||
353 | int sdio_readsb(struct sdio_func *func, void *dst, unsigned int addr, | ||
354 | int count) | ||
355 | { | ||
356 | return sdio_io_rw_ext_helper(func, 0, addr, 0, dst, count); | ||
357 | } | ||
358 | |||
359 | EXPORT_SYMBOL_GPL(sdio_readsb); | ||
360 | |||
361 | /** | ||
362 | * sdio_writesb - write to a FIFO of a SDIO function | ||
363 | * @func: SDIO function to access | ||
364 | * @addr: address of (single byte) FIFO | ||
365 | * @src: buffer that contains the data to write | ||
366 | * @count: number of bytes to write | ||
367 | * | ||
368 | * Writes to the specified FIFO of a given SDIO function. Return | ||
369 | * value indicates if the transfer succeeded or not. | ||
370 | */ | ||
371 | int sdio_writesb(struct sdio_func *func, unsigned int addr, void *src, | ||
372 | int count) | ||
373 | { | ||
374 | return sdio_io_rw_ext_helper(func, 1, addr, 0, src, count); | ||
375 | } | ||
376 | EXPORT_SYMBOL_GPL(sdio_writesb); | ||
377 | |||
378 | /** | ||
379 | * sdio_readw - read a 16 bit integer from a SDIO function | ||
380 | * @func: SDIO function to access | ||
381 | * @addr: address to read | ||
382 | * @err_ret: optional status value from transfer | ||
383 | * | ||
384 | * Reads a 16 bit integer from the address space of a given SDIO | ||
385 | * function. If there is a problem reading the address, 0xffff | ||
386 | * is returned and @err_ret will contain the error code. | ||
387 | */ | ||
388 | unsigned short sdio_readw(struct sdio_func *func, unsigned int addr, | ||
389 | int *err_ret) | ||
390 | { | ||
391 | int ret; | ||
392 | |||
393 | if (err_ret) | ||
394 | *err_ret = 0; | ||
395 | |||
396 | ret = sdio_memcpy_fromio(func, func->tmpbuf, addr, 2); | ||
397 | if (ret) { | ||
398 | if (err_ret) | ||
399 | *err_ret = ret; | ||
400 | return 0xFFFF; | ||
401 | } | ||
402 | |||
403 | return le16_to_cpu(*(u16*)func->tmpbuf); | ||
404 | } | ||
405 | EXPORT_SYMBOL_GPL(sdio_readw); | ||
406 | |||
407 | /** | ||
408 | * sdio_writew - write a 16 bit integer to a SDIO function | ||
409 | * @func: SDIO function to access | ||
410 | * @b: integer to write | ||
411 | * @addr: address to write to | ||
412 | * @err_ret: optional status value from transfer | ||
413 | * | ||
414 | * Writes a 16 bit integer to the address space of a given SDIO | ||
415 | * function. @err_ret will contain the status of the actual | ||
416 | * transfer. | ||
417 | */ | ||
418 | void sdio_writew(struct sdio_func *func, unsigned short b, unsigned int addr, | ||
419 | int *err_ret) | ||
420 | { | ||
421 | int ret; | ||
422 | |||
423 | *(u16*)func->tmpbuf = cpu_to_le16(b); | ||
424 | |||
425 | ret = sdio_memcpy_toio(func, addr, func->tmpbuf, 2); | ||
426 | if (err_ret) | ||
427 | *err_ret = ret; | ||
428 | } | ||
429 | EXPORT_SYMBOL_GPL(sdio_writew); | ||
430 | |||
431 | /** | ||
432 | * sdio_readl - read a 32 bit integer from a SDIO function | ||
433 | * @func: SDIO function to access | ||
434 | * @addr: address to read | ||
435 | * @err_ret: optional status value from transfer | ||
436 | * | ||
437 | * Reads a 32 bit integer from the address space of a given SDIO | ||
438 | * function. If there is a problem reading the address, | ||
439 | * 0xffffffff is returned and @err_ret will contain the error | ||
440 | * code. | ||
441 | */ | ||
442 | unsigned long sdio_readl(struct sdio_func *func, unsigned int addr, | ||
443 | int *err_ret) | ||
444 | { | ||
445 | int ret; | ||
446 | |||
447 | if (err_ret) | ||
448 | *err_ret = 0; | ||
449 | |||
450 | ret = sdio_memcpy_fromio(func, func->tmpbuf, addr, 4); | ||
451 | if (ret) { | ||
452 | if (err_ret) | ||
453 | *err_ret = ret; | ||
454 | return 0xFFFFFFFF; | ||
455 | } | ||
456 | |||
457 | return le32_to_cpu(*(u32*)func->tmpbuf); | ||
458 | } | ||
459 | EXPORT_SYMBOL_GPL(sdio_readl); | ||
460 | |||
461 | /** | ||
462 | * sdio_writel - write a 32 bit integer to a SDIO function | ||
463 | * @func: SDIO function to access | ||
464 | * @b: integer to write | ||
465 | * @addr: address to write to | ||
466 | * @err_ret: optional status value from transfer | ||
467 | * | ||
468 | * Writes a 32 bit integer to the address space of a given SDIO | ||
469 | * function. @err_ret will contain the status of the actual | ||
470 | * transfer. | ||
471 | */ | ||
472 | void sdio_writel(struct sdio_func *func, unsigned long b, unsigned int addr, | ||
473 | int *err_ret) | ||
474 | { | ||
475 | int ret; | ||
476 | |||
477 | *(u32*)func->tmpbuf = cpu_to_le32(b); | ||
478 | |||
479 | ret = sdio_memcpy_toio(func, addr, func->tmpbuf, 4); | ||
480 | if (err_ret) | ||
481 | *err_ret = ret; | ||
482 | } | ||
483 | EXPORT_SYMBOL_GPL(sdio_writel); | ||
484 | |||
485 | /** | ||
486 | * sdio_f0_readb - read a single byte from SDIO function 0 | ||
487 | * @func: an SDIO function of the card | ||
488 | * @addr: address to read | ||
489 | * @err_ret: optional status value from transfer | ||
490 | * | ||
491 | * Reads a single byte from the address space of SDIO function 0. | ||
492 | * If there is a problem reading the address, 0xff is returned | ||
493 | * and @err_ret will contain the error code. | ||
494 | */ | ||
495 | unsigned char sdio_f0_readb(struct sdio_func *func, unsigned int addr, | ||
496 | int *err_ret) | ||
497 | { | ||
498 | int ret; | ||
499 | unsigned char val; | ||
500 | |||
501 | BUG_ON(!func); | ||
502 | |||
503 | if (err_ret) | ||
504 | *err_ret = 0; | ||
505 | |||
506 | ret = mmc_io_rw_direct(func->card, 0, 0, addr, 0, &val); | ||
507 | if (ret) { | ||
508 | if (err_ret) | ||
509 | *err_ret = ret; | ||
510 | return 0xFF; | ||
511 | } | ||
512 | |||
513 | return val; | ||
514 | } | ||
515 | EXPORT_SYMBOL_GPL(sdio_f0_readb); | ||
516 | |||
517 | /** | ||
518 | * sdio_f0_writeb - write a single byte to SDIO function 0 | ||
519 | * @func: an SDIO function of the card | ||
520 | * @b: byte to write | ||
521 | * @addr: address to write to | ||
522 | * @err_ret: optional status value from transfer | ||
523 | * | ||
524 | * Writes a single byte to the address space of SDIO function 0. | ||
525 | * @err_ret will contain the status of the actual transfer. | ||
526 | * | ||
527 | * Only writes to the vendor specific CCCR registers (0xF0 - | ||
528 | * 0xFF) are permiited; @err_ret will be set to -EINVAL for * | ||
529 | * writes outside this range. | ||
530 | */ | ||
531 | void sdio_f0_writeb(struct sdio_func *func, unsigned char b, unsigned int addr, | ||
532 | int *err_ret) | ||
533 | { | ||
534 | int ret; | ||
535 | |||
536 | BUG_ON(!func); | ||
537 | |||
538 | if (addr < 0xF0 || addr > 0xFF) { | ||
539 | if (err_ret) | ||
540 | *err_ret = -EINVAL; | ||
541 | return; | ||
542 | } | ||
543 | |||
544 | ret = mmc_io_rw_direct(func->card, 1, 0, addr, b, NULL); | ||
545 | if (err_ret) | ||
546 | *err_ret = ret; | ||
547 | } | ||
548 | EXPORT_SYMBOL_GPL(sdio_f0_writeb); | ||
diff --git a/drivers/mmc/core/sdio_irq.c b/drivers/mmc/core/sdio_irq.c new file mode 100644 index 000000000000..3bd3021f5e80 --- /dev/null +++ b/drivers/mmc/core/sdio_irq.c | |||
@@ -0,0 +1,267 @@ | |||
1 | /* | ||
2 | * linux/drivers/mmc/core/sdio_irq.c | ||
3 | * | ||
4 | * Author: Nicolas Pitre | ||
5 | * Created: June 18, 2007 | ||
6 | * Copyright: MontaVista Software Inc. | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License as published by | ||
10 | * the Free Software Foundation; either version 2 of the License, or (at | ||
11 | * your option) any later version. | ||
12 | */ | ||
13 | |||
14 | #include <linux/kernel.h> | ||
15 | #include <linux/sched.h> | ||
16 | #include <linux/kthread.h> | ||
17 | #include <linux/wait.h> | ||
18 | #include <linux/delay.h> | ||
19 | |||
20 | #include <linux/mmc/core.h> | ||
21 | #include <linux/mmc/host.h> | ||
22 | #include <linux/mmc/card.h> | ||
23 | #include <linux/mmc/sdio.h> | ||
24 | #include <linux/mmc/sdio_func.h> | ||
25 | |||
26 | #include "sdio_ops.h" | ||
27 | |||
28 | static int process_sdio_pending_irqs(struct mmc_card *card) | ||
29 | { | ||
30 | int i, ret, count; | ||
31 | unsigned char pending; | ||
32 | |||
33 | ret = mmc_io_rw_direct(card, 0, 0, SDIO_CCCR_INTx, 0, &pending); | ||
34 | if (ret) { | ||
35 | printk(KERN_DEBUG "%s: error %d reading SDIO_CCCR_INTx\n", | ||
36 | mmc_card_id(card), ret); | ||
37 | return ret; | ||
38 | } | ||
39 | |||
40 | count = 0; | ||
41 | for (i = 1; i <= 7; i++) { | ||
42 | if (pending & (1 << i)) { | ||
43 | struct sdio_func *func = card->sdio_func[i - 1]; | ||
44 | if (!func) { | ||
45 | printk(KERN_WARNING "%s: pending IRQ for " | ||
46 | "non-existant function\n", | ||
47 | mmc_card_id(card)); | ||
48 | ret = -EINVAL; | ||
49 | } else if (func->irq_handler) { | ||
50 | func->irq_handler(func); | ||
51 | count++; | ||
52 | } else { | ||
53 | printk(KERN_WARNING "%s: pending IRQ with no handler\n", | ||
54 | sdio_func_id(func)); | ||
55 | ret = -EINVAL; | ||
56 | } | ||
57 | } | ||
58 | } | ||
59 | |||
60 | if (count) | ||
61 | return count; | ||
62 | |||
63 | return ret; | ||
64 | } | ||
65 | |||
66 | static int sdio_irq_thread(void *_host) | ||
67 | { | ||
68 | struct mmc_host *host = _host; | ||
69 | struct sched_param param = { .sched_priority = 1 }; | ||
70 | unsigned long period, idle_period; | ||
71 | int ret; | ||
72 | |||
73 | sched_setscheduler(current, SCHED_FIFO, ¶m); | ||
74 | |||
75 | /* | ||
76 | * We want to allow for SDIO cards to work even on non SDIO | ||
77 | * aware hosts. One thing that non SDIO host cannot do is | ||
78 | * asynchronous notification of pending SDIO card interrupts | ||
79 | * hence we poll for them in that case. | ||
80 | */ | ||
81 | idle_period = msecs_to_jiffies(10); | ||
82 | period = (host->caps & MMC_CAP_SDIO_IRQ) ? | ||
83 | MAX_SCHEDULE_TIMEOUT : idle_period; | ||
84 | |||
85 | pr_debug("%s: IRQ thread started (poll period = %lu jiffies)\n", | ||
86 | mmc_hostname(host), period); | ||
87 | |||
88 | do { | ||
89 | /* | ||
90 | * We claim the host here on drivers behalf for a couple | ||
91 | * reasons: | ||
92 | * | ||
93 | * 1) it is already needed to retrieve the CCCR_INTx; | ||
94 | * 2) we want the driver(s) to clear the IRQ condition ASAP; | ||
95 | * 3) we need to control the abort condition locally. | ||
96 | * | ||
97 | * Just like traditional hard IRQ handlers, we expect SDIO | ||
98 | * IRQ handlers to be quick and to the point, so that the | ||
99 | * holding of the host lock does not cover too much work | ||
100 | * that doesn't require that lock to be held. | ||
101 | */ | ||
102 | ret = __mmc_claim_host(host, &host->sdio_irq_thread_abort); | ||
103 | if (ret) | ||
104 | break; | ||
105 | ret = process_sdio_pending_irqs(host->card); | ||
106 | mmc_release_host(host); | ||
107 | |||
108 | /* | ||
109 | * Give other threads a chance to run in the presence of | ||
110 | * errors. FIXME: determine if due to card removal and | ||
111 | * possibly exit this thread if so. | ||
112 | */ | ||
113 | if (ret < 0) | ||
114 | ssleep(1); | ||
115 | |||
116 | /* | ||
117 | * Adaptive polling frequency based on the assumption | ||
118 | * that an interrupt will be closely followed by more. | ||
119 | * This has a substantial benefit for network devices. | ||
120 | */ | ||
121 | if (!(host->caps & MMC_CAP_SDIO_IRQ)) { | ||
122 | if (ret > 0) | ||
123 | period /= 2; | ||
124 | else { | ||
125 | period++; | ||
126 | if (period > idle_period) | ||
127 | period = idle_period; | ||
128 | } | ||
129 | } | ||
130 | |||
131 | set_task_state(current, TASK_INTERRUPTIBLE); | ||
132 | if (host->caps & MMC_CAP_SDIO_IRQ) | ||
133 | host->ops->enable_sdio_irq(host, 1); | ||
134 | if (!kthread_should_stop()) | ||
135 | schedule_timeout(period); | ||
136 | set_task_state(current, TASK_RUNNING); | ||
137 | } while (!kthread_should_stop()); | ||
138 | |||
139 | if (host->caps & MMC_CAP_SDIO_IRQ) | ||
140 | host->ops->enable_sdio_irq(host, 0); | ||
141 | |||
142 | pr_debug("%s: IRQ thread exiting with code %d\n", | ||
143 | mmc_hostname(host), ret); | ||
144 | |||
145 | return ret; | ||
146 | } | ||
147 | |||
148 | static int sdio_card_irq_get(struct mmc_card *card) | ||
149 | { | ||
150 | struct mmc_host *host = card->host; | ||
151 | |||
152 | WARN_ON(!host->claimed); | ||
153 | |||
154 | if (!host->sdio_irqs++) { | ||
155 | atomic_set(&host->sdio_irq_thread_abort, 0); | ||
156 | host->sdio_irq_thread = | ||
157 | kthread_run(sdio_irq_thread, host, "ksdiorqd"); | ||
158 | if (IS_ERR(host->sdio_irq_thread)) { | ||
159 | int err = PTR_ERR(host->sdio_irq_thread); | ||
160 | host->sdio_irqs--; | ||
161 | return err; | ||
162 | } | ||
163 | } | ||
164 | |||
165 | return 0; | ||
166 | } | ||
167 | |||
168 | static int sdio_card_irq_put(struct mmc_card *card) | ||
169 | { | ||
170 | struct mmc_host *host = card->host; | ||
171 | |||
172 | WARN_ON(!host->claimed); | ||
173 | BUG_ON(host->sdio_irqs < 1); | ||
174 | |||
175 | if (!--host->sdio_irqs) { | ||
176 | atomic_set(&host->sdio_irq_thread_abort, 1); | ||
177 | kthread_stop(host->sdio_irq_thread); | ||
178 | } | ||
179 | |||
180 | return 0; | ||
181 | } | ||
182 | |||
183 | /** | ||
184 | * sdio_claim_irq - claim the IRQ for a SDIO function | ||
185 | * @func: SDIO function | ||
186 | * @handler: IRQ handler callback | ||
187 | * | ||
188 | * Claim and activate the IRQ for the given SDIO function. The provided | ||
189 | * handler will be called when that IRQ is asserted. The host is always | ||
190 | * claimed already when the handler is called so the handler must not | ||
191 | * call sdio_claim_host() nor sdio_release_host(). | ||
192 | */ | ||
193 | int sdio_claim_irq(struct sdio_func *func, sdio_irq_handler_t *handler) | ||
194 | { | ||
195 | int ret; | ||
196 | unsigned char reg; | ||
197 | |||
198 | BUG_ON(!func); | ||
199 | BUG_ON(!func->card); | ||
200 | |||
201 | pr_debug("SDIO: Enabling IRQ for %s...\n", sdio_func_id(func)); | ||
202 | |||
203 | if (func->irq_handler) { | ||
204 | pr_debug("SDIO: IRQ for %s already in use.\n", sdio_func_id(func)); | ||
205 | return -EBUSY; | ||
206 | } | ||
207 | |||
208 | ret = mmc_io_rw_direct(func->card, 0, 0, SDIO_CCCR_IENx, 0, ®); | ||
209 | if (ret) | ||
210 | return ret; | ||
211 | |||
212 | reg |= 1 << func->num; | ||
213 | |||
214 | reg |= 1; /* Master interrupt enable */ | ||
215 | |||
216 | ret = mmc_io_rw_direct(func->card, 1, 0, SDIO_CCCR_IENx, reg, NULL); | ||
217 | if (ret) | ||
218 | return ret; | ||
219 | |||
220 | func->irq_handler = handler; | ||
221 | ret = sdio_card_irq_get(func->card); | ||
222 | if (ret) | ||
223 | func->irq_handler = NULL; | ||
224 | |||
225 | return ret; | ||
226 | } | ||
227 | EXPORT_SYMBOL_GPL(sdio_claim_irq); | ||
228 | |||
229 | /** | ||
230 | * sdio_release_irq - release the IRQ for a SDIO function | ||
231 | * @func: SDIO function | ||
232 | * | ||
233 | * Disable and release the IRQ for the given SDIO function. | ||
234 | */ | ||
235 | int sdio_release_irq(struct sdio_func *func) | ||
236 | { | ||
237 | int ret; | ||
238 | unsigned char reg; | ||
239 | |||
240 | BUG_ON(!func); | ||
241 | BUG_ON(!func->card); | ||
242 | |||
243 | pr_debug("SDIO: Disabling IRQ for %s...\n", sdio_func_id(func)); | ||
244 | |||
245 | if (func->irq_handler) { | ||
246 | func->irq_handler = NULL; | ||
247 | sdio_card_irq_put(func->card); | ||
248 | } | ||
249 | |||
250 | ret = mmc_io_rw_direct(func->card, 0, 0, SDIO_CCCR_IENx, 0, ®); | ||
251 | if (ret) | ||
252 | return ret; | ||
253 | |||
254 | reg &= ~(1 << func->num); | ||
255 | |||
256 | /* Disable master interrupt with the last function interrupt */ | ||
257 | if (!(reg & 0xFE)) | ||
258 | reg = 0; | ||
259 | |||
260 | ret = mmc_io_rw_direct(func->card, 1, 0, SDIO_CCCR_IENx, reg, NULL); | ||
261 | if (ret) | ||
262 | return ret; | ||
263 | |||
264 | return 0; | ||
265 | } | ||
266 | EXPORT_SYMBOL_GPL(sdio_release_irq); | ||
267 | |||
diff --git a/drivers/mmc/core/sdio_ops.c b/drivers/mmc/core/sdio_ops.c new file mode 100644 index 000000000000..4d289b275031 --- /dev/null +++ b/drivers/mmc/core/sdio_ops.c | |||
@@ -0,0 +1,176 @@ | |||
1 | /* | ||
2 | * linux/drivers/mmc/sdio_ops.c | ||
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 <asm/scatterlist.h> | ||
13 | #include <linux/scatterlist.h> | ||
14 | |||
15 | #include <linux/mmc/host.h> | ||
16 | #include <linux/mmc/card.h> | ||
17 | #include <linux/mmc/mmc.h> | ||
18 | #include <linux/mmc/sdio.h> | ||
19 | |||
20 | #include "core.h" | ||
21 | |||
22 | int mmc_send_io_op_cond(struct mmc_host *host, u32 ocr, u32 *rocr) | ||
23 | { | ||
24 | struct mmc_command cmd; | ||
25 | int i, err = 0; | ||
26 | |||
27 | BUG_ON(!host); | ||
28 | |||
29 | memset(&cmd, 0, sizeof(struct mmc_command)); | ||
30 | |||
31 | cmd.opcode = SD_IO_SEND_OP_COND; | ||
32 | cmd.arg = ocr; | ||
33 | cmd.flags = MMC_RSP_SPI_R4 | MMC_RSP_R4 | MMC_CMD_BCR; | ||
34 | |||
35 | for (i = 100; i; i--) { | ||
36 | err = mmc_wait_for_cmd(host, &cmd, MMC_CMD_RETRIES); | ||
37 | if (err) | ||
38 | break; | ||
39 | |||
40 | /* if we're just probing, do a single pass */ | ||
41 | if (ocr == 0) | ||
42 | break; | ||
43 | |||
44 | /* otherwise wait until reset completes */ | ||
45 | if (mmc_host_is_spi(host)) { | ||
46 | /* | ||
47 | * Both R1_SPI_IDLE and MMC_CARD_BUSY indicate | ||
48 | * an initialized card under SPI, but some cards | ||
49 | * (Marvell's) only behave when looking at this | ||
50 | * one. | ||
51 | */ | ||
52 | if (cmd.resp[1] & MMC_CARD_BUSY) | ||
53 | break; | ||
54 | } else { | ||
55 | if (cmd.resp[0] & MMC_CARD_BUSY) | ||
56 | break; | ||
57 | } | ||
58 | |||
59 | err = -ETIMEDOUT; | ||
60 | |||
61 | mmc_delay(10); | ||
62 | } | ||
63 | |||
64 | if (rocr) | ||
65 | *rocr = cmd.resp[mmc_host_is_spi(host) ? 1 : 0]; | ||
66 | |||
67 | return err; | ||
68 | } | ||
69 | |||
70 | int mmc_io_rw_direct(struct mmc_card *card, int write, unsigned fn, | ||
71 | unsigned addr, u8 in, u8* out) | ||
72 | { | ||
73 | struct mmc_command cmd; | ||
74 | int err; | ||
75 | |||
76 | BUG_ON(!card); | ||
77 | BUG_ON(fn > 7); | ||
78 | |||
79 | memset(&cmd, 0, sizeof(struct mmc_command)); | ||
80 | |||
81 | cmd.opcode = SD_IO_RW_DIRECT; | ||
82 | cmd.arg = write ? 0x80000000 : 0x00000000; | ||
83 | cmd.arg |= fn << 28; | ||
84 | cmd.arg |= (write && out) ? 0x08000000 : 0x00000000; | ||
85 | cmd.arg |= addr << 9; | ||
86 | cmd.arg |= in; | ||
87 | cmd.flags = MMC_RSP_SPI_R5 | MMC_RSP_R5 | MMC_CMD_AC; | ||
88 | |||
89 | err = mmc_wait_for_cmd(card->host, &cmd, 0); | ||
90 | if (err) | ||
91 | return err; | ||
92 | |||
93 | if (mmc_host_is_spi(card->host)) { | ||
94 | /* host driver already reported errors */ | ||
95 | } else { | ||
96 | if (cmd.resp[0] & R5_ERROR) | ||
97 | return -EIO; | ||
98 | if (cmd.resp[0] & R5_FUNCTION_NUMBER) | ||
99 | return -EINVAL; | ||
100 | if (cmd.resp[0] & R5_OUT_OF_RANGE) | ||
101 | return -ERANGE; | ||
102 | } | ||
103 | |||
104 | if (out) { | ||
105 | if (mmc_host_is_spi(card->host)) | ||
106 | *out = (cmd.resp[0] >> 8) & 0xFF; | ||
107 | else | ||
108 | *out = cmd.resp[0] & 0xFF; | ||
109 | } | ||
110 | |||
111 | return 0; | ||
112 | } | ||
113 | |||
114 | int mmc_io_rw_extended(struct mmc_card *card, int write, unsigned fn, | ||
115 | unsigned addr, int incr_addr, u8 *buf, unsigned blocks, unsigned blksz) | ||
116 | { | ||
117 | struct mmc_request mrq; | ||
118 | struct mmc_command cmd; | ||
119 | struct mmc_data data; | ||
120 | struct scatterlist sg; | ||
121 | |||
122 | BUG_ON(!card); | ||
123 | BUG_ON(fn > 7); | ||
124 | BUG_ON(blocks == 1 && blksz > 512); | ||
125 | WARN_ON(blocks == 0); | ||
126 | WARN_ON(blksz == 0); | ||
127 | |||
128 | memset(&mrq, 0, sizeof(struct mmc_request)); | ||
129 | memset(&cmd, 0, sizeof(struct mmc_command)); | ||
130 | memset(&data, 0, sizeof(struct mmc_data)); | ||
131 | |||
132 | mrq.cmd = &cmd; | ||
133 | mrq.data = &data; | ||
134 | |||
135 | cmd.opcode = SD_IO_RW_EXTENDED; | ||
136 | cmd.arg = write ? 0x80000000 : 0x00000000; | ||
137 | cmd.arg |= fn << 28; | ||
138 | cmd.arg |= incr_addr ? 0x04000000 : 0x00000000; | ||
139 | cmd.arg |= addr << 9; | ||
140 | if (blocks == 1 && blksz <= 512) | ||
141 | cmd.arg |= (blksz == 512) ? 0 : blksz; /* byte mode */ | ||
142 | else | ||
143 | cmd.arg |= 0x08000000 | blocks; /* block mode */ | ||
144 | cmd.flags = MMC_RSP_SPI_R5 | MMC_RSP_R5 | MMC_CMD_ADTC; | ||
145 | |||
146 | data.blksz = blksz; | ||
147 | data.blocks = blocks; | ||
148 | data.flags = write ? MMC_DATA_WRITE : MMC_DATA_READ; | ||
149 | data.sg = &sg; | ||
150 | data.sg_len = 1; | ||
151 | |||
152 | sg_init_one(&sg, buf, blksz * blocks); | ||
153 | |||
154 | mmc_set_data_timeout(&data, card); | ||
155 | |||
156 | mmc_wait_for_req(card->host, &mrq); | ||
157 | |||
158 | if (cmd.error) | ||
159 | return cmd.error; | ||
160 | if (data.error) | ||
161 | return data.error; | ||
162 | |||
163 | if (mmc_host_is_spi(card->host)) { | ||
164 | /* host driver already reported errors */ | ||
165 | } else { | ||
166 | if (cmd.resp[0] & R5_ERROR) | ||
167 | return -EIO; | ||
168 | if (cmd.resp[0] & R5_FUNCTION_NUMBER) | ||
169 | return -EINVAL; | ||
170 | if (cmd.resp[0] & R5_OUT_OF_RANGE) | ||
171 | return -ERANGE; | ||
172 | } | ||
173 | |||
174 | return 0; | ||
175 | } | ||
176 | |||
diff --git a/drivers/mmc/core/sdio_ops.h b/drivers/mmc/core/sdio_ops.h new file mode 100644 index 000000000000..e2e74b0d17d8 --- /dev/null +++ b/drivers/mmc/core/sdio_ops.h | |||
@@ -0,0 +1,22 @@ | |||
1 | /* | ||
2 | * linux/drivers/mmc/sdio_ops.c | ||
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_SDIO_OPS_H | ||
13 | #define _MMC_SDIO_OPS_H | ||
14 | |||
15 | int mmc_send_io_op_cond(struct mmc_host *host, u32 ocr, u32 *rocr); | ||
16 | int mmc_io_rw_direct(struct mmc_card *card, int write, unsigned fn, | ||
17 | unsigned addr, u8 in, u8* out); | ||
18 | int mmc_io_rw_extended(struct mmc_card *card, int write, unsigned fn, | ||
19 | unsigned addr, int incr_addr, u8 *buf, unsigned blocks, unsigned blksz); | ||
20 | |||
21 | #endif | ||
22 | |||