Skip to content

Commit

Permalink
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel…
Browse files Browse the repository at this point in the history
…/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
  • Loading branch information
Linus Torvalds committed Oct 27, 2007
2 parents a2508c0 + 460cd05 commit 3d1343b
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 25 deletions.
22 changes: 20 additions & 2 deletions drivers/mmc/core/mmc_ops.c
Original file line number Diff line number Diff line change
Expand Up @@ -267,23 +267,41 @@ mmc_send_cxd_data(struct mmc_card *card, struct mmc_host *host,

int mmc_send_csd(struct mmc_card *card, u32 *csd)
{
int ret, i;

if (!mmc_host_is_spi(card->host))
return mmc_send_cxd_native(card->host, card->rca << 16,
csd, MMC_SEND_CSD);

return mmc_send_cxd_data(card, card->host, MMC_SEND_CSD, csd, 16);
ret = mmc_send_cxd_data(card, card->host, MMC_SEND_CSD, csd, 16);
if (ret)
return ret;

for (i = 0;i < 4;i++)
csd[i] = be32_to_cpu(csd[i]);

return 0;
}

int mmc_send_cid(struct mmc_host *host, u32 *cid)
{
int ret, i;

if (!mmc_host_is_spi(host)) {
if (!host->card)
return -EINVAL;
return mmc_send_cxd_native(host, host->card->rca << 16,
cid, MMC_SEND_CID);
}

return mmc_send_cxd_data(NULL, host, MMC_SEND_CID, cid, 16);
ret = mmc_send_cxd_data(NULL, host, MMC_SEND_CID, cid, 16);
if (ret)
return ret;

for (i = 0;i < 4;i++)
cid[i] = be32_to_cpu(cid[i]);

return 0;
}

int mmc_send_ext_csd(struct mmc_card *card, u8 *ext_csd)
Expand Down
4 changes: 2 additions & 2 deletions drivers/mmc/core/sd_ops.c
Original file line number Diff line number Diff line change
Expand Up @@ -294,8 +294,8 @@ int mmc_app_send_scr(struct mmc_card *card, u32 *scr)
if (data.error)
return data.error;

scr[0] = ntohl(scr[0]);
scr[1] = ntohl(scr[1]);
scr[0] = be32_to_cpu(scr[0]);
scr[1] = be32_to_cpu(scr[1]);

return 0;
}
Expand Down
4 changes: 2 additions & 2 deletions drivers/mmc/host/au1xmmc.c
Original file line number Diff line number Diff line change
Expand Up @@ -212,12 +212,12 @@ static int au1xmmc_send_command(struct au1xmmc_host *host, int wait,
}

if (data) {
if (flags & MMC_DATA_READ) {
if (data->flags & MMC_DATA_READ) {
if (data->blocks > 1)
mmccmd |= SD_CMD_CT_4;
else
mmccmd |= SD_CMD_CT_2;
} else if (flags & MMC_DATA_WRITE) {
} else if (data->flags & MMC_DATA_WRITE) {
if (data->blocks > 1)
mmccmd |= SD_CMD_CT_3;
else
Expand Down
52 changes: 33 additions & 19 deletions drivers/mmc/host/mmc_spi.c
Original file line number Diff line number Diff line change
Expand Up @@ -1165,6 +1165,23 @@ mmc_spi_detect_irq(int irq, void *mmc)
return IRQ_HANDLED;
}

struct count_children {
unsigned n;
struct bus_type *bus;
};

static int maybe_count_child(struct device *dev, void *c)
{
struct count_children *ccp = c;

if (dev->bus == ccp->bus) {
if (ccp->n)
return -EBUSY;
ccp->n++;
}
return 0;
}

static int mmc_spi_probe(struct spi_device *spi)
{
void *ones;
Expand All @@ -1188,33 +1205,30 @@ static int mmc_spi_probe(struct spi_device *spi)
return status;
}

/* We can use the bus safely iff nobody else will interfere with
* us. That is, either we have the experimental exclusive access
* primitives ... or else there's nobody to share it with.
/* We can use the bus safely iff nobody else will interfere with us.
* Most commands consist of one SPI message to issue a command, then
* several more to collect its response, then possibly more for data
* transfer. Clocking access to other devices during that period will
* corrupt the command execution.
*
* Until we have software primitives which guarantee non-interference,
* we'll aim for a hardware-level guarantee.
*
* REVISIT we can't guarantee another device won't be added later...
*/
if (spi->master->num_chipselect > 1) {
struct device *parent = spi->dev.parent;
struct count_children cc;

/* If there are multiple devices on this bus, we
* can't proceed.
*/
spin_lock(&parent->klist_children.k_lock);
if (parent->klist_children.k_list.next
!= parent->klist_children.k_list.prev)
status = -EMLINK;
else
status = 0;
spin_unlock(&parent->klist_children.k_lock);
cc.n = 0;
cc.bus = spi->dev.bus;
status = device_for_each_child(spi->dev.parent, &cc,
maybe_count_child);
if (status < 0) {
dev_err(&spi->dev, "can't share SPI bus\n");
return status;
}

/* REVISIT we can't guarantee another device won't
* be added later. It's uncommon though ... for now,
* work as if this is safe.
*/
dev_warn(&spi->dev, "ASSUMING unshared SPI bus!\n");
dev_warn(&spi->dev, "ASSUMING SPI bus stays unshared!\n");
}

/* We need a supply of ones to transmit. This is the only time
Expand Down

0 comments on commit 3d1343b

Please sign in to comment.