Merge remote-tracking branch 'spi/topic/dma' into spi-next
authorMark Brown <broonie@kernel.org>
Fri, 11 Mar 2016 07:28:20 +0000 (14:28 +0700)
committerMark Brown <broonie@kernel.org>
Fri, 11 Mar 2016 07:28:20 +0000 (14:28 +0700)
1  2 
drivers/spi/spi.c

diff --combined drivers/spi/spi.c
@@@ -702,6 -702,7 +702,7 @@@ static int spi_map_buf(struct spi_maste
                       enum dma_data_direction dir)
  {
        const bool vmalloced_buf = is_vmalloc_addr(buf);
+       unsigned int max_seg_size = dma_get_max_seg_size(dev);
        int desc_len;
        int sgs;
        struct page *vm_page;
        int i, ret;
  
        if (vmalloced_buf) {
-               desc_len = PAGE_SIZE;
+               desc_len = min_t(int, max_seg_size, PAGE_SIZE);
                sgs = DIV_ROUND_UP(len + offset_in_page(buf), desc_len);
        } else {
-               desc_len = master->max_dma_len;
+               desc_len = min_t(int, max_seg_size, master->max_dma_len);
                sgs = DIV_ROUND_UP(len, desc_len);
        }
  
                        sg_set_buf(&sgt->sgl[i], sg_buf, min);
                }
  
                buf += min;
                len -= min;
        }
@@@ -1152,7 -1152,6 +1152,7 @@@ static void __spi_pump_messages(struct 
                }
        }
  
 +      mutex_lock(&master->bus_lock_mutex);
        trace_spi_message_start(master->cur_msg);
  
        if (master->prepare_message) {
                                "failed to prepare message: %d\n", ret);
                        master->cur_msg->status = ret;
                        spi_finalize_current_message(master);
 +                      mutex_unlock(&master->bus_lock_mutex);
                        return;
                }
                master->cur_msg_prepared = true;
        if (ret) {
                master->cur_msg->status = ret;
                spi_finalize_current_message(master);
 +              mutex_unlock(&master->bus_lock_mutex);
                return;
        }
  
        if (ret) {
                dev_err(&master->dev,
                        "failed to transfer one message from queue\n");
 +              mutex_unlock(&master->bus_lock_mutex);
                return;
        }
 +      mutex_unlock(&master->bus_lock_mutex);
 +
 +      /* Prod the scheduler in case transfer_one() was busy waiting */
 +      cond_resched();
  }
  
  /**
@@@ -2359,46 -2351,6 +2359,46 @@@ int spi_async_locked(struct spi_device 
  EXPORT_SYMBOL_GPL(spi_async_locked);
  
  
 +int spi_flash_read(struct spi_device *spi,
 +                 struct spi_flash_read_message *msg)
 +
 +{
 +      struct spi_master *master = spi->master;
 +      int ret;
 +
 +      if ((msg->opcode_nbits == SPI_NBITS_DUAL ||
 +           msg->addr_nbits == SPI_NBITS_DUAL) &&
 +          !(spi->mode & (SPI_TX_DUAL | SPI_TX_QUAD)))
 +              return -EINVAL;
 +      if ((msg->opcode_nbits == SPI_NBITS_QUAD ||
 +           msg->addr_nbits == SPI_NBITS_QUAD) &&
 +          !(spi->mode & SPI_TX_QUAD))
 +              return -EINVAL;
 +      if (msg->data_nbits == SPI_NBITS_DUAL &&
 +          !(spi->mode & (SPI_RX_DUAL | SPI_RX_QUAD)))
 +              return -EINVAL;
 +      if (msg->data_nbits == SPI_NBITS_QUAD &&
 +          !(spi->mode &  SPI_RX_QUAD))
 +              return -EINVAL;
 +
 +      if (master->auto_runtime_pm) {
 +              ret = pm_runtime_get_sync(master->dev.parent);
 +              if (ret < 0) {
 +                      dev_err(&master->dev, "Failed to power device: %d\n",
 +                              ret);
 +                      return ret;
 +              }
 +      }
 +      mutex_lock(&master->bus_lock_mutex);
 +      ret = master->spi_flash_read(spi, msg);
 +      mutex_unlock(&master->bus_lock_mutex);
 +      if (master->auto_runtime_pm)
 +              pm_runtime_put(master->dev.parent);
 +
 +      return ret;
 +}
 +EXPORT_SYMBOL_GPL(spi_flash_read);
 +
  /*-------------------------------------------------------------------------*/
  
  /* Utility methods for SPI master protocol drivers, layered on