Merge remote-tracking branches 'spi/topic/pxa2xx', 'spi/topic/qup', 'spi/topic/rockchip', 'spi/topic/st-ssc4' and 'spi/topic/xlp' into spi-next

This commit is contained in:
Mark Brown 2016-05-23 12:16:55 +01:00
8 changed files with 50 additions and 35 deletions

View File

@ -580,7 +580,7 @@ config SPI_SIRF
config SPI_ST_SSC4 config SPI_ST_SSC4
tristate "STMicroelectronics SPI SSC-based driver" tristate "STMicroelectronics SPI SSC-based driver"
depends on ARCH_STI depends on ARCH_STI || COMPILE_TEST
help help
STMicroelectronics SoCs support for SPI. If you say yes to STMicroelectronics SoCs support for SPI. If you say yes to
this option, support will be included for the SSC driven SPI. this option, support will be included for the SSC driven SPI.
@ -667,7 +667,7 @@ config SPI_XILINX
config SPI_XLP config SPI_XLP
tristate "Netlogic XLP SPI controller driver" tristate "Netlogic XLP SPI controller driver"
depends on CPU_XLP || COMPILE_TEST depends on CPU_XLP || ARCH_VULCAN || COMPILE_TEST
help help
Enable support for the SPI controller on the Netlogic XLP SoCs. Enable support for the SPI controller on the Netlogic XLP SoCs.
Currently supported XLP variants are XLP8XX, XLP3XX, XLP2XX, XLP9XX Currently supported XLP variants are XLP8XX, XLP3XX, XLP2XX, XLP9XX

View File

@ -33,12 +33,10 @@ static int pxa2xx_spi_map_dma_buffer(struct driver_data *drv_data,
dmadev = drv_data->tx_chan->device->dev; dmadev = drv_data->tx_chan->device->dev;
sgt = &drv_data->tx_sgt; sgt = &drv_data->tx_sgt;
buf = drv_data->tx; buf = drv_data->tx;
drv_data->tx_map_len = len;
} else { } else {
dmadev = drv_data->rx_chan->device->dev; dmadev = drv_data->rx_chan->device->dev;
sgt = &drv_data->rx_sgt; sgt = &drv_data->rx_sgt;
buf = drv_data->rx; buf = drv_data->rx;
drv_data->rx_map_len = len;
} }
nents = DIV_ROUND_UP(len, SZ_2K); nents = DIV_ROUND_UP(len, SZ_2K);
@ -55,11 +53,7 @@ static int pxa2xx_spi_map_dma_buffer(struct driver_data *drv_data,
for_each_sg(sgt->sgl, sg, sgt->nents, i) { for_each_sg(sgt->sgl, sg, sgt->nents, i) {
size_t bytes = min_t(size_t, len, SZ_2K); size_t bytes = min_t(size_t, len, SZ_2K);
if (buf) sg_set_buf(sg, pbuf, bytes);
sg_set_buf(sg, pbuf, bytes);
else
sg_set_buf(sg, drv_data->dummy, bytes);
pbuf += bytes; pbuf += bytes;
len -= bytes; len -= bytes;
} }
@ -133,9 +127,6 @@ static void pxa2xx_spi_dma_transfer_complete(struct driver_data *drv_data,
if (!error) { if (!error) {
pxa2xx_spi_unmap_dma_buffers(drv_data); pxa2xx_spi_unmap_dma_buffers(drv_data);
drv_data->tx += drv_data->tx_map_len;
drv_data->rx += drv_data->rx_map_len;
msg->actual_length += drv_data->len; msg->actual_length += drv_data->len;
msg->state = pxa2xx_spi_next_transfer(drv_data); msg->state = pxa2xx_spi_next_transfer(drv_data);
} else { } else {
@ -267,19 +258,22 @@ irqreturn_t pxa2xx_spi_dma_transfer(struct driver_data *drv_data)
int pxa2xx_spi_dma_prepare(struct driver_data *drv_data, u32 dma_burst) int pxa2xx_spi_dma_prepare(struct driver_data *drv_data, u32 dma_burst)
{ {
struct dma_async_tx_descriptor *tx_desc, *rx_desc; struct dma_async_tx_descriptor *tx_desc, *rx_desc;
int err = 0;
tx_desc = pxa2xx_spi_dma_prepare_one(drv_data, DMA_MEM_TO_DEV); tx_desc = pxa2xx_spi_dma_prepare_one(drv_data, DMA_MEM_TO_DEV);
if (!tx_desc) { if (!tx_desc) {
dev_err(&drv_data->pdev->dev, dev_err(&drv_data->pdev->dev,
"failed to get DMA TX descriptor\n"); "failed to get DMA TX descriptor\n");
return -EBUSY; err = -EBUSY;
goto err_tx;
} }
rx_desc = pxa2xx_spi_dma_prepare_one(drv_data, DMA_DEV_TO_MEM); rx_desc = pxa2xx_spi_dma_prepare_one(drv_data, DMA_DEV_TO_MEM);
if (!rx_desc) { if (!rx_desc) {
dev_err(&drv_data->pdev->dev, dev_err(&drv_data->pdev->dev,
"failed to get DMA RX descriptor\n"); "failed to get DMA RX descriptor\n");
return -EBUSY; err = -EBUSY;
goto err_rx;
} }
/* We are ready when RX completes */ /* We are ready when RX completes */
@ -289,6 +283,12 @@ int pxa2xx_spi_dma_prepare(struct driver_data *drv_data, u32 dma_burst)
dmaengine_submit(rx_desc); dmaengine_submit(rx_desc);
dmaengine_submit(tx_desc); dmaengine_submit(tx_desc);
return 0; return 0;
err_rx:
dmaengine_terminate_async(drv_data->tx_chan);
err_tx:
pxa2xx_spi_unmap_dma_buffers(drv_data);
return err;
} }
void pxa2xx_spi_dma_start(struct driver_data *drv_data) void pxa2xx_spi_dma_start(struct driver_data *drv_data)
@ -308,10 +308,6 @@ int pxa2xx_spi_dma_setup(struct driver_data *drv_data)
dma_cap_zero(mask); dma_cap_zero(mask);
dma_cap_set(DMA_SLAVE, mask); dma_cap_set(DMA_SLAVE, mask);
drv_data->dummy = devm_kzalloc(dev, SZ_2K, GFP_KERNEL);
if (!drv_data->dummy)
return -ENOMEM;
drv_data->tx_chan = dma_request_slave_channel_compat(mask, drv_data->tx_chan = dma_request_slave_channel_compat(mask,
pdata->dma_filter, pdata->tx_param, dev, "tx"); pdata->dma_filter, pdata->tx_param, dev, "tx");
if (!drv_data->tx_chan) if (!drv_data->tx_chan)

View File

@ -173,8 +173,8 @@ static int pxa2xx_spi_pci_probe(struct pci_dev *dev,
ssp->type = c->type; ssp->type = c->type;
snprintf(buf, sizeof(buf), "pxa2xx-spi.%d", ssp->port_id); snprintf(buf, sizeof(buf), "pxa2xx-spi.%d", ssp->port_id);
ssp->clk = clk_register_fixed_rate(&dev->dev, buf , NULL, ssp->clk = clk_register_fixed_rate(&dev->dev, buf , NULL, 0,
CLK_IS_ROOT, c->max_clk_rate); c->max_clk_rate);
if (IS_ERR(ssp->clk)) if (IS_ERR(ssp->clk))
return PTR_ERR(ssp->clk); return PTR_ERR(ssp->clk);

View File

@ -570,9 +570,8 @@ static void giveback(struct driver_data *drv_data)
/* see if the next and current messages point /* see if the next and current messages point
* to the same chip * to the same chip
*/ */
if (next_msg && next_msg->spi != msg->spi) if ((next_msg && next_msg->spi != msg->spi) ||
next_msg = NULL; msg->state == ERROR_STATE)
if (!next_msg || msg->state == ERROR_STATE)
cs_deassert(drv_data); cs_deassert(drv_data);
} }
@ -928,6 +927,7 @@ static void pump_transfers(unsigned long data)
u32 dma_thresh = drv_data->cur_chip->dma_threshold; u32 dma_thresh = drv_data->cur_chip->dma_threshold;
u32 dma_burst = drv_data->cur_chip->dma_burst_size; u32 dma_burst = drv_data->cur_chip->dma_burst_size;
u32 change_mask = pxa2xx_spi_get_ssrc1_change_mask(drv_data); u32 change_mask = pxa2xx_spi_get_ssrc1_change_mask(drv_data);
int err;
/* Get current state information */ /* Get current state information */
message = drv_data->cur_msg; message = drv_data->cur_msg;
@ -1047,7 +1047,12 @@ static void pump_transfers(unsigned long data)
/* Ensure we have the correct interrupt handler */ /* Ensure we have the correct interrupt handler */
drv_data->transfer_handler = pxa2xx_spi_dma_transfer; drv_data->transfer_handler = pxa2xx_spi_dma_transfer;
pxa2xx_spi_dma_prepare(drv_data, dma_burst); err = pxa2xx_spi_dma_prepare(drv_data, dma_burst);
if (err) {
message->status = err;
giveback(drv_data);
return;
}
/* Clear status and start DMA engine */ /* Clear status and start DMA engine */
cr1 = chip->cr1 | dma_thresh | drv_data->dma_cr1; cr1 = chip->cr1 | dma_thresh | drv_data->dma_cr1;
@ -1555,6 +1560,7 @@ static int pxa2xx_spi_probe(struct platform_device *pdev)
master->unprepare_transfer_hardware = pxa2xx_spi_unprepare_transfer; master->unprepare_transfer_hardware = pxa2xx_spi_unprepare_transfer;
master->fw_translate_cs = pxa2xx_spi_fw_translate_cs; master->fw_translate_cs = pxa2xx_spi_fw_translate_cs;
master->auto_runtime_pm = true; master->auto_runtime_pm = true;
master->flags = SPI_MASTER_MUST_RX | SPI_MASTER_MUST_TX;
drv_data->ssp_type = ssp->type; drv_data->ssp_type = ssp->type;

View File

@ -56,7 +56,6 @@ struct driver_data {
struct sg_table tx_sgt; struct sg_table tx_sgt;
int rx_nents; int rx_nents;
int tx_nents; int tx_nents;
void *dummy;
atomic_t dma_running; atomic_t dma_running;
/* Current message transfer state info */ /* Current message transfer state info */
@ -69,8 +68,6 @@ struct driver_data {
void *rx; void *rx;
void *rx_end; void *rx_end;
int dma_mapped; int dma_mapped;
size_t rx_map_len;
size_t tx_map_len;
u8 n_bytes; u8 n_bytes;
int (*write)(struct driver_data *drv_data); int (*write)(struct driver_data *drv_data);
int (*read)(struct driver_data *drv_data); int (*read)(struct driver_data *drv_data);

View File

@ -937,6 +937,10 @@ static int spi_qup_pm_suspend_runtime(struct device *device)
config = readl(controller->base + QUP_CONFIG); config = readl(controller->base + QUP_CONFIG);
config |= QUP_CONFIG_CLOCK_AUTO_GATE; config |= QUP_CONFIG_CLOCK_AUTO_GATE;
writel_relaxed(config, controller->base + QUP_CONFIG); writel_relaxed(config, controller->base + QUP_CONFIG);
clk_disable_unprepare(controller->cclk);
clk_disable_unprepare(controller->iclk);
return 0; return 0;
} }
@ -945,6 +949,15 @@ static int spi_qup_pm_resume_runtime(struct device *device)
struct spi_master *master = dev_get_drvdata(device); struct spi_master *master = dev_get_drvdata(device);
struct spi_qup *controller = spi_master_get_devdata(master); struct spi_qup *controller = spi_master_get_devdata(master);
u32 config; u32 config;
int ret;
ret = clk_prepare_enable(controller->iclk);
if (ret)
return ret;
ret = clk_prepare_enable(controller->cclk);
if (ret)
return ret;
/* Disable clocks auto gaiting */ /* Disable clocks auto gaiting */
config = readl_relaxed(controller->base + QUP_CONFIG); config = readl_relaxed(controller->base + QUP_CONFIG);
@ -1017,6 +1030,8 @@ static int spi_qup_remove(struct platform_device *pdev)
pm_runtime_put_noidle(&pdev->dev); pm_runtime_put_noidle(&pdev->dev);
pm_runtime_disable(&pdev->dev); pm_runtime_disable(&pdev->dev);
spi_master_put(master);
return 0; return 0;
} }

View File

@ -744,10 +744,8 @@ static int rockchip_spi_probe(struct platform_device *pdev)
rs->dma_rx.ch = dma_request_chan(rs->dev, "rx"); rs->dma_rx.ch = dma_request_chan(rs->dev, "rx");
if (IS_ERR(rs->dma_rx.ch)) { if (IS_ERR(rs->dma_rx.ch)) {
if (PTR_ERR(rs->dma_rx.ch) == -EPROBE_DEFER) { if (PTR_ERR(rs->dma_rx.ch) == -EPROBE_DEFER) {
dma_release_channel(rs->dma_tx.ch);
rs->dma_tx.ch = NULL;
ret = -EPROBE_DEFER; ret = -EPROBE_DEFER;
goto err_get_fifo_len; goto err_free_dma_tx;
} }
dev_warn(rs->dev, "Failed to request RX DMA channel\n"); dev_warn(rs->dev, "Failed to request RX DMA channel\n");
rs->dma_rx.ch = NULL; rs->dma_rx.ch = NULL;
@ -775,10 +773,11 @@ static int rockchip_spi_probe(struct platform_device *pdev)
err_register_master: err_register_master:
pm_runtime_disable(&pdev->dev); pm_runtime_disable(&pdev->dev);
if (rs->dma_tx.ch)
dma_release_channel(rs->dma_tx.ch);
if (rs->dma_rx.ch) if (rs->dma_rx.ch)
dma_release_channel(rs->dma_rx.ch); dma_release_channel(rs->dma_rx.ch);
err_free_dma_tx:
if (rs->dma_tx.ch)
dma_release_channel(rs->dma_tx.ch);
err_get_fifo_len: err_get_fifo_len:
clk_disable_unprepare(rs->spiclk); clk_disable_unprepare(rs->spiclk);
err_spiclk_enable: err_spiclk_enable:

View File

@ -345,12 +345,13 @@ static int spi_st_probe(struct platform_device *pdev)
spi_st->clk = devm_clk_get(&pdev->dev, "ssc"); spi_st->clk = devm_clk_get(&pdev->dev, "ssc");
if (IS_ERR(spi_st->clk)) { if (IS_ERR(spi_st->clk)) {
dev_err(&pdev->dev, "Unable to request clock\n"); dev_err(&pdev->dev, "Unable to request clock\n");
return PTR_ERR(spi_st->clk); ret = PTR_ERR(spi_st->clk);
goto put_master;
} }
ret = spi_st_clk_enable(spi_st); ret = spi_st_clk_enable(spi_st);
if (ret) if (ret)
return ret; goto put_master;
init_completion(&spi_st->done); init_completion(&spi_st->done);
@ -408,7 +409,8 @@ static int spi_st_probe(struct platform_device *pdev)
clk_disable: clk_disable:
spi_st_clk_disable(spi_st); spi_st_clk_disable(spi_st);
put_master:
spi_master_put(master);
return ret; return ret;
} }