@@ -187,6 +187,16 @@ bool spi_mem_default_supports_op(struct spi_mem *mem,
187187 return false;
188188 }
189189
190+ if (op -> max_freq && mem -> spi -> controller -> min_speed_hz &&
191+ op -> max_freq < mem -> spi -> controller -> min_speed_hz )
192+ return false;
193+
194+ if (op -> max_freq &&
195+ op -> max_freq < mem -> spi -> max_speed_hz ) {
196+ if (!spi_mem_controller_is_capable (ctlr , per_op_freq ))
197+ return false;
198+ }
199+
190200 return spi_mem_check_buswidth (mem , op );
191201}
192202EXPORT_SYMBOL_GPL (spi_mem_default_supports_op );
@@ -364,6 +374,9 @@ int spi_mem_exec_op(struct spi_mem *mem, const struct spi_mem_op *op)
364374 u8 * tmpbuf ;
365375 int ret ;
366376
377+ /* Make sure the operation frequency is correct before going futher */
378+ spi_mem_adjust_op_freq (mem , (struct spi_mem_op * )op );
379+
367380 ret = spi_mem_check_op (op );
368381 if (ret )
369382 return ret ;
@@ -410,6 +423,7 @@ int spi_mem_exec_op(struct spi_mem *mem, const struct spi_mem_op *op)
410423 xfers [xferpos ].tx_buf = tmpbuf ;
411424 xfers [xferpos ].len = op -> cmd .nbytes ;
412425 xfers [xferpos ].tx_nbits = op -> cmd .buswidth ;
426+ xfers [xferpos ].speed_hz = op -> max_freq ;
413427 spi_message_add_tail (& xfers [xferpos ], & msg );
414428 xferpos ++ ;
415429 totalxferlen ++ ;
@@ -424,6 +438,7 @@ int spi_mem_exec_op(struct spi_mem *mem, const struct spi_mem_op *op)
424438 xfers [xferpos ].tx_buf = tmpbuf + 1 ;
425439 xfers [xferpos ].len = op -> addr .nbytes ;
426440 xfers [xferpos ].tx_nbits = op -> addr .buswidth ;
441+ xfers [xferpos ].speed_hz = op -> max_freq ;
427442 spi_message_add_tail (& xfers [xferpos ], & msg );
428443 xferpos ++ ;
429444 totalxferlen += op -> addr .nbytes ;
@@ -435,6 +450,7 @@ int spi_mem_exec_op(struct spi_mem *mem, const struct spi_mem_op *op)
435450 xfers [xferpos ].len = op -> dummy .nbytes ;
436451 xfers [xferpos ].tx_nbits = op -> dummy .buswidth ;
437452 xfers [xferpos ].dummy_data = 1 ;
453+ xfers [xferpos ].speed_hz = op -> max_freq ;
438454 spi_message_add_tail (& xfers [xferpos ], & msg );
439455 xferpos ++ ;
440456 totalxferlen += op -> dummy .nbytes ;
@@ -450,6 +466,7 @@ int spi_mem_exec_op(struct spi_mem *mem, const struct spi_mem_op *op)
450466 }
451467
452468 xfers [xferpos ].len = op -> data .nbytes ;
469+ xfers [xferpos ].speed_hz = op -> max_freq ;
453470 spi_message_add_tail (& xfers [xferpos ], & msg );
454471 xferpos ++ ;
455472 totalxferlen += op -> data .nbytes ;
@@ -528,6 +545,23 @@ int spi_mem_adjust_op_size(struct spi_mem *mem, struct spi_mem_op *op)
528545}
529546EXPORT_SYMBOL_GPL (spi_mem_adjust_op_size );
530547
548+ /**
549+ * spi_mem_adjust_op_freq() - Adjust the frequency of a SPI mem operation to
550+ * match controller, PCB and chip limitations
551+ * @mem: the SPI memory
552+ * @op: the operation to adjust
553+ *
554+ * Some chips have per-op frequency limitations and must adapt the maximum
555+ * speed. This function allows SPI mem drivers to set @op->max_freq to the
556+ * maximum supported value.
557+ */
558+ void spi_mem_adjust_op_freq (struct spi_mem * mem , struct spi_mem_op * op )
559+ {
560+ if (!op -> max_freq || op -> max_freq > mem -> spi -> max_speed_hz )
561+ op -> max_freq = mem -> spi -> max_speed_hz ;
562+ }
563+ EXPORT_SYMBOL_GPL (spi_mem_adjust_op_freq );
564+
531565static ssize_t spi_mem_no_dirmap_read (struct spi_mem_dirmap_desc * desc ,
532566 u64 offs , size_t len , void * buf )
533567{
0 commit comments