diff options
author | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-10-27 13:12:39 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-10-27 13:12:39 -0400 |
commit | 3d1343b55643d60839d711205076e75754e9126e (patch) | |
tree | 72db9f362ee10c050abe07fc1910775f9b280de0 /drivers | |
parent | a2508c0814c6d2c0259fa859a6184343b1e39ea3 (diff) | |
parent | 460cd0589df8aa9b89599905b13c2010db627012 (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:
mmc_spi: Fix mmc-over-spi regression
mmc: use common byte swap macros
mmc: fix cid and csd byte order
at91_mci: Fix bad reference
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/mmc/core/mmc_ops.c | 22 | ||||
-rw-r--r-- | drivers/mmc/core/sd_ops.c | 4 | ||||
-rw-r--r-- | drivers/mmc/host/au1xmmc.c | 4 | ||||
-rw-r--r-- | drivers/mmc/host/mmc_spi.c | 52 |
4 files changed, 57 insertions, 25 deletions
diff --git a/drivers/mmc/core/mmc_ops.c b/drivers/mmc/core/mmc_ops.c index bf4bc6adcfef..7471d49909b2 100644 --- a/drivers/mmc/core/mmc_ops.c +++ b/drivers/mmc/core/mmc_ops.c | |||
@@ -267,15 +267,26 @@ mmc_send_cxd_data(struct mmc_card *card, struct mmc_host *host, | |||
267 | 267 | ||
268 | int mmc_send_csd(struct mmc_card *card, u32 *csd) | 268 | int mmc_send_csd(struct mmc_card *card, u32 *csd) |
269 | { | 269 | { |
270 | int ret, i; | ||
271 | |||
270 | if (!mmc_host_is_spi(card->host)) | 272 | if (!mmc_host_is_spi(card->host)) |
271 | return mmc_send_cxd_native(card->host, card->rca << 16, | 273 | return mmc_send_cxd_native(card->host, card->rca << 16, |
272 | csd, MMC_SEND_CSD); | 274 | csd, MMC_SEND_CSD); |
273 | 275 | ||
274 | return mmc_send_cxd_data(card, card->host, MMC_SEND_CSD, csd, 16); | 276 | ret = mmc_send_cxd_data(card, card->host, MMC_SEND_CSD, csd, 16); |
277 | if (ret) | ||
278 | return ret; | ||
279 | |||
280 | for (i = 0;i < 4;i++) | ||
281 | csd[i] = be32_to_cpu(csd[i]); | ||
282 | |||
283 | return 0; | ||
275 | } | 284 | } |
276 | 285 | ||
277 | int mmc_send_cid(struct mmc_host *host, u32 *cid) | 286 | int mmc_send_cid(struct mmc_host *host, u32 *cid) |
278 | { | 287 | { |
288 | int ret, i; | ||
289 | |||
279 | if (!mmc_host_is_spi(host)) { | 290 | if (!mmc_host_is_spi(host)) { |
280 | if (!host->card) | 291 | if (!host->card) |
281 | return -EINVAL; | 292 | return -EINVAL; |
@@ -283,7 +294,14 @@ int mmc_send_cid(struct mmc_host *host, u32 *cid) | |||
283 | cid, MMC_SEND_CID); | 294 | cid, MMC_SEND_CID); |
284 | } | 295 | } |
285 | 296 | ||
286 | return mmc_send_cxd_data(NULL, host, MMC_SEND_CID, cid, 16); | 297 | ret = mmc_send_cxd_data(NULL, host, MMC_SEND_CID, cid, 16); |
298 | if (ret) | ||
299 | return ret; | ||
300 | |||
301 | for (i = 0;i < 4;i++) | ||
302 | cid[i] = be32_to_cpu(cid[i]); | ||
303 | |||
304 | return 0; | ||
287 | } | 305 | } |
288 | 306 | ||
289 | int mmc_send_ext_csd(struct mmc_card *card, u8 *ext_csd) | 307 | int mmc_send_ext_csd(struct mmc_card *card, u8 *ext_csd) |
diff --git a/drivers/mmc/core/sd_ops.c b/drivers/mmc/core/sd_ops.c index ee4029a24efd..a6dafe62b992 100644 --- a/drivers/mmc/core/sd_ops.c +++ b/drivers/mmc/core/sd_ops.c | |||
@@ -294,8 +294,8 @@ int mmc_app_send_scr(struct mmc_card *card, u32 *scr) | |||
294 | if (data.error) | 294 | if (data.error) |
295 | return data.error; | 295 | return data.error; |
296 | 296 | ||
297 | scr[0] = ntohl(scr[0]); | 297 | scr[0] = be32_to_cpu(scr[0]); |
298 | scr[1] = ntohl(scr[1]); | 298 | scr[1] = be32_to_cpu(scr[1]); |
299 | 299 | ||
300 | return 0; | 300 | return 0; |
301 | } | 301 | } |
diff --git a/drivers/mmc/host/au1xmmc.c b/drivers/mmc/host/au1xmmc.c index c77fadc0dfa3..b2104d4f87af 100644 --- a/drivers/mmc/host/au1xmmc.c +++ b/drivers/mmc/host/au1xmmc.c | |||
@@ -212,12 +212,12 @@ static int au1xmmc_send_command(struct au1xmmc_host *host, int wait, | |||
212 | } | 212 | } |
213 | 213 | ||
214 | if (data) { | 214 | if (data) { |
215 | if (flags & MMC_DATA_READ) { | 215 | if (data->flags & MMC_DATA_READ) { |
216 | if (data->blocks > 1) | 216 | if (data->blocks > 1) |
217 | mmccmd |= SD_CMD_CT_4; | 217 | mmccmd |= SD_CMD_CT_4; |
218 | else | 218 | else |
219 | mmccmd |= SD_CMD_CT_2; | 219 | mmccmd |= SD_CMD_CT_2; |
220 | } else if (flags & MMC_DATA_WRITE) { | 220 | } else if (data->flags & MMC_DATA_WRITE) { |
221 | if (data->blocks > 1) | 221 | if (data->blocks > 1) |
222 | mmccmd |= SD_CMD_CT_3; | 222 | mmccmd |= SD_CMD_CT_3; |
223 | else | 223 | else |
diff --git a/drivers/mmc/host/mmc_spi.c b/drivers/mmc/host/mmc_spi.c index 12c2d807c145..a6469218f194 100644 --- a/drivers/mmc/host/mmc_spi.c +++ b/drivers/mmc/host/mmc_spi.c | |||
@@ -1165,6 +1165,23 @@ mmc_spi_detect_irq(int irq, void *mmc) | |||
1165 | return IRQ_HANDLED; | 1165 | return IRQ_HANDLED; |
1166 | } | 1166 | } |
1167 | 1167 | ||
1168 | struct count_children { | ||
1169 | unsigned n; | ||
1170 | struct bus_type *bus; | ||
1171 | }; | ||
1172 | |||
1173 | static int maybe_count_child(struct device *dev, void *c) | ||
1174 | { | ||
1175 | struct count_children *ccp = c; | ||
1176 | |||
1177 | if (dev->bus == ccp->bus) { | ||
1178 | if (ccp->n) | ||
1179 | return -EBUSY; | ||
1180 | ccp->n++; | ||
1181 | } | ||
1182 | return 0; | ||
1183 | } | ||
1184 | |||
1168 | static int mmc_spi_probe(struct spi_device *spi) | 1185 | static int mmc_spi_probe(struct spi_device *spi) |
1169 | { | 1186 | { |
1170 | void *ones; | 1187 | void *ones; |
@@ -1188,33 +1205,30 @@ static int mmc_spi_probe(struct spi_device *spi) | |||
1188 | return status; | 1205 | return status; |
1189 | } | 1206 | } |
1190 | 1207 | ||
1191 | /* We can use the bus safely iff nobody else will interfere with | 1208 | /* We can use the bus safely iff nobody else will interfere with us. |
1192 | * us. That is, either we have the experimental exclusive access | 1209 | * Most commands consist of one SPI message to issue a command, then |
1193 | * primitives ... or else there's nobody to share it with. | 1210 | * several more to collect its response, then possibly more for data |
1211 | * transfer. Clocking access to other devices during that period will | ||
1212 | * corrupt the command execution. | ||
1213 | * | ||
1214 | * Until we have software primitives which guarantee non-interference, | ||
1215 | * we'll aim for a hardware-level guarantee. | ||
1216 | * | ||
1217 | * REVISIT we can't guarantee another device won't be added later... | ||
1194 | */ | 1218 | */ |
1195 | if (spi->master->num_chipselect > 1) { | 1219 | if (spi->master->num_chipselect > 1) { |
1196 | struct device *parent = spi->dev.parent; | 1220 | struct count_children cc; |
1197 | 1221 | ||
1198 | /* If there are multiple devices on this bus, we | 1222 | cc.n = 0; |
1199 | * can't proceed. | 1223 | cc.bus = spi->dev.bus; |
1200 | */ | 1224 | status = device_for_each_child(spi->dev.parent, &cc, |
1201 | spin_lock(&parent->klist_children.k_lock); | 1225 | maybe_count_child); |
1202 | if (parent->klist_children.k_list.next | ||
1203 | != parent->klist_children.k_list.prev) | ||
1204 | status = -EMLINK; | ||
1205 | else | ||
1206 | status = 0; | ||
1207 | spin_unlock(&parent->klist_children.k_lock); | ||
1208 | if (status < 0) { | 1226 | if (status < 0) { |
1209 | dev_err(&spi->dev, "can't share SPI bus\n"); | 1227 | dev_err(&spi->dev, "can't share SPI bus\n"); |
1210 | return status; | 1228 | return status; |
1211 | } | 1229 | } |
1212 | 1230 | ||
1213 | /* REVISIT we can't guarantee another device won't | 1231 | dev_warn(&spi->dev, "ASSUMING SPI bus stays unshared!\n"); |
1214 | * be added later. It's uncommon though ... for now, | ||
1215 | * work as if this is safe. | ||
1216 | */ | ||
1217 | dev_warn(&spi->dev, "ASSUMING unshared SPI bus!\n"); | ||
1218 | } | 1232 | } |
1219 | 1233 | ||
1220 | /* We need a supply of ones to transmit. This is the only time | 1234 | /* We need a supply of ones to transmit. This is the only time |