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

Commit 2bf22b39 authored by Paul Walmsley's avatar Paul Walmsley Committed by Chris Ball
Browse files

mmc: core: add workaround for controllers with broken multiblock reads

Due to hardware bugs, some MMC host controllers don't support
multiple-block reads[1].  To resolve, add a new MMC capability flag,
MMC_CAP2_NO_MULTI_READ, which can be set by affected host controller
drivers.  When this capability is set, all reads will be issued one
sector at a time.

1. See for example Advisory 2.1.1.128 "MMC: Multiple Block Read
Operation Issue" in _OMAP3530/3525/3515/3503 Silicon Errata_
Revision F (October 2010) (SPRZ278F), available from
http://focus.ti.com/lit/er/sprz278f/sprz278f.pdf



Signed-off-by: default avatarPaul Walmsley <paul@pwsan.com>
Cc: Dave Hylands <dhylands@gmail.com>
Tested-by: default avatarSteve Sakoman <sakoman@gmail.com>
Signed-off-by: default avatarChris Ball <cjb@laptop.org>
parent b6ad726e
Loading
Loading
Loading
Loading
+14 −7
Original line number Diff line number Diff line
@@ -1030,14 +1030,21 @@ static void mmc_blk_rw_rq_prep(struct mmc_queue_req *mqrq,
	if (brq->data.blocks > card->host->max_blk_count)
		brq->data.blocks = card->host->max_blk_count;

	if (brq->data.blocks > 1) {
		/*
	 * After a read error, we redo the request one sector at a time
	 * in order to accurately determine which sectors can be read
	 * successfully.
		 * After a read error, we redo the request one sector
		 * at a time in order to accurately determine which
		 * sectors can be read successfully.
		 */
	if (disable_multi && brq->data.blocks > 1)
		if (disable_multi)
			brq->data.blocks = 1;

		/* Some controllers can't do multiblock reads due to hw bugs */
		if (card->host->caps2 & MMC_CAP2_NO_MULTI_READ &&
		    rq_data_dir(req) == READ)
			brq->data.blocks = 1;
	}

	if (brq->data.blocks > 1 || do_rel_wr) {
		/* SPI multiblock writes terminate using a special
		 * token, not a STOP_TRANSMISSION request.
+1 −0
Original line number Diff line number Diff line
@@ -241,6 +241,7 @@ struct mmc_host {
#define MMC_CAP2_BOOTPART_NOACC	(1 << 0)	/* Boot partition no access */
#define MMC_CAP2_CACHE_CTRL	(1 << 1)	/* Allow cache control */
#define MMC_CAP2_POWEROFF_NOTIFY (1 << 2)	/* Notify poweroff supported */
#define MMC_CAP2_NO_MULTI_READ	(1 << 3)	/* Multiblock reads don't work */

	mmc_pm_flag_t		pm_caps;	/* supported pm features */
	unsigned int        power_notify_type;