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

Commit 6fc56ccf authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge master.kernel.org:/home/rmk/linux-2.6-mmc

* master.kernel.org:/home/rmk/linux-2.6-mmc:
  [MMC] Move set_ios debugging into mmc.c
  [MMC] Correct mmc_request_done comments
  [MMC] PXA: reduce the number of lines PXAMCI debug uses
  [MMC] PXA and i.MX: don't avoid sending stop command on error
  [MMC] extend data timeout for writes
  [ARM] 3485/1: i.MX: MX1 SD/MMC fix of unintentional double start possibility
parents cbdf811c 920e70c5
Loading
Loading
Loading
Loading
+0 −3
Original line number Diff line number Diff line
@@ -621,9 +621,6 @@ static void at91_mci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
	struct at91mci_host *host = mmc_priv(mmc);
	unsigned long at91_master_clock = clk_get_rate(mci_clk);

	DBG("Clock %uHz, busmode %u, powermode %u, Vdd %u\n",
		ios->clock, ios->bus_mode, ios->power_mode, ios->vdd);

	if (host)
		host->bus_mode = ios->bus_mode;
	else
+0 −4
Original line number Diff line number Diff line
@@ -720,10 +720,6 @@ static void au1xmmc_set_ios(struct mmc_host* mmc, struct mmc_ios* ios)
{
	struct au1xmmc_host *host = mmc_priv(mmc);

	DBG("set_ios (power=%u, clock=%uHz, vdd=%u, mode=%u)\n",
	      host->id, ios->power_mode, ios->clock, ios->vdd,
	      ios->bus_mode);

	if (ios->power_mode == MMC_POWER_OFF)
		au1xmmc_set_power(host, 0);
	else if (ios->power_mode == MMC_POWER_ON) {
+44 −16
Original line number Diff line number Diff line
@@ -102,6 +102,7 @@ struct imxmci_host {
#define IMXMCI_PEND_CPU_DATA_b	5
#define IMXMCI_PEND_CARD_XCHG_b	6
#define IMXMCI_PEND_SET_INIT_b	7
#define IMXMCI_PEND_STARTED_b	8

#define IMXMCI_PEND_IRQ_m	(1 << IMXMCI_PEND_IRQ_b)
#define IMXMCI_PEND_DMA_END_m	(1 << IMXMCI_PEND_DMA_END_b)
@@ -111,6 +112,7 @@ struct imxmci_host {
#define IMXMCI_PEND_CPU_DATA_m	(1 << IMXMCI_PEND_CPU_DATA_b)
#define IMXMCI_PEND_CARD_XCHG_m	(1 << IMXMCI_PEND_CARD_XCHG_b)
#define IMXMCI_PEND_SET_INIT_m	(1 << IMXMCI_PEND_SET_INIT_b)
#define IMXMCI_PEND_STARTED_m	(1 << IMXMCI_PEND_STARTED_b)

static void imxmci_stop_clock(struct imxmci_host *host)
{
@@ -131,23 +133,52 @@ static void imxmci_stop_clock(struct imxmci_host *host)
	dev_dbg(mmc_dev(host->mmc), "imxmci_stop_clock blocked, no luck\n");
}

static void imxmci_start_clock(struct imxmci_host *host)
static int imxmci_start_clock(struct imxmci_host *host)
{
	int i = 0;
	unsigned int trials = 0;
	unsigned int delay_limit = 128;
	unsigned long flags;

	MMC_STR_STP_CLK &= ~STR_STP_CLK_STOP_CLK;
	while(i < 0x1000) {
	        if(!(i & 0x7f))

	clear_bit(IMXMCI_PEND_STARTED_b, &host->pending_events);

	/*
	 * Command start of the clock, this usually succeeds in less
	 * then 6 delay loops, but during card detection (low clockrate)
	 * it takes up to 5000 delay loops and sometimes fails for the first time
	 */
	MMC_STR_STP_CLK |= STR_STP_CLK_START_CLK;

		if(MMC_STATUS & STATUS_CARD_BUS_CLK_RUN) {
	do {
		unsigned int delay = delay_limit;

		while(delay--){
			if(MMC_STATUS & STATUS_CARD_BUS_CLK_RUN)
				/* Check twice before cut */
				if(MMC_STATUS & STATUS_CARD_BUS_CLK_RUN)
				return;
		}
					return 0;

		i++;
			if(test_bit(IMXMCI_PEND_STARTED_b, &host->pending_events))
				return 0;
		}
	dev_dbg(mmc_dev(host->mmc), "imxmci_start_clock blocked, no luck\n");

		local_irq_save(flags);
		/*
		 * Ensure, that request is not doubled under all possible circumstances.
		 * It is possible, that cock running state is missed, because some other
		 * IRQ or schedule delays this function execution and the clocks has
		 * been already stopped by other means (response processing, SDHC HW)
		 */
		if(!test_bit(IMXMCI_PEND_STARTED_b, &host->pending_events))
			MMC_STR_STP_CLK |= STR_STP_CLK_START_CLK;
		local_irq_restore(flags);

	} while(++trials<256);

	dev_err(mmc_dev(host->mmc), "imxmci_start_clock blocked, no luck\n");

	return -1;
}

static void imxmci_softreset(void)
@@ -498,7 +529,7 @@ static int imxmci_data_done(struct imxmci_host *host, unsigned int stat)

	data_error = imxmci_finish_data(host, stat);

	if (host->req->stop && (data_error == MMC_ERR_NONE)) {
	if (host->req->stop) {
		imxmci_stop_clock(host);
		imxmci_start_cmd(host, host->req->stop, 0);
	} else {
@@ -622,6 +653,7 @@ static irqreturn_t imxmci_irq(int irq, void *devid, struct pt_regs *regs)
	atomic_set(&host->stuck_timeout, 0);
	host->status_reg = stat;
	set_bit(IMXMCI_PEND_IRQ_b, &host->pending_events);
	set_bit(IMXMCI_PEND_STARTED_b, &host->pending_events);
	tasklet_schedule(&host->tasklet);

	return IRQ_RETVAL(handled);;
@@ -775,10 +807,6 @@ static void imxmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
	struct imxmci_host *host = mmc_priv(mmc);
	int prescaler;

	dev_dbg(mmc_dev(host->mmc), "clock %u power %u vdd %u width %u\n",
		ios->clock, ios->power_mode, ios->vdd,
		(ios->bus_width==MMC_BUS_WIDTH_4)?4:1);

	if( ios->bus_width==MMC_BUS_WIDTH_4 ) {
		host->actual_bus_width = MMC_BUS_WIDTH_4;
		imx_gpio_mode(PB11_PF_SD_DAT3);
+40 −22
Original line number Diff line number Diff line
@@ -59,21 +59,23 @@ static const unsigned int tacc_mant[] = {


/**
 *	mmc_request_done - finish processing an MMC command
 *	@host: MMC host which completed command
 *	@mrq: MMC request which completed
 *	mmc_request_done - finish processing an MMC request
 *	@host: MMC host which completed request
 *	@mrq: MMC request which request
 *
 *	MMC drivers should call this function when they have completed
 *	their processing of a command.  This should be called before the
 *	data part of the command has completed.
 *	their processing of a request.
 */
void mmc_request_done(struct mmc_host *host, struct mmc_request *mrq)
{
	struct mmc_command *cmd = mrq->cmd;
	int err = mrq->cmd->error;
	pr_debug("MMC: req done (%02x): %d: %08x %08x %08x %08x\n",
		 cmd->opcode, err, cmd->resp[0], cmd->resp[1],
		 cmd->resp[2], cmd->resp[3]);
	int err = cmd->error;

	pr_debug("%s: req done (CMD%u): %d/%d/%d: %08x %08x %08x %08x\n",
		 mmc_hostname(host), cmd->opcode, err,
		 mrq->data ? mrq->data->error : 0,
		 mrq->stop ? mrq->stop->error : 0,
		 cmd->resp[0], cmd->resp[1], cmd->resp[2], cmd->resp[3]);

	if (err && cmd->retries) {
		cmd->retries--;
@@ -97,8 +99,9 @@ EXPORT_SYMBOL(mmc_request_done);
void
mmc_start_request(struct mmc_host *host, struct mmc_request *mrq)
{
	pr_debug("MMC: starting cmd %02x arg %08x flags %08x\n",
		 mrq->cmd->opcode, mrq->cmd->arg, mrq->cmd->flags);
	pr_debug("%s: starting CMD%u arg %08x flags %08x\n",
		 mmc_hostname(host), mrq->cmd->opcode,
		 mrq->cmd->arg, mrq->cmd->flags);

	WARN_ON(host->card_busy == NULL);

@@ -312,6 +315,18 @@ void mmc_release_host(struct mmc_host *host)

EXPORT_SYMBOL(mmc_release_host);

static inline void mmc_set_ios(struct mmc_host *host)
{
	struct mmc_ios *ios = &host->ios;

	pr_debug("%s: clock %uHz busmode %u powermode %u cs %u Vdd %u width %u\n",
		 mmc_hostname(host), ios->clock, ios->bus_mode,
		 ios->power_mode, ios->chip_select, ios->vdd,
		 ios->bus_width);
	
	host->ops->set_ios(host, ios);
}

static int mmc_select_card(struct mmc_host *host, struct mmc_card *card)
{
	int err;
@@ -364,7 +379,7 @@ static int mmc_select_card(struct mmc_host *host, struct mmc_card *card)
		}
	}

	host->ops->set_ios(host, &host->ios);
	mmc_set_ios(host);

	return MMC_ERR_NONE;
}
@@ -415,7 +430,7 @@ static u32 mmc_select_voltage(struct mmc_host *host, u32 ocr)
		ocr = 3 << bit;

		host->ios.vdd = bit;
		host->ops->set_ios(host, &host->ios);
		mmc_set_ios(host);
	} else {
		ocr = 0;
	}
@@ -549,6 +564,7 @@ static void mmc_decode_csd(struct mmc_card *card)
		csd->read_partial = UNSTUFF_BITS(resp, 79, 1);
		csd->write_misalign = UNSTUFF_BITS(resp, 78, 1);
		csd->read_misalign = UNSTUFF_BITS(resp, 77, 1);
		csd->r2w_factor = UNSTUFF_BITS(resp, 26, 3);
		csd->write_blkbits = UNSTUFF_BITS(resp, 22, 4);
		csd->write_partial = UNSTUFF_BITS(resp, 21, 1);
	} else {
@@ -583,6 +599,7 @@ static void mmc_decode_csd(struct mmc_card *card)
		csd->read_partial = UNSTUFF_BITS(resp, 79, 1);
		csd->write_misalign = UNSTUFF_BITS(resp, 78, 1);
		csd->read_misalign = UNSTUFF_BITS(resp, 77, 1);
		csd->r2w_factor = UNSTUFF_BITS(resp, 26, 3);
		csd->write_blkbits = UNSTUFF_BITS(resp, 22, 4);
		csd->write_partial = UNSTUFF_BITS(resp, 21, 1);
	}
@@ -666,7 +683,7 @@ static void mmc_idle_cards(struct mmc_host *host)
	struct mmc_command cmd;

	host->ios.chip_select = MMC_CS_HIGH;
	host->ops->set_ios(host, &host->ios);
	mmc_set_ios(host);

	mmc_delay(1);

@@ -679,7 +696,7 @@ static void mmc_idle_cards(struct mmc_host *host)
	mmc_delay(1);

	host->ios.chip_select = MMC_CS_DONTCARE;
	host->ops->set_ios(host, &host->ios);
	mmc_set_ios(host);

	mmc_delay(1);
}
@@ -704,13 +721,13 @@ static void mmc_power_up(struct mmc_host *host)
	host->ios.chip_select = MMC_CS_DONTCARE;
	host->ios.power_mode = MMC_POWER_UP;
	host->ios.bus_width = MMC_BUS_WIDTH_1;
	host->ops->set_ios(host, &host->ios);
	mmc_set_ios(host);

	mmc_delay(1);

	host->ios.clock = host->f_min;
	host->ios.power_mode = MMC_POWER_ON;
	host->ops->set_ios(host, &host->ios);
	mmc_set_ios(host);

	mmc_delay(2);
}
@@ -723,7 +740,7 @@ static void mmc_power_off(struct mmc_host *host)
	host->ios.chip_select = MMC_CS_DONTCARE;
	host->ios.power_mode = MMC_POWER_OFF;
	host->ios.bus_width = MMC_BUS_WIDTH_1;
	host->ops->set_ios(host, &host->ios);
	mmc_set_ios(host);
}

static int mmc_send_op_cond(struct mmc_host *host, u32 ocr, u32 *rocr)
@@ -971,7 +988,8 @@ static unsigned int mmc_calculate_clock(struct mmc_host *host)
		if (!mmc_card_dead(card) && max_dtr > card->csd.max_dtr)
			max_dtr = card->csd.max_dtr;

	pr_debug("MMC: selected %d.%03dMHz transfer rate\n",
	pr_debug("%s: selected %d.%03dMHz transfer rate\n",
		 mmc_hostname(host),
		 max_dtr / 1000000, (max_dtr / 1000) % 1000);

	return max_dtr;
@@ -1046,7 +1064,7 @@ static void mmc_setup(struct mmc_host *host)
	} else {
		host->ios.bus_mode = MMC_BUSMODE_OPENDRAIN;
		host->ios.clock = host->f_min;
		host->ops->set_ios(host, &host->ios);
		mmc_set_ios(host);

		/*
		 * We should remember the OCR mask from the existing
@@ -1082,7 +1100,7 @@ static void mmc_setup(struct mmc_host *host)
	 * Ok, now switch to push-pull mode.
	 */
	host->ios.bus_mode = MMC_BUSMODE_PUSHPULL;
	host->ops->set_ios(host, &host->ios);
	mmc_set_ios(host);

	mmc_read_csds(host);

@@ -1128,7 +1146,7 @@ static void mmc_rescan(void *data)
		 * attached cards and the host support.
		 */
		host->ios.clock = mmc_calculate_clock(host);
		host->ops->set_ios(host, &host->ios);
		mmc_set_ios(host);
	}

	mmc_release_host(host);
+6 −0
Original line number Diff line number Diff line
@@ -187,6 +187,12 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req)
			brq.cmd.opcode = MMC_WRITE_BLOCK;
			brq.data.flags |= MMC_DATA_WRITE;
			brq.data.blocks = 1;

			/*
			 * Scale up the timeout by the r2w factor
			 */
			brq.data.timeout_ns <<= card->csd.r2w_factor;
			brq.data.timeout_clks <<= card->csd.r2w_factor;
		}

		if (brq.data.blocks > 1) {
Loading