Merge branch 'spi-5.2' into spi-5.3
authorMark Brown <broonie@kernel.org>
Thu, 23 May 2019 13:47:04 +0000 (14:47 +0100)
committerMark Brown <broonie@kernel.org>
Thu, 23 May 2019 13:47:04 +0000 (14:47 +0100)
1  2 
drivers/spi/spi.c

diff --combined drivers/spi/spi.c
@@@ -1090,60 -1090,6 +1090,60 @@@ static int spi_transfer_wait(struct spi
        return 0;
  }
  
 +static void _spi_transfer_delay_ns(u32 ns)
 +{
 +      if (!ns)
 +              return;
 +      if (ns <= 1000) {
 +              ndelay(ns);
 +      } else {
 +              u32 us = DIV_ROUND_UP(ns, 1000);
 +
 +              if (us <= 10)
 +                      udelay(us);
 +              else
 +                      usleep_range(us, us + DIV_ROUND_UP(us, 10));
 +      }
 +}
 +
 +static void _spi_transfer_cs_change_delay(struct spi_message *msg,
 +                                        struct spi_transfer *xfer)
 +{
 +      u32 delay = xfer->cs_change_delay;
 +      u32 unit = xfer->cs_change_delay_unit;
 +      u32 hz;
 +
 +      /* return early on "fast" mode - for everything but USECS */
 +      if (!delay && unit != SPI_DELAY_UNIT_USECS)
 +              return;
 +
 +      switch (unit) {
 +      case SPI_DELAY_UNIT_USECS:
 +              /* for compatibility use default of 10us */
 +              if (!delay)
 +                      delay = 10000;
 +              else
 +                      delay *= 1000;
 +              break;
 +      case SPI_DELAY_UNIT_NSECS: /* nothing to do here */
 +              break;
 +      case SPI_DELAY_UNIT_SCK:
 +              /* if there is no effective speed know, then approximate
 +               * by underestimating with half the requested hz
 +               */
 +              hz = xfer->effective_speed_hz ?: xfer->speed_hz / 2;
 +              delay *= DIV_ROUND_UP(1000000000, hz);
 +              break;
 +      default:
 +              dev_err_once(&msg->spi->dev,
 +                           "Use of unsupported delay unit %i, using default of 10us\n",
 +                           xfer->cs_change_delay_unit);
 +              delay = 10000;
 +      }
 +      /* now sleep for the requested amount of time */
 +      _spi_transfer_delay_ns(delay);
 +}
 +
  /*
   * spi_transfer_one_message - Default implementation of transfer_one_message()
   *
@@@ -1202,8 -1148,14 +1202,8 @@@ static int spi_transfer_one_message(str
                if (msg->status != -EINPROGRESS)
                        goto out;
  
 -              if (xfer->delay_usecs) {
 -                      u16 us = xfer->delay_usecs;
 -
 -                      if (us <= 10)
 -                              udelay(us);
 -                      else
 -                              usleep_range(us, us + DIV_ROUND_UP(us, 10));
 -              }
 +              if (xfer->delay_usecs)
 +                      _spi_transfer_delay_ns(xfer->delay_usecs * 1000);
  
                if (xfer->cs_change) {
                        if (list_is_last(&xfer->transfer_list,
                                keep_cs = true;
                        } else {
                                spi_set_cs(msg->spi, false);
 -                              udelay(10);
 +                              _spi_transfer_cs_change_delay(msg, xfer);
                                spi_set_cs(msg->spi, true);
                        }
                }
        if (msg->status && ctlr->handle_err)
                ctlr->handle_err(ctlr, msg);
  
-       spi_finalize_current_message(ctlr);
        spi_res_release(ctlr, msg);
  
+       spi_finalize_current_message(ctlr);
        return ret;
  }
  
@@@ -1355,10 -1307,15 +1355,15 @@@ static void __spi_pump_messages(struct 
                ret = ctlr->prepare_transfer_hardware(ctlr);
                if (ret) {
                        dev_err(&ctlr->dev,
-                               "failed to prepare transfer hardware\n");
+                               "failed to prepare transfer hardware: %d\n",
+                               ret);
  
                        if (ctlr->auto_runtime_pm)
                                pm_runtime_put(ctlr->dev.parent);
+                       ctlr->cur_msg->status = ret;
+                       spi_finalize_current_message(ctlr);
                        mutex_unlock(&ctlr->io_mutex);
                        return;
                }
@@@ -3126,7 -3083,6 +3131,7 @@@ static int __spi_validate(struct spi_de
         */
        message->frame_length = 0;
        list_for_each_entry(xfer, &message->transfers, transfer_list) {
 +              xfer->effective_speed_hz = 0;
                message->frame_length += xfer->len;
                if (!xfer->bits_per_word)
                        xfer->bits_per_word = spi->bits_per_word;
@@@ -3806,3 -3762,4 +3811,3 @@@ err0
   * include needing to have boardinfo data structures be much more public.
   */
  postcore_initcall(spi_init);
 -