@@ -269,8 +269,9 @@ static int stm32_qspi_tx(struct stm32_qspi *qspi, const struct spi_mem_op *op)
269269
270270 if (qspi -> fmode == CCR_FMODE_MM )
271271 return stm32_qspi_tx_mm (qspi , op );
272- else if ((op -> data .dir == SPI_MEM_DATA_IN && qspi -> dma_chrx ) ||
273- (op -> data .dir == SPI_MEM_DATA_OUT && qspi -> dma_chtx ))
272+ else if (((op -> data .dir == SPI_MEM_DATA_IN && qspi -> dma_chrx ) ||
273+ (op -> data .dir == SPI_MEM_DATA_OUT && qspi -> dma_chtx )) &&
274+ op -> data .nbytes > 4 )
274275 if (!stm32_qspi_tx_dma (qspi , op ))
275276 return 0 ;
276277
@@ -330,7 +331,7 @@ static int stm32_qspi_send(struct spi_mem *mem, const struct spi_mem_op *op)
330331{
331332 struct stm32_qspi * qspi = spi_controller_get_devdata (mem -> spi -> master );
332333 struct stm32_qspi_flash * flash = & qspi -> flash [mem -> spi -> chip_select ];
333- u32 ccr , cr , addr_max ;
334+ u32 ccr , cr ;
334335 int timeout , err = 0 ;
335336
336337 dev_dbg (qspi -> dev , "cmd:%#x mode:%d.%d.%d.%d addr:%#llx len:%#x\n" ,
@@ -342,18 +343,6 @@ static int stm32_qspi_send(struct spi_mem *mem, const struct spi_mem_op *op)
342343 if (err )
343344 goto abort ;
344345
345- addr_max = op -> addr .val + op -> data .nbytes + 1 ;
346-
347- if (op -> data .dir == SPI_MEM_DATA_IN ) {
348- if (addr_max < qspi -> mm_size &&
349- op -> addr .buswidth )
350- qspi -> fmode = CCR_FMODE_MM ;
351- else
352- qspi -> fmode = CCR_FMODE_INDR ;
353- } else {
354- qspi -> fmode = CCR_FMODE_INDW ;
355- }
356-
357346 cr = readl_relaxed (qspi -> io_base + QSPI_CR );
358347 cr &= ~CR_PRESC_MASK & ~CR_FSEL ;
359348 cr |= FIELD_PREP (CR_PRESC_MASK , flash -> presc );
@@ -363,8 +352,6 @@ static int stm32_qspi_send(struct spi_mem *mem, const struct spi_mem_op *op)
363352 if (op -> data .nbytes )
364353 writel_relaxed (op -> data .nbytes - 1 ,
365354 qspi -> io_base + QSPI_DLR );
366- else
367- qspi -> fmode = CCR_FMODE_INDW ;
368355
369356 ccr = qspi -> fmode ;
370357 ccr |= FIELD_PREP (CCR_INST_MASK , op -> cmd .opcode );
@@ -440,6 +427,11 @@ static int stm32_qspi_exec_op(struct spi_mem *mem, const struct spi_mem_op *op)
440427 }
441428
442429 mutex_lock (& qspi -> lock );
430+ if (op -> data .dir == SPI_MEM_DATA_IN && op -> data .nbytes )
431+ qspi -> fmode = CCR_FMODE_INDR ;
432+ else
433+ qspi -> fmode = CCR_FMODE_INDW ;
434+
443435 ret = stm32_qspi_send (mem , op );
444436 mutex_unlock (& qspi -> lock );
445437
@@ -449,6 +441,64 @@ static int stm32_qspi_exec_op(struct spi_mem *mem, const struct spi_mem_op *op)
449441 return ret ;
450442}
451443
444+ static int stm32_qspi_dirmap_create (struct spi_mem_dirmap_desc * desc )
445+ {
446+ struct stm32_qspi * qspi = spi_controller_get_devdata (desc -> mem -> spi -> master );
447+
448+ if (desc -> info .op_tmpl .data .dir == SPI_MEM_DATA_OUT )
449+ return - EOPNOTSUPP ;
450+
451+ /* should never happen, as mm_base == null is an error probe exit condition */
452+ if (!qspi -> mm_base && desc -> info .op_tmpl .data .dir == SPI_MEM_DATA_IN )
453+ return - EOPNOTSUPP ;
454+
455+ if (!qspi -> mm_size )
456+ return - EOPNOTSUPP ;
457+
458+ return 0 ;
459+ }
460+
461+ static ssize_t stm32_qspi_dirmap_read (struct spi_mem_dirmap_desc * desc ,
462+ u64 offs , size_t len , void * buf )
463+ {
464+ struct stm32_qspi * qspi = spi_controller_get_devdata (desc -> mem -> spi -> master );
465+ struct spi_mem_op op ;
466+ u32 addr_max ;
467+ int ret ;
468+
469+ ret = pm_runtime_get_sync (qspi -> dev );
470+ if (ret < 0 ) {
471+ pm_runtime_put_noidle (qspi -> dev );
472+ return ret ;
473+ }
474+
475+ mutex_lock (& qspi -> lock );
476+ /* make a local copy of desc op_tmpl and complete dirmap rdesc
477+ * spi_mem_op template with offs, len and *buf in order to get
478+ * all needed transfer information into struct spi_mem_op
479+ */
480+ memcpy (& op , & desc -> info .op_tmpl , sizeof (struct spi_mem_op ));
481+ dev_dbg (qspi -> dev , "%s len = 0x%x offs = 0x%llx buf = 0x%p\n" , __func__ , len , offs , buf );
482+
483+ op .data .nbytes = len ;
484+ op .addr .val = desc -> info .offset + offs ;
485+ op .data .buf .in = buf ;
486+
487+ addr_max = op .addr .val + op .data .nbytes + 1 ;
488+ if (addr_max < qspi -> mm_size && op .addr .buswidth )
489+ qspi -> fmode = CCR_FMODE_MM ;
490+ else
491+ qspi -> fmode = CCR_FMODE_INDR ;
492+
493+ ret = stm32_qspi_send (desc -> mem , & op );
494+ mutex_unlock (& qspi -> lock );
495+
496+ pm_runtime_mark_last_busy (qspi -> dev );
497+ pm_runtime_put_autosuspend (qspi -> dev );
498+
499+ return ret ?: len ;
500+ }
501+
452502static int stm32_qspi_setup (struct spi_device * spi )
453503{
454504 struct spi_controller * ctrl = spi -> master ;
@@ -554,7 +604,9 @@ static void stm32_qspi_dma_free(struct stm32_qspi *qspi)
554604 * to check supported mode.
555605 */
556606static const struct spi_controller_mem_ops stm32_qspi_mem_ops = {
557- .exec_op = stm32_qspi_exec_op ,
607+ .exec_op = stm32_qspi_exec_op ,
608+ .dirmap_create = stm32_qspi_dirmap_create ,
609+ .dirmap_read = stm32_qspi_dirmap_read ,
558610};
559611
560612static int stm32_qspi_probe (struct platform_device * pdev )
@@ -727,21 +779,31 @@ static int __maybe_unused stm32_qspi_suspend(struct device *dev)
727779{
728780 pinctrl_pm_select_sleep_state (dev );
729781
730- return 0 ;
782+ return pm_runtime_force_suspend ( dev ) ;
731783}
732784
733785static int __maybe_unused stm32_qspi_resume (struct device * dev )
734786{
735787 struct stm32_qspi * qspi = dev_get_drvdata (dev );
788+ int ret ;
789+
790+ ret = pm_runtime_force_resume (dev );
791+ if (ret < 0 )
792+ return ret ;
736793
737794 pinctrl_pm_select_default_state (dev );
738- clk_prepare_enable (qspi -> clk );
795+
796+ ret = pm_runtime_get_sync (dev );
797+ if (ret < 0 ) {
798+ pm_runtime_put_noidle (dev );
799+ return ret ;
800+ }
739801
740802 writel_relaxed (qspi -> cr_reg , qspi -> io_base + QSPI_CR );
741803 writel_relaxed (qspi -> dcr_reg , qspi -> io_base + QSPI_DCR );
742804
743- pm_runtime_mark_last_busy (qspi -> dev );
744- pm_runtime_put_autosuspend (qspi -> dev );
805+ pm_runtime_mark_last_busy (dev );
806+ pm_runtime_put_autosuspend (dev );
745807
746808 return 0 ;
747809}
0 commit comments