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

Commit 5df460b1 authored by Guennadi Liakhovetski's avatar Guennadi Liakhovetski Committed by Chris Ball
Browse files

mmc: sh_mmcif: fix missing and consolidate IO completion timeouts



Read block and write block operations are currently missing completion
timeouts. Add missing timeouts and consolidate them at one location.

Signed-off-by: default avatarGuennadi Liakhovetski <g.liakhovetski@gmx.de>
Signed-off-by: default avatarChris Ball <cjb@laptop.org>
parent a812ba0f
Loading
Loading
Loading
Loading
+22 −23
Original line number Original line Diff line number Diff line
@@ -564,7 +564,6 @@ static void sh_mmcif_single_read(struct sh_mmcif_host *host,
			   BLOCK_SIZE_MASK) + 3;
			   BLOCK_SIZE_MASK) + 3;


	host->wait_for = MMCIF_WAIT_FOR_READ;
	host->wait_for = MMCIF_WAIT_FOR_READ;
	schedule_delayed_work(&host->timeout_work, host->timeout);


	/* buf read enable */
	/* buf read enable */
	sh_mmcif_bitset(host, MMCIF_CE_INT_MASK, MASK_MBUFREN);
	sh_mmcif_bitset(host, MMCIF_CE_INT_MASK, MASK_MBUFREN);
@@ -606,7 +605,7 @@ static void sh_mmcif_multi_read(struct sh_mmcif_host *host,
	host->sg_idx = 0;
	host->sg_idx = 0;
	host->sg_blkidx = 0;
	host->sg_blkidx = 0;
	host->pio_ptr = sg_virt(data->sg);
	host->pio_ptr = sg_virt(data->sg);
	schedule_delayed_work(&host->timeout_work, host->timeout);

	sh_mmcif_bitset(host, MMCIF_CE_INT_MASK, MASK_MBUFREN);
	sh_mmcif_bitset(host, MMCIF_CE_INT_MASK, MASK_MBUFREN);
}
}


@@ -629,7 +628,6 @@ static bool sh_mmcif_mread_block(struct sh_mmcif_host *host)
	if (!sh_mmcif_next_block(host, p))
	if (!sh_mmcif_next_block(host, p))
		return false;
		return false;


	schedule_delayed_work(&host->timeout_work, host->timeout);
	sh_mmcif_bitset(host, MMCIF_CE_INT_MASK, MASK_MBUFREN);
	sh_mmcif_bitset(host, MMCIF_CE_INT_MASK, MASK_MBUFREN);


	return true;
	return true;
@@ -642,7 +640,6 @@ static void sh_mmcif_single_write(struct sh_mmcif_host *host,
			   BLOCK_SIZE_MASK) + 3;
			   BLOCK_SIZE_MASK) + 3;


	host->wait_for = MMCIF_WAIT_FOR_WRITE;
	host->wait_for = MMCIF_WAIT_FOR_WRITE;
	schedule_delayed_work(&host->timeout_work, host->timeout);


	/* buf write enable */
	/* buf write enable */
	sh_mmcif_bitset(host, MMCIF_CE_INT_MASK, MASK_MBUFWEN);
	sh_mmcif_bitset(host, MMCIF_CE_INT_MASK, MASK_MBUFWEN);
@@ -684,7 +681,7 @@ static void sh_mmcif_multi_write(struct sh_mmcif_host *host,
	host->sg_idx = 0;
	host->sg_idx = 0;
	host->sg_blkidx = 0;
	host->sg_blkidx = 0;
	host->pio_ptr = sg_virt(data->sg);
	host->pio_ptr = sg_virt(data->sg);
	schedule_delayed_work(&host->timeout_work, host->timeout);

	sh_mmcif_bitset(host, MMCIF_CE_INT_MASK, MASK_MBUFWEN);
	sh_mmcif_bitset(host, MMCIF_CE_INT_MASK, MASK_MBUFWEN);
}
}


@@ -707,7 +704,6 @@ static bool sh_mmcif_mwrite_block(struct sh_mmcif_host *host)
	if (!sh_mmcif_next_block(host, p))
	if (!sh_mmcif_next_block(host, p))
		return false;
		return false;


	schedule_delayed_work(&host->timeout_work, host->timeout);
	sh_mmcif_bitset(host, MMCIF_CE_INT_MASK, MASK_MBUFWEN);
	sh_mmcif_bitset(host, MMCIF_CE_INT_MASK, MASK_MBUFWEN);


	return true;
	return true;
@@ -900,7 +896,6 @@ static void sh_mmcif_stop_cmd(struct sh_mmcif_host *host,
	}
	}


	host->wait_for = MMCIF_WAIT_FOR_STOP;
	host->wait_for = MMCIF_WAIT_FOR_STOP;
	schedule_delayed_work(&host->timeout_work, host->timeout);
}
}


static void sh_mmcif_request(struct mmc_host *mmc, struct mmc_request *mrq)
static void sh_mmcif_request(struct mmc_host *mmc, struct mmc_request *mrq)
@@ -1121,6 +1116,7 @@ static irqreturn_t sh_mmcif_irqt(int irq, void *dev_id)
{
{
	struct sh_mmcif_host *host = dev_id;
	struct sh_mmcif_host *host = dev_id;
	struct mmc_request *mrq = host->mrq;
	struct mmc_request *mrq = host->mrq;
	bool wait = false;


	cancel_delayed_work_sync(&host->timeout_work);
	cancel_delayed_work_sync(&host->timeout_work);


@@ -1133,29 +1129,24 @@ static irqreturn_t sh_mmcif_irqt(int irq, void *dev_id)
		/* We're too late, the timeout has already kicked in */
		/* We're too late, the timeout has already kicked in */
		return IRQ_HANDLED;
		return IRQ_HANDLED;
	case MMCIF_WAIT_FOR_CMD:
	case MMCIF_WAIT_FOR_CMD:
		if (sh_mmcif_end_cmd(host))
		/* Wait for data? */
			/* Wait for data */
		wait = sh_mmcif_end_cmd(host);
			return IRQ_HANDLED;
		break;
		break;
	case MMCIF_WAIT_FOR_MREAD:
	case MMCIF_WAIT_FOR_MREAD:
		if (sh_mmcif_mread_block(host))
		/* Wait for more data? */
			/* Wait for more data */
		wait = sh_mmcif_mread_block(host);
			return IRQ_HANDLED;
		break;
		break;
	case MMCIF_WAIT_FOR_READ:
	case MMCIF_WAIT_FOR_READ:
		if (sh_mmcif_read_block(host))
		/* Wait for data end? */
			/* Wait for data end */
		wait = sh_mmcif_read_block(host);
			return IRQ_HANDLED;
		break;
		break;
	case MMCIF_WAIT_FOR_MWRITE:
	case MMCIF_WAIT_FOR_MWRITE:
		if (sh_mmcif_mwrite_block(host))
		/* Wait data to write? */
			/* Wait data to write */
		wait = sh_mmcif_mwrite_block(host);
			return IRQ_HANDLED;
		break;
		break;
	case MMCIF_WAIT_FOR_WRITE:
	case MMCIF_WAIT_FOR_WRITE:
		if (sh_mmcif_write_block(host))
		/* Wait for data end? */
			/* Wait for data end */
		wait = sh_mmcif_write_block(host);
			return IRQ_HANDLED;
		break;
		break;
	case MMCIF_WAIT_FOR_STOP:
	case MMCIF_WAIT_FOR_STOP:
		if (host->sd_error) {
		if (host->sd_error) {
@@ -1174,6 +1165,12 @@ static irqreturn_t sh_mmcif_irqt(int irq, void *dev_id)
		BUG();
		BUG();
	}
	}


	if (wait) {
		schedule_delayed_work(&host->timeout_work, host->timeout);
		/* Wait for more data */
		return IRQ_HANDLED;
	}

	if (host->wait_for != MMCIF_WAIT_FOR_STOP) {
	if (host->wait_for != MMCIF_WAIT_FOR_STOP) {
		struct mmc_data *data = mrq->data;
		struct mmc_data *data = mrq->data;
		if (!mrq->cmd->error && data && !data->error)
		if (!mrq->cmd->error && data && !data->error)
@@ -1182,10 +1179,12 @@ static irqreturn_t sh_mmcif_irqt(int irq, void *dev_id)


		if (mrq->stop && !mrq->cmd->error && (!data || !data->error)) {
		if (mrq->stop && !mrq->cmd->error && (!data || !data->error)) {
			sh_mmcif_stop_cmd(host, mrq);
			sh_mmcif_stop_cmd(host, mrq);
			if (!mrq->stop->error)
			if (!mrq->stop->error) {
				schedule_delayed_work(&host->timeout_work, host->timeout);
				return IRQ_HANDLED;
				return IRQ_HANDLED;
			}
			}
		}
		}
	}


	host->wait_for = MMCIF_WAIT_FOR_REQUEST;
	host->wait_for = MMCIF_WAIT_FOR_REQUEST;
	host->state = STATE_IDLE;
	host->state = STATE_IDLE;