浏览代码

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
Linus Torvalds 17 年之前
父节点
当前提交
3d1343b556
共有 4 个文件被更改,包括 57 次插入25 次删除
  1. 20 2
      drivers/mmc/core/mmc_ops.c
  2. 2 2
      drivers/mmc/core/sd_ops.c
  3. 2 2
      drivers/mmc/host/au1xmmc.c
  4. 33 19
      drivers/mmc/host/mmc_spi.c

+ 20 - 2
drivers/mmc/core/mmc_ops.c

@@ -267,15 +267,26 @@ mmc_send_cxd_data(struct mmc_card *card, struct mmc_host *host,
 
 
 int mmc_send_csd(struct mmc_card *card, u32 *csd)
 int mmc_send_csd(struct mmc_card *card, u32 *csd)
 {
 {
+	int ret, i;
+
 	if (!mmc_host_is_spi(card->host))
 	if (!mmc_host_is_spi(card->host))
 		return mmc_send_cxd_native(card->host, card->rca << 16,
 		return mmc_send_cxd_native(card->host, card->rca << 16,
 				csd, MMC_SEND_CSD);
 				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 mmc_send_cid(struct mmc_host *host, u32 *cid)
 {
 {
+	int ret, i;
+
 	if (!mmc_host_is_spi(host)) {
 	if (!mmc_host_is_spi(host)) {
 		if (!host->card)
 		if (!host->card)
 			return -EINVAL;
 			return -EINVAL;
@@ -283,7 +294,14 @@ int mmc_send_cid(struct mmc_host *host, u32 *cid)
 				cid, MMC_SEND_CID);
 				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)
 int mmc_send_ext_csd(struct mmc_card *card, u8 *ext_csd)

+ 2 - 2
drivers/mmc/core/sd_ops.c

@@ -294,8 +294,8 @@ int mmc_app_send_scr(struct mmc_card *card, u32 *scr)
 	if (data.error)
 	if (data.error)
 		return 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;
 	return 0;
 }
 }

+ 2 - 2
drivers/mmc/host/au1xmmc.c

@@ -212,12 +212,12 @@ static int au1xmmc_send_command(struct au1xmmc_host *host, int wait,
 	}
 	}
 
 
 	if (data) {
 	if (data) {
-		if (flags & MMC_DATA_READ) {
+		if (data->flags & MMC_DATA_READ) {
 			if (data->blocks > 1)
 			if (data->blocks > 1)
 				mmccmd |= SD_CMD_CT_4;
 				mmccmd |= SD_CMD_CT_4;
 			else
 			else
 				mmccmd |= SD_CMD_CT_2;
 				mmccmd |= SD_CMD_CT_2;
-		} else if (flags & MMC_DATA_WRITE) {
+		} else if (data->flags & MMC_DATA_WRITE) {
 			if (data->blocks > 1)
 			if (data->blocks > 1)
 				mmccmd |= SD_CMD_CT_3;
 				mmccmd |= SD_CMD_CT_3;
 			else
 			else

+ 33 - 19
drivers/mmc/host/mmc_spi.c

@@ -1165,6 +1165,23 @@ mmc_spi_detect_irq(int irq, void *mmc)
 	return IRQ_HANDLED;
 	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)
 static int mmc_spi_probe(struct spi_device *spi)
 {
 {
 	void			*ones;
 	void			*ones;
@@ -1188,33 +1205,30 @@ static int mmc_spi_probe(struct spi_device *spi)
 		return status;
 		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) {
 	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) {
 		if (status < 0) {
 			dev_err(&spi->dev, "can't share SPI bus\n");
 			dev_err(&spi->dev, "can't share SPI bus\n");
 			return status;
 			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
 	/* We need a supply of ones to transmit.  This is the only time