Loading drivers/spi/spi-qup.c +45 −6 Original line number Original line Diff line number Diff line Loading @@ -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; Loading Loading @@ -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) Loading Loading @@ -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; Loading Loading @@ -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); Loading Loading @@ -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 { Loading @@ -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; } } Loading drivers/spi/spi-stm32-qspi.c +2 −2 Original line number Original line Diff line number Diff line Loading @@ -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) Loading Loading @@ -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 */ Loading drivers/spi/spi-uniphier.c +12 −5 Original line number Original line Diff line number Diff line Loading @@ -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); Loading @@ -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; } } Loading Loading
drivers/spi/spi-qup.c +45 −6 Original line number Original line Diff line number Diff line Loading @@ -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; Loading Loading @@ -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) Loading Loading @@ -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; Loading Loading @@ -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); Loading Loading @@ -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 { Loading @@ -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; } } Loading
drivers/spi/spi-stm32-qspi.c +2 −2 Original line number Original line Diff line number Diff line Loading @@ -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) Loading Loading @@ -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 */ Loading
drivers/spi/spi-uniphier.c +12 −5 Original line number Original line Diff line number Diff line Loading @@ -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); Loading @@ -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; } } Loading