Commit 6c7bdf2d authored by Mark Brown's avatar Mark Brown

Merge remote-tracking branch 'spi/fix/core' into spi-linus

parents d6d211db c3676d5c
...@@ -580,6 +580,7 @@ static void spi_set_cs(struct spi_device *spi, bool enable) ...@@ -580,6 +580,7 @@ static void spi_set_cs(struct spi_device *spi, bool enable)
spi->master->set_cs(spi, !enable); spi->master->set_cs(spi, !enable);
} }
#ifdef CONFIG_HAS_DMA
static int spi_map_buf(struct spi_master *master, struct device *dev, static int spi_map_buf(struct spi_master *master, struct device *dev,
struct sg_table *sgt, void *buf, size_t len, struct sg_table *sgt, void *buf, size_t len,
enum dma_data_direction dir) enum dma_data_direction dir)
...@@ -637,55 +638,12 @@ static void spi_unmap_buf(struct spi_master *master, struct device *dev, ...@@ -637,55 +638,12 @@ static void spi_unmap_buf(struct spi_master *master, struct device *dev,
} }
} }
static int spi_map_msg(struct spi_master *master, struct spi_message *msg) static int __spi_map_msg(struct spi_master *master, struct spi_message *msg)
{ {
struct device *tx_dev, *rx_dev; struct device *tx_dev, *rx_dev;
struct spi_transfer *xfer; struct spi_transfer *xfer;
void *tmp;
unsigned int max_tx, max_rx;
int ret; int ret;
if (master->flags & (SPI_MASTER_MUST_RX | SPI_MASTER_MUST_TX)) {
max_tx = 0;
max_rx = 0;
list_for_each_entry(xfer, &msg->transfers, transfer_list) {
if ((master->flags & SPI_MASTER_MUST_TX) &&
!xfer->tx_buf)
max_tx = max(xfer->len, max_tx);
if ((master->flags & SPI_MASTER_MUST_RX) &&
!xfer->rx_buf)
max_rx = max(xfer->len, max_rx);
}
if (max_tx) {
tmp = krealloc(master->dummy_tx, max_tx,
GFP_KERNEL | GFP_DMA);
if (!tmp)
return -ENOMEM;
master->dummy_tx = tmp;
memset(tmp, 0, max_tx);
}
if (max_rx) {
tmp = krealloc(master->dummy_rx, max_rx,
GFP_KERNEL | GFP_DMA);
if (!tmp)
return -ENOMEM;
master->dummy_rx = tmp;
}
if (max_tx || max_rx) {
list_for_each_entry(xfer, &msg->transfers,
transfer_list) {
if (!xfer->tx_buf)
xfer->tx_buf = master->dummy_tx;
if (!xfer->rx_buf)
xfer->rx_buf = master->dummy_rx;
}
}
}
if (!master->can_dma) if (!master->can_dma)
return 0; return 0;
...@@ -742,6 +700,69 @@ static int spi_unmap_msg(struct spi_master *master, struct spi_message *msg) ...@@ -742,6 +700,69 @@ static int spi_unmap_msg(struct spi_master *master, struct spi_message *msg)
return 0; return 0;
} }
#else /* !CONFIG_HAS_DMA */
static inline int __spi_map_msg(struct spi_master *master,
struct spi_message *msg)
{
return 0;
}
static inline int spi_unmap_msg(struct spi_master *master,
struct spi_message *msg)
{
return 0;
}
#endif /* !CONFIG_HAS_DMA */
static int spi_map_msg(struct spi_master *master, struct spi_message *msg)
{
struct spi_transfer *xfer;
void *tmp;
unsigned int max_tx, max_rx;
if (master->flags & (SPI_MASTER_MUST_RX | SPI_MASTER_MUST_TX)) {
max_tx = 0;
max_rx = 0;
list_for_each_entry(xfer, &msg->transfers, transfer_list) {
if ((master->flags & SPI_MASTER_MUST_TX) &&
!xfer->tx_buf)
max_tx = max(xfer->len, max_tx);
if ((master->flags & SPI_MASTER_MUST_RX) &&
!xfer->rx_buf)
max_rx = max(xfer->len, max_rx);
}
if (max_tx) {
tmp = krealloc(master->dummy_tx, max_tx,
GFP_KERNEL | GFP_DMA);
if (!tmp)
return -ENOMEM;
master->dummy_tx = tmp;
memset(tmp, 0, max_tx);
}
if (max_rx) {
tmp = krealloc(master->dummy_rx, max_rx,
GFP_KERNEL | GFP_DMA);
if (!tmp)
return -ENOMEM;
master->dummy_rx = tmp;
}
if (max_tx || max_rx) {
list_for_each_entry(xfer, &msg->transfers,
transfer_list) {
if (!xfer->tx_buf)
xfer->tx_buf = master->dummy_tx;
if (!xfer->rx_buf)
xfer->rx_buf = master->dummy_rx;
}
}
}
return __spi_map_msg(master, msg);
}
/* /*
* spi_transfer_one_message - Default implementation of transfer_one_message() * spi_transfer_one_message - Default implementation of transfer_one_message()
...@@ -1151,7 +1172,6 @@ static int spi_master_initialize_queue(struct spi_master *master) ...@@ -1151,7 +1172,6 @@ static int spi_master_initialize_queue(struct spi_master *master)
{ {
int ret; int ret;
master->queued = true;
master->transfer = spi_queued_transfer; master->transfer = spi_queued_transfer;
if (!master->transfer_one_message) if (!master->transfer_one_message)
master->transfer_one_message = spi_transfer_one_message; master->transfer_one_message = spi_transfer_one_message;
...@@ -1162,6 +1182,7 @@ static int spi_master_initialize_queue(struct spi_master *master) ...@@ -1162,6 +1182,7 @@ static int spi_master_initialize_queue(struct spi_master *master)
dev_err(&master->dev, "problem initializing queue\n"); dev_err(&master->dev, "problem initializing queue\n");
goto err_init_queue; goto err_init_queue;
} }
master->queued = true;
ret = spi_start_queue(master); ret = spi_start_queue(master);
if (ret) { if (ret) {
dev_err(&master->dev, "problem starting queue\n"); dev_err(&master->dev, "problem starting queue\n");
...@@ -1171,8 +1192,8 @@ static int spi_master_initialize_queue(struct spi_master *master) ...@@ -1171,8 +1192,8 @@ static int spi_master_initialize_queue(struct spi_master *master)
return 0; return 0;
err_start_queue: err_start_queue:
err_init_queue:
spi_destroy_queue(master); spi_destroy_queue(master);
err_init_queue:
return ret; return ret;
} }
...@@ -1756,7 +1777,7 @@ EXPORT_SYMBOL_GPL(spi_busnum_to_master); ...@@ -1756,7 +1777,7 @@ EXPORT_SYMBOL_GPL(spi_busnum_to_master);
*/ */
int spi_setup(struct spi_device *spi) int spi_setup(struct spi_device *spi)
{ {
unsigned bad_bits; unsigned bad_bits, ugly_bits;
int status = 0; int status = 0;
/* check mode to prevent that DUAL and QUAD set at the same time /* check mode to prevent that DUAL and QUAD set at the same time
...@@ -1776,6 +1797,15 @@ int spi_setup(struct spi_device *spi) ...@@ -1776,6 +1797,15 @@ int spi_setup(struct spi_device *spi)
* that aren't supported with their current master * that aren't supported with their current master
*/ */
bad_bits = spi->mode & ~spi->master->mode_bits; bad_bits = spi->mode & ~spi->master->mode_bits;
ugly_bits = bad_bits &
(SPI_TX_DUAL | SPI_TX_QUAD | SPI_RX_DUAL | SPI_RX_QUAD);
if (ugly_bits) {
dev_warn(&spi->dev,
"setup: ignoring unsupported mode bits %x\n",
ugly_bits);
spi->mode &= ~ugly_bits;
bad_bits &= ~ugly_bits;
}
if (bad_bits) { if (bad_bits) {
dev_err(&spi->dev, "setup: unsupported mode bits %x\n", dev_err(&spi->dev, "setup: unsupported mode bits %x\n",
bad_bits); bad_bits);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment