Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d2e2d7ca authored by Linus Torvalds's avatar Linus Torvalds
Browse files
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/drzeus/mmc:
  mmc_spi: support for non-byte-aligned cards
  omap_hsmmc: Do not expect cmd/data to be non-null when CC/TC occurs
  mmc: Fix compile for omap_hsmmc.c
  mmc_spi: convert timeout handling to jiffies and avoid busy waiting
  mmc_spi: do not check CID and CSD blocks with CRC16
  omap_hsmmc: Flush posted write to IRQ
  New mail address for Pierre Ossman
  imxmmc: move RSSR BLR
  imxmmc: init-exit rework
  mmc: Accept EXT_CSD rev 1.3 since it is backwards compatible with 1.2
parents 7831d56b ab5a643c
Loading
Loading
Loading
Loading
+3 −3
Original line number Original line Diff line number Diff line
@@ -3057,7 +3057,7 @@ S: Supported


MULTIMEDIA CARD (MMC), SECURE DIGITAL (SD) AND SDIO SUBSYSTEM
MULTIMEDIA CARD (MMC), SECURE DIGITAL (SD) AND SDIO SUBSYSTEM
P:	Pierre Ossman
P:	Pierre Ossman
M:	drzeus-mmc@drzeus.cx
M:	pierre@ossman.eu
L:	linux-kernel@vger.kernel.org
L:	linux-kernel@vger.kernel.org
S:	Maintained
S:	Maintained


@@ -3939,7 +3939,7 @@ S: Maintained


SECURE DIGITAL HOST CONTROLLER INTERFACE (SDHCI) DRIVER
SECURE DIGITAL HOST CONTROLLER INTERFACE (SDHCI) DRIVER
P:	Pierre Ossman
P:	Pierre Ossman
M:	drzeus-sdhci@drzeus.cx
M:	pierre@ossman.eu
L:	sdhci-devel@lists.ossman.eu
L:	sdhci-devel@lists.ossman.eu
S:	Maintained
S:	Maintained


@@ -4926,7 +4926,7 @@ S: Maintained


W83L51xD SD/MMC CARD INTERFACE DRIVER
W83L51xD SD/MMC CARD INTERFACE DRIVER
P:	Pierre Ossman
P:	Pierre Ossman
M:	drzeus-wbsd@drzeus.cx
M:	pierre@ossman.eu
L:	linux-kernel@vger.kernel.org
L:	linux-kernel@vger.kernel.org
S:	Maintained
S:	Maintained


+1 −1
Original line number Original line Diff line number Diff line
@@ -208,7 +208,7 @@ static int mmc_read_ext_csd(struct mmc_card *card)
	}
	}


	ext_csd_struct = ext_csd[EXT_CSD_REV];
	ext_csd_struct = ext_csd[EXT_CSD_REV];
	if (ext_csd_struct > 2) {
	if (ext_csd_struct > 3) {
		printk(KERN_ERR "%s: unrecognised EXT_CSD structure "
		printk(KERN_ERR "%s: unrecognised EXT_CSD structure "
			"version %d\n", mmc_hostname(card->host),
			"version %d\n", mmc_hostname(card->host),
			ext_csd_struct);
			ext_csd_struct);
+12 −9
Original line number Original line Diff line number Diff line
@@ -362,15 +362,6 @@ static int mmc_sd_init_card(struct mmc_host *host, u32 ocr,
	if (err)
	if (err)
		goto err;
		goto err;


	/*
	 * For SPI, enable CRC as appropriate.
	 */
	if (mmc_host_is_spi(host)) {
		err = mmc_spi_set_crc(host, use_spi_crc);
		if (err)
			goto err;
	}

	/*
	/*
	 * Fetch CID from card.
	 * Fetch CID from card.
	 */
	 */
@@ -457,6 +448,18 @@ static int mmc_sd_init_card(struct mmc_host *host, u32 ocr,
			goto free_card;
			goto free_card;
	}
	}


	/*
	 * For SPI, enable CRC as appropriate.
	 * This CRC enable is located AFTER the reading of the
	 * card registers because some SDHC cards are not able
	 * to provide valid CRCs for non-512-byte blocks.
	 */
	if (mmc_host_is_spi(host)) {
		err = mmc_spi_set_crc(host, use_spi_crc);
		if (err)
			goto free_card;
	}

	/*
	/*
	 * Attempt to change to high-speed (if supported)
	 * Attempt to change to high-speed (if supported)
	 */
	 */
+7 −12
Original line number Original line Diff line number Diff line
@@ -307,13 +307,6 @@ static void imxmci_setup_data(struct imxmci_host *host, struct mmc_data *data)


	wmb();
	wmb();


	if (host->actual_bus_width == MMC_BUS_WIDTH_4)
		BLR(host->dma) = 0;	/* burst 64 byte read / 64 bytes write */
	else
		BLR(host->dma) = 16;	/* burst 16 byte read / 16 bytes write */

	RSSR(host->dma) = DMA_REQ_SDHC;

	set_bit(IMXMCI_PEND_DMA_DATA_b, &host->pending_events);
	set_bit(IMXMCI_PEND_DMA_DATA_b, &host->pending_events);
	clear_bit(IMXMCI_PEND_CPU_DATA_b, &host->pending_events);
	clear_bit(IMXMCI_PEND_CPU_DATA_b, &host->pending_events);


@@ -818,9 +811,11 @@ static void imxmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
	if (ios->bus_width == MMC_BUS_WIDTH_4) {
	if (ios->bus_width == MMC_BUS_WIDTH_4) {
		host->actual_bus_width = MMC_BUS_WIDTH_4;
		host->actual_bus_width = MMC_BUS_WIDTH_4;
		imx_gpio_mode(PB11_PF_SD_DAT3);
		imx_gpio_mode(PB11_PF_SD_DAT3);
		BLR(host->dma) = 0;	/* burst 64 byte read/write */
	} else {
	} else {
		host->actual_bus_width = MMC_BUS_WIDTH_1;
		host->actual_bus_width = MMC_BUS_WIDTH_1;
		imx_gpio_mode(GPIO_PORTB | GPIO_IN | GPIO_PUEN | 11);
		imx_gpio_mode(GPIO_PORTB | GPIO_IN | GPIO_PUEN | 11);
		BLR(host->dma) = 16;	/* burst 16 byte read/write */
	}
	}


	if (host->power_mode != ios->power_mode) {
	if (host->power_mode != ios->power_mode) {
@@ -938,7 +933,7 @@ static void imxmci_check_status(unsigned long data)
	mod_timer(&host->timer, jiffies + (HZ>>1));
	mod_timer(&host->timer, jiffies + (HZ>>1));
}
}


static int imxmci_probe(struct platform_device *pdev)
static int __init imxmci_probe(struct platform_device *pdev)
{
{
	struct mmc_host *mmc;
	struct mmc_host *mmc;
	struct imxmci_host *host = NULL;
	struct imxmci_host *host = NULL;
@@ -1034,6 +1029,7 @@ static int imxmci_probe(struct platform_device *pdev)
	}
	}
	host->dma_allocated = 1;
	host->dma_allocated = 1;
	imx_dma_setup_handlers(host->dma, imxmci_dma_irq, NULL, host);
	imx_dma_setup_handlers(host->dma, imxmci_dma_irq, NULL, host);
	RSSR(host->dma) = DMA_REQ_SDHC;


	tasklet_init(&host->tasklet, imxmci_tasklet_fnc, (unsigned long)host);
	tasklet_init(&host->tasklet, imxmci_tasklet_fnc, (unsigned long)host);
	host->status_reg=0;
	host->status_reg=0;
@@ -1079,7 +1075,7 @@ static int imxmci_probe(struct platform_device *pdev)
	return ret;
	return ret;
}
}


static int imxmci_remove(struct platform_device *pdev)
static int __exit imxmci_remove(struct platform_device *pdev)
{
{
	struct mmc_host *mmc = platform_get_drvdata(pdev);
	struct mmc_host *mmc = platform_get_drvdata(pdev);


@@ -1145,8 +1141,7 @@ static int imxmci_resume(struct platform_device *dev)
#endif /* CONFIG_PM */
#endif /* CONFIG_PM */


static struct platform_driver imxmci_driver = {
static struct platform_driver imxmci_driver = {
	.probe		= imxmci_probe,
	.remove		= __exit_p(imxmci_remove),
	.remove		= imxmci_remove,
	.suspend	= imxmci_suspend,
	.suspend	= imxmci_suspend,
	.resume		= imxmci_resume,
	.resume		= imxmci_resume,
	.driver		= {
	.driver		= {
@@ -1157,7 +1152,7 @@ static struct platform_driver imxmci_driver = {


static int __init imxmci_init(void)
static int __init imxmci_init(void)
{
{
	return platform_driver_register(&imxmci_driver);
	return platform_driver_probe(&imxmci_driver, imxmci_probe);
}
}


static void __exit imxmci_exit(void)
static void __exit imxmci_exit(void)
+133 −55
Original line number Original line Diff line number Diff line
@@ -24,7 +24,7 @@
 * along with this program; if not, write to the Free Software
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */
 */
#include <linux/hrtimer.h>
#include <linux/sched.h>
#include <linux/delay.h>
#include <linux/delay.h>
#include <linux/bio.h>
#include <linux/bio.h>
#include <linux/dma-mapping.h>
#include <linux/dma-mapping.h>
@@ -95,7 +95,7 @@
 * reads which takes nowhere near that long.  Older cards may be able to use
 * reads which takes nowhere near that long.  Older cards may be able to use
 * shorter timeouts ... but why bother?
 * shorter timeouts ... but why bother?
 */
 */
#define r1b_timeout		ktime_set(3, 0)
#define r1b_timeout		(HZ * 3)




/****************************************************************************/
/****************************************************************************/
@@ -183,12 +183,11 @@ mmc_spi_readbytes(struct mmc_spi_host *host, unsigned len)
	return status;
	return status;
}
}


static int
static int mmc_spi_skip(struct mmc_spi_host *host, unsigned long timeout,
mmc_spi_skip(struct mmc_spi_host *host, ktime_t timeout, unsigned n, u8 byte)
			unsigned n, u8 byte)
{
{
	u8		*cp = host->data->status;
	u8		*cp = host->data->status;

	unsigned long start = jiffies;
	timeout = ktime_add(timeout, ktime_get());


	while (1) {
	while (1) {
		int		status;
		int		status;
@@ -203,22 +202,26 @@ mmc_spi_skip(struct mmc_spi_host *host, ktime_t timeout, unsigned n, u8 byte)
				return cp[i];
				return cp[i];
		}
		}


		/* REVISIT investigate msleep() to avoid busy-wait I/O
		if (time_is_before_jiffies(start + timeout))
		 * in at least some cases.
		 */
		if (ktime_to_ns(ktime_sub(ktime_get(), timeout)) > 0)
			break;
			break;

		/* If we need long timeouts, we may release the CPU.
		 * We use jiffies here because we want to have a relation
		 * between elapsed time and the blocking of the scheduler.
		 */
		if (time_is_before_jiffies(start+1))
			schedule();
	}
	}
	return -ETIMEDOUT;
	return -ETIMEDOUT;
}
}


static inline int
static inline int
mmc_spi_wait_unbusy(struct mmc_spi_host *host, ktime_t timeout)
mmc_spi_wait_unbusy(struct mmc_spi_host *host, unsigned long timeout)
{
{
	return mmc_spi_skip(host, timeout, sizeof(host->data->status), 0);
	return mmc_spi_skip(host, timeout, sizeof(host->data->status), 0);
}
}


static int mmc_spi_readtoken(struct mmc_spi_host *host, ktime_t timeout)
static int mmc_spi_readtoken(struct mmc_spi_host *host, unsigned long timeout)
{
{
	return mmc_spi_skip(host, timeout, 1, 0xff);
	return mmc_spi_skip(host, timeout, 1, 0xff);
}
}
@@ -251,6 +254,10 @@ static int mmc_spi_response_get(struct mmc_spi_host *host,
	u8	*cp = host->data->status;
	u8	*cp = host->data->status;
	u8	*end = cp + host->t.len;
	u8	*end = cp + host->t.len;
	int	value = 0;
	int	value = 0;
	int	bitshift;
	u8 	leftover = 0;
	unsigned short rotator;
	int 	i;
	char	tag[32];
	char	tag[32];


	snprintf(tag, sizeof(tag), "  ... CMD%d response SPI_%s",
	snprintf(tag, sizeof(tag), "  ... CMD%d response SPI_%s",
@@ -268,9 +275,8 @@ static int mmc_spi_response_get(struct mmc_spi_host *host,


	/* Data block reads (R1 response types) may need more data... */
	/* Data block reads (R1 response types) may need more data... */
	if (cp == end) {
	if (cp == end) {
		unsigned	i;

		cp = host->data->status;
		cp = host->data->status;
		end = cp+1;


		/* Card sends N(CR) (== 1..8) bytes of all-ones then one
		/* Card sends N(CR) (== 1..8) bytes of all-ones then one
		 * status byte ... and we already scanned 2 bytes.
		 * status byte ... and we already scanned 2 bytes.
@@ -295,14 +301,28 @@ static int mmc_spi_response_get(struct mmc_spi_host *host,
	}
	}


checkstatus:
checkstatus:
	bitshift = 0;
	if (*cp & 0x80)	{
	if (*cp & 0x80)	{
		dev_dbg(&host->spi->dev, "%s: INVALID RESPONSE, %02x\n",
		/* Houston, we have an ugly card with a bit-shifted response */
					tag, *cp);
		rotator = *cp++ << 8;
		value = -EBADR;
		/* read the next byte */
		if (cp == end) {
			value = mmc_spi_readbytes(host, 1);
			if (value < 0)
				goto done;
				goto done;
			cp = host->data->status;
			end = cp+1;
		}
		}

		rotator |= *cp++;
		while (rotator & 0x8000) {
			bitshift++;
			rotator <<= 1;
		}
		cmd->resp[0] = rotator >> 8;
		leftover = rotator;
	} else {
		cmd->resp[0] = *cp++;
		cmd->resp[0] = *cp++;
	}
	cmd->error = 0;
	cmd->error = 0;


	/* Status byte: the entire seven-bit R1 response.  */
	/* Status byte: the entire seven-bit R1 response.  */
@@ -336,12 +356,45 @@ static int mmc_spi_response_get(struct mmc_spi_host *host,
	 * SPI R5 == R1 + data byte; IO_RW_DIRECT
	 * SPI R5 == R1 + data byte; IO_RW_DIRECT
	 */
	 */
	case MMC_RSP_SPI_R2:
	case MMC_RSP_SPI_R2:
		/* read the next byte */
		if (cp == end) {
			value = mmc_spi_readbytes(host, 1);
			if (value < 0)
				goto done;
			cp = host->data->status;
			end = cp+1;
		}
		if (bitshift) {
			rotator = leftover << 8;
			rotator |= *cp << bitshift;
			cmd->resp[0] |= (rotator & 0xFF00);
		} else {
			cmd->resp[0] |= *cp << 8;
			cmd->resp[0] |= *cp << 8;
		}
		break;
		break;


	/* SPI R3, R4, or R7 == R1 + 4 bytes */
	/* SPI R3, R4, or R7 == R1 + 4 bytes */
	case MMC_RSP_SPI_R3:
	case MMC_RSP_SPI_R3:
		cmd->resp[1] = get_unaligned_be32(cp);
		rotator = leftover << 8;
		cmd->resp[1] = 0;
		for (i = 0; i < 4; i++) {
			cmd->resp[1] <<= 8;
			/* read the next byte */
			if (cp == end) {
				value = mmc_spi_readbytes(host, 1);
				if (value < 0)
					goto done;
				cp = host->data->status;
				end = cp+1;
			}
			if (bitshift) {
				rotator |= *cp++ << bitshift;
				cmd->resp[1] |= (rotator >> 8);
				rotator <<= 8;
			} else {
				cmd->resp[1] |= *cp++;
			}
		}
		break;
		break;


	/* SPI R1 == just one status byte */
	/* SPI R1 == just one status byte */
@@ -607,7 +660,7 @@ mmc_spi_setup_data_message(
 */
 */
static int
static int
mmc_spi_writeblock(struct mmc_spi_host *host, struct spi_transfer *t,
mmc_spi_writeblock(struct mmc_spi_host *host, struct spi_transfer *t,
	ktime_t timeout)
	unsigned long timeout)
{
{
	struct spi_device	*spi = host->spi;
	struct spi_device	*spi = host->spi;
	int			status, i;
	int			status, i;
@@ -717,11 +770,13 @@ mmc_spi_writeblock(struct mmc_spi_host *host, struct spi_transfer *t,
 */
 */
static int
static int
mmc_spi_readblock(struct mmc_spi_host *host, struct spi_transfer *t,
mmc_spi_readblock(struct mmc_spi_host *host, struct spi_transfer *t,
	ktime_t timeout)
	unsigned long timeout)
{
{
	struct spi_device	*spi = host->spi;
	struct spi_device	*spi = host->spi;
	int			status;
	int			status;
	struct scratch		*scratch = host->data;
	struct scratch		*scratch = host->data;
	unsigned int 		bitshift;
	u8			leftover;


	/* At least one SD card sends an all-zeroes byte when N(CX)
	/* At least one SD card sends an all-zeroes byte when N(CX)
	 * applies, before the all-ones bytes ... just cope with that.
	 * applies, before the all-ones bytes ... just cope with that.
@@ -733,7 +788,21 @@ mmc_spi_readblock(struct mmc_spi_host *host, struct spi_transfer *t,
	if (status == 0xff || status == 0)
	if (status == 0xff || status == 0)
		status = mmc_spi_readtoken(host, timeout);
		status = mmc_spi_readtoken(host, timeout);


	if (status == SPI_TOKEN_SINGLE) {
	if (status < 0) {
		dev_dbg(&spi->dev, "read error %02x (%d)\n", status, status);
		return status;
	}

	/* The token may be bit-shifted...
	 * the first 0-bit precedes the data stream.
	 */
	bitshift = 7;
	while (status & 0x80) {
		status <<= 1;
		bitshift--;
	}
	leftover = status << 1;

	if (host->dma_dev) {
	if (host->dma_dev) {
		dma_sync_single_for_device(host->dma_dev,
		dma_sync_single_for_device(host->dma_dev,
				host->data_dma, sizeof(*scratch),
				host->data_dma, sizeof(*scratch),
@@ -754,17 +823,25 @@ mmc_spi_readblock(struct mmc_spi_host *host, struct spi_transfer *t,
				DMA_FROM_DEVICE);
				DMA_FROM_DEVICE);
	}
	}


	} else {
	if (bitshift) {
		dev_dbg(&spi->dev, "read error %02x (%d)\n", status, status);
		/* Walk through the data and the crc and do

		 * all the magic to get byte-aligned data.
		/* we've read extra garbage, timed out, etc */
		if (status < 0)
			return status;

		/* low four bits are an R2 subset, fifth seems to be
		 * vendor specific ... map them all to generic error..
		 */
		 */
		return -EIO;
		u8 *cp = t->rx_buf;
		unsigned int len;
		unsigned int bitright = 8 - bitshift;
		u8 temp;
		for (len = t->len; len; len--) {
			temp = *cp;
			*cp++ = leftover | (temp >> bitshift);
			leftover = temp << bitright;
		}
		cp = (u8 *) &scratch->crc_val;
		temp = *cp;
		*cp++ = leftover | (temp >> bitshift);
		leftover = temp << bitright;
		temp = *cp;
		*cp = leftover | (temp >> bitshift);
	}
	}


	if (host->mmc->use_spi_crc) {
	if (host->mmc->use_spi_crc) {
@@ -803,7 +880,7 @@ mmc_spi_data_do(struct mmc_spi_host *host, struct mmc_command *cmd,
	unsigned		n_sg;
	unsigned		n_sg;
	int			multiple = (data->blocks > 1);
	int			multiple = (data->blocks > 1);
	u32			clock_rate;
	u32			clock_rate;
	ktime_t			timeout;
	unsigned long		timeout;


	if (data->flags & MMC_DATA_READ)
	if (data->flags & MMC_DATA_READ)
		direction = DMA_FROM_DEVICE;
		direction = DMA_FROM_DEVICE;
@@ -817,8 +894,9 @@ mmc_spi_data_do(struct mmc_spi_host *host, struct mmc_command *cmd,
	else
	else
		clock_rate = spi->max_speed_hz;
		clock_rate = spi->max_speed_hz;


	timeout = ktime_add_ns(ktime_set(0, 0), data->timeout_ns +
	timeout = data->timeout_ns +
			data->timeout_clks * 1000000 / clock_rate);
		  data->timeout_clks * 1000000 / clock_rate;
	timeout = usecs_to_jiffies((unsigned int)(timeout / 1000)) + 1;


	/* Handle scatterlist segments one at a time, with synch for
	/* Handle scatterlist segments one at a time, with synch for
	 * each 512-byte block
	 * each 512-byte block
Loading