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

Unverified Commit 2337ff45 authored by Mark Brown's avatar Mark Brown
Browse files

Merge branch 'spi-5.2' into spi-linus

parents 6fbc7275 2b947137
Loading
Loading
Loading
Loading
+45 −6
Original line number Original line Diff line number Diff line
@@ -273,6 +273,9 @@ static void spi_qup_read(struct spi_qup *controller, u32 *opflags)
		writel_relaxed(QUP_OP_IN_SERVICE_FLAG,
		writel_relaxed(QUP_OP_IN_SERVICE_FLAG,
			       controller->base + QUP_OPERATIONAL);
			       controller->base + QUP_OPERATIONAL);


		if (!remainder)
			goto exit;

		if (is_block_mode) {
		if (is_block_mode) {
			num_words = (remainder > words_per_block) ?
			num_words = (remainder > words_per_block) ?
					words_per_block : remainder;
					words_per_block : remainder;
@@ -302,11 +305,13 @@ static void spi_qup_read(struct spi_qup *controller, u32 *opflags)
	 * to refresh opflags value because MAX_INPUT_DONE_FLAG may now be
	 * to refresh opflags value because MAX_INPUT_DONE_FLAG may now be
	 * present and this is used to determine if transaction is complete
	 * present and this is used to determine if transaction is complete
	 */
	 */
exit:
	if (!remainder) {
		*opflags = readl_relaxed(controller->base + QUP_OPERATIONAL);
		*opflags = readl_relaxed(controller->base + QUP_OPERATIONAL);
		if (is_block_mode && *opflags & QUP_OP_MAX_INPUT_DONE_FLAG)
		if (is_block_mode && *opflags & QUP_OP_MAX_INPUT_DONE_FLAG)
			writel_relaxed(QUP_OP_IN_SERVICE_FLAG,
			writel_relaxed(QUP_OP_IN_SERVICE_FLAG,
				       controller->base + QUP_OPERATIONAL);
				       controller->base + QUP_OPERATIONAL);

	}
}
}


static void spi_qup_write_to_fifo(struct spi_qup *controller, u32 num_words)
static void spi_qup_write_to_fifo(struct spi_qup *controller, u32 num_words)
@@ -354,6 +359,10 @@ static void spi_qup_write(struct spi_qup *controller)
		writel_relaxed(QUP_OP_OUT_SERVICE_FLAG,
		writel_relaxed(QUP_OP_OUT_SERVICE_FLAG,
			       controller->base + QUP_OPERATIONAL);
			       controller->base + QUP_OPERATIONAL);


		/* make sure the interrupt is valid */
		if (!remainder)
			return;

		if (is_block_mode) {
		if (is_block_mode) {
			num_words = (remainder > words_per_block) ?
			num_words = (remainder > words_per_block) ?
				words_per_block : remainder;
				words_per_block : remainder;
@@ -567,10 +576,24 @@ static int spi_qup_do_pio(struct spi_device *spi, struct spi_transfer *xfer,
	return 0;
	return 0;
}
}


static bool spi_qup_data_pending(struct spi_qup *controller)
{
	unsigned int remainder_tx, remainder_rx;

	remainder_tx = DIV_ROUND_UP(spi_qup_len(controller) -
				    controller->tx_bytes, controller->w_size);

	remainder_rx = DIV_ROUND_UP(spi_qup_len(controller) -
				    controller->rx_bytes, controller->w_size);

	return remainder_tx || remainder_rx;
}

static irqreturn_t spi_qup_qup_irq(int irq, void *dev_id)
static irqreturn_t spi_qup_qup_irq(int irq, void *dev_id)
{
{
	struct spi_qup *controller = dev_id;
	struct spi_qup *controller = dev_id;
	u32 opflags, qup_err, spi_err;
	u32 opflags, qup_err, spi_err;
	unsigned long flags;
	int error = 0;
	int error = 0;


	qup_err = readl_relaxed(controller->base + QUP_ERROR_FLAGS);
	qup_err = readl_relaxed(controller->base + QUP_ERROR_FLAGS);
@@ -602,6 +625,11 @@ static irqreturn_t spi_qup_qup_irq(int irq, void *dev_id)
		error = -EIO;
		error = -EIO;
	}
	}


	spin_lock_irqsave(&controller->lock, flags);
	if (!controller->error)
		controller->error = error;
	spin_unlock_irqrestore(&controller->lock, flags);

	if (spi_qup_is_dma_xfer(controller->mode)) {
	if (spi_qup_is_dma_xfer(controller->mode)) {
		writel_relaxed(opflags, controller->base + QUP_OPERATIONAL);
		writel_relaxed(opflags, controller->base + QUP_OPERATIONAL);
	} else {
	} else {
@@ -610,11 +638,22 @@ static irqreturn_t spi_qup_qup_irq(int irq, void *dev_id)


		if (opflags & QUP_OP_OUT_SERVICE_FLAG)
		if (opflags & QUP_OP_OUT_SERVICE_FLAG)
			spi_qup_write(controller);
			spi_qup_write(controller);

		if (!spi_qup_data_pending(controller))
			complete(&controller->done);
	}
	}


	if ((opflags & QUP_OP_MAX_INPUT_DONE_FLAG) || error)
	if (error)
		complete(&controller->done);
		complete(&controller->done);


	if (opflags & QUP_OP_MAX_INPUT_DONE_FLAG) {
		if (!spi_qup_is_dma_xfer(controller->mode)) {
			if (spi_qup_data_pending(controller))
				return IRQ_HANDLED;
		}
		complete(&controller->done);
	}

	return IRQ_HANDLED;
	return IRQ_HANDLED;
}
}


+2 −2
Original line number Original line Diff line number Diff line
@@ -29,7 +29,7 @@
#define CR_SSHIFT		BIT(4)
#define CR_SSHIFT		BIT(4)
#define CR_DFM			BIT(6)
#define CR_DFM			BIT(6)
#define CR_FSEL			BIT(7)
#define CR_FSEL			BIT(7)
#define CR_FTHRES_MASK		GENMASK(12, 8)
#define CR_FTHRES_SHIFT		8
#define CR_TEIE			BIT(16)
#define CR_TEIE			BIT(16)
#define CR_TCIE			BIT(17)
#define CR_TCIE			BIT(17)
#define CR_FTIE			BIT(18)
#define CR_FTIE			BIT(18)
@@ -463,7 +463,7 @@ static int stm32_qspi_setup(struct spi_device *spi)
	flash->presc = presc;
	flash->presc = presc;


	mutex_lock(&qspi->lock);
	mutex_lock(&qspi->lock);
	qspi->cr_reg = FIELD_PREP(CR_FTHRES_MASK, 3) | CR_SSHIFT | CR_EN;
	qspi->cr_reg = 3 << CR_FTHRES_SHIFT | CR_SSHIFT | CR_EN;
	writel_relaxed(qspi->cr_reg, qspi->io_base + QSPI_CR);
	writel_relaxed(qspi->cr_reg, qspi->io_base + QSPI_CR);


	/* set dcr fsize to max address */
	/* set dcr fsize to max address */
+12 −5
Original line number Original line Diff line number Diff line
@@ -328,7 +328,12 @@ static int uniphier_spi_transfer_one(struct spi_master *master,
				     struct spi_transfer *t)
				     struct spi_transfer *t)
{
{
	struct uniphier_spi_priv *priv = spi_master_get_devdata(master);
	struct uniphier_spi_priv *priv = spi_master_get_devdata(master);
	int status;
	struct device *dev = master->dev.parent;
	unsigned long time_left;

	/* Terminate and return success for 0 byte length transfer */
	if (!t->len)
		return 0;


	uniphier_spi_setup_transfer(spi, t);
	uniphier_spi_setup_transfer(spi, t);


@@ -338,13 +343,15 @@ static int uniphier_spi_transfer_one(struct spi_master *master,


	uniphier_spi_irq_enable(spi, SSI_IE_RCIE | SSI_IE_RORIE);
	uniphier_spi_irq_enable(spi, SSI_IE_RCIE | SSI_IE_RORIE);


	status = wait_for_completion_timeout(&priv->xfer_done,
	time_left = wait_for_completion_timeout(&priv->xfer_done,
					msecs_to_jiffies(SSI_TIMEOUT_MS));
					msecs_to_jiffies(SSI_TIMEOUT_MS));


	uniphier_spi_irq_disable(spi, SSI_IE_RCIE | SSI_IE_RORIE);
	uniphier_spi_irq_disable(spi, SSI_IE_RCIE | SSI_IE_RORIE);


	if (status < 0)
	if (!time_left) {
		return status;
		dev_err(dev, "transfer timeout.\n");
		return -ETIMEDOUT;
	}


	return priv->error;
	return priv->error;
}
}