mirror of
https://github.com/torvalds/linux.git
synced 2024-11-11 06:31:49 +00:00
spi: Merge up fixes to help CI
Get the fixes into CI for development.
This commit is contained in:
commit
fdc5231374
@ -18703,7 +18703,6 @@ F: include/dt-bindings/clock/samsung,*.h
|
||||
F: include/linux/clk/samsung.h
|
||||
|
||||
SAMSUNG SPI DRIVERS
|
||||
M: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
|
||||
M: Andi Shyti <andi.shyti@kernel.org>
|
||||
L: linux-spi@vger.kernel.org
|
||||
L: linux-samsung-soc@vger.kernel.org
|
||||
|
@ -12,6 +12,7 @@
|
||||
#include <linux/gpio/consumer.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of_irq.h>
|
||||
#include <linux/of_address.h>
|
||||
@ -302,49 +303,43 @@ static int cdns_spi_setup_transfer(struct spi_device *spi,
|
||||
}
|
||||
|
||||
/**
|
||||
* cdns_spi_fill_tx_fifo - Fills the TX FIFO with as many bytes as possible
|
||||
* cdns_spi_process_fifo - Fills the TX FIFO, and drain the RX FIFO
|
||||
* @xspi: Pointer to the cdns_spi structure
|
||||
* @ntx: Number of bytes to pack into the TX FIFO
|
||||
* @nrx: Number of bytes to drain from the RX FIFO
|
||||
*/
|
||||
static void cdns_spi_fill_tx_fifo(struct cdns_spi *xspi)
|
||||
static void cdns_spi_process_fifo(struct cdns_spi *xspi, int ntx, int nrx)
|
||||
{
|
||||
unsigned long trans_cnt = 0;
|
||||
ntx = clamp(ntx, 0, xspi->tx_bytes);
|
||||
nrx = clamp(nrx, 0, xspi->rx_bytes);
|
||||
|
||||
while ((trans_cnt < xspi->tx_fifo_depth) &&
|
||||
(xspi->tx_bytes > 0)) {
|
||||
xspi->tx_bytes -= ntx;
|
||||
xspi->rx_bytes -= nrx;
|
||||
|
||||
while (ntx || nrx) {
|
||||
/* When xspi in busy condition, bytes may send failed,
|
||||
* then spi control did't work thoroughly, add one byte delay
|
||||
*/
|
||||
if (cdns_spi_read(xspi, CDNS_SPI_ISR) &
|
||||
CDNS_SPI_IXR_TXFULL)
|
||||
if (cdns_spi_read(xspi, CDNS_SPI_ISR) & CDNS_SPI_IXR_TXFULL)
|
||||
udelay(10);
|
||||
|
||||
if (xspi->txbuf)
|
||||
cdns_spi_write(xspi, CDNS_SPI_TXD, *xspi->txbuf++);
|
||||
else
|
||||
cdns_spi_write(xspi, CDNS_SPI_TXD, 0);
|
||||
if (ntx) {
|
||||
if (xspi->txbuf)
|
||||
cdns_spi_write(xspi, CDNS_SPI_TXD, *xspi->txbuf++);
|
||||
else
|
||||
cdns_spi_write(xspi, CDNS_SPI_TXD, 0);
|
||||
|
||||
xspi->tx_bytes--;
|
||||
trans_cnt++;
|
||||
}
|
||||
}
|
||||
ntx--;
|
||||
}
|
||||
|
||||
/**
|
||||
* cdns_spi_read_rx_fifo - Reads the RX FIFO with as many bytes as possible
|
||||
* @xspi: Pointer to the cdns_spi structure
|
||||
* @count: Read byte count
|
||||
*/
|
||||
static void cdns_spi_read_rx_fifo(struct cdns_spi *xspi, unsigned long count)
|
||||
{
|
||||
u8 data;
|
||||
if (nrx) {
|
||||
u8 data = cdns_spi_read(xspi, CDNS_SPI_RXD);
|
||||
|
||||
/* Read out the data from the RX FIFO */
|
||||
while (count > 0) {
|
||||
data = cdns_spi_read(xspi, CDNS_SPI_RXD);
|
||||
if (xspi->rxbuf)
|
||||
*xspi->rxbuf++ = data;
|
||||
xspi->rx_bytes--;
|
||||
count--;
|
||||
if (xspi->rxbuf)
|
||||
*xspi->rxbuf++ = data;
|
||||
|
||||
nrx--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -382,33 +377,22 @@ static irqreturn_t cdns_spi_irq(int irq, void *dev_id)
|
||||
spi_finalize_current_transfer(ctlr);
|
||||
status = IRQ_HANDLED;
|
||||
} else if (intr_status & CDNS_SPI_IXR_TXOW) {
|
||||
int trans_cnt = cdns_spi_read(xspi, CDNS_SPI_THLD);
|
||||
int threshold = cdns_spi_read(xspi, CDNS_SPI_THLD);
|
||||
int trans_cnt = xspi->rx_bytes - xspi->tx_bytes;
|
||||
|
||||
if (threshold > 1)
|
||||
trans_cnt -= threshold;
|
||||
|
||||
/* Set threshold to one if number of pending are
|
||||
* less than half fifo
|
||||
*/
|
||||
if (xspi->tx_bytes < xspi->tx_fifo_depth >> 1)
|
||||
cdns_spi_write(xspi, CDNS_SPI_THLD, 1);
|
||||
|
||||
while (trans_cnt) {
|
||||
cdns_spi_read_rx_fifo(xspi, 1);
|
||||
|
||||
if (xspi->tx_bytes) {
|
||||
if (xspi->txbuf)
|
||||
cdns_spi_write(xspi, CDNS_SPI_TXD,
|
||||
*xspi->txbuf++);
|
||||
else
|
||||
cdns_spi_write(xspi, CDNS_SPI_TXD, 0);
|
||||
xspi->tx_bytes--;
|
||||
}
|
||||
trans_cnt--;
|
||||
}
|
||||
if (!xspi->tx_bytes) {
|
||||
/* Fixed delay due to controller limitation with
|
||||
* RX_NEMPTY incorrect status
|
||||
* Xilinx AR:65885 contains more details
|
||||
*/
|
||||
udelay(10);
|
||||
cdns_spi_read_rx_fifo(xspi, xspi->rx_bytes);
|
||||
if (xspi->tx_bytes) {
|
||||
cdns_spi_process_fifo(xspi, trans_cnt, trans_cnt);
|
||||
} else {
|
||||
cdns_spi_process_fifo(xspi, 0, trans_cnt);
|
||||
cdns_spi_write(xspi, CDNS_SPI_IDR,
|
||||
CDNS_SPI_IXR_DEFAULT);
|
||||
spi_finalize_current_transfer(ctlr);
|
||||
@ -451,16 +435,17 @@ static int cdns_transfer_one(struct spi_controller *ctlr,
|
||||
xspi->tx_bytes = transfer->len;
|
||||
xspi->rx_bytes = transfer->len;
|
||||
|
||||
if (!spi_controller_is_slave(ctlr))
|
||||
if (!spi_controller_is_slave(ctlr)) {
|
||||
cdns_spi_setup_transfer(spi, transfer);
|
||||
} else {
|
||||
/* Set TX empty threshold to half of FIFO depth
|
||||
* only if TX bytes are more than half FIFO depth.
|
||||
*/
|
||||
if (xspi->tx_bytes > xspi->tx_fifo_depth)
|
||||
cdns_spi_write(xspi, CDNS_SPI_THLD, xspi->tx_fifo_depth >> 1);
|
||||
}
|
||||
|
||||
/* Set TX empty threshold to half of FIFO depth
|
||||
* only if TX bytes are more than half FIFO depth.
|
||||
*/
|
||||
if (xspi->tx_bytes > (xspi->tx_fifo_depth >> 1))
|
||||
cdns_spi_write(xspi, CDNS_SPI_THLD, xspi->tx_fifo_depth >> 1);
|
||||
|
||||
cdns_spi_fill_tx_fifo(xspi);
|
||||
cdns_spi_process_fifo(xspi, xspi->tx_fifo_depth, 0);
|
||||
spi_transfer_delay_exec(transfer);
|
||||
|
||||
cdns_spi_write(xspi, CDNS_SPI_IER, CDNS_SPI_IXR_DEFAULT);
|
||||
|
@ -264,17 +264,17 @@ static void dw_spi_elba_set_cs(struct spi_device *spi, bool enable)
|
||||
struct regmap *syscon = dwsmmio->priv;
|
||||
u8 cs;
|
||||
|
||||
cs = spi->chip_select;
|
||||
cs = spi_get_chipselect(spi, 0);
|
||||
if (cs < 2)
|
||||
dw_spi_elba_override_cs(syscon, spi->chip_select, enable);
|
||||
dw_spi_elba_override_cs(syscon, spi_get_chipselect(spi, 0), enable);
|
||||
|
||||
/*
|
||||
* The DW SPI controller needs a native CS bit selected to start
|
||||
* the serial engine.
|
||||
*/
|
||||
spi->chip_select = 0;
|
||||
spi_set_chipselect(spi, 0, 0);
|
||||
dw_spi_set_cs(spi, enable);
|
||||
spi->chip_select = cs;
|
||||
spi_get_chipselect(spi, cs);
|
||||
}
|
||||
|
||||
static int dw_spi_elba_init(struct platform_device *pdev,
|
||||
|
@ -916,9 +916,14 @@ static int fsl_lpspi_probe(struct platform_device *pdev)
|
||||
ret = fsl_lpspi_dma_init(&pdev->dev, fsl_lpspi, controller);
|
||||
if (ret == -EPROBE_DEFER)
|
||||
goto out_pm_get;
|
||||
|
||||
if (ret < 0)
|
||||
dev_err(&pdev->dev, "dma setup error %d, use pio\n", ret);
|
||||
else
|
||||
/*
|
||||
* disable LPSPI module IRQ when enable DMA mode successfully,
|
||||
* to prevent the unexpected LPSPI module IRQ events.
|
||||
*/
|
||||
disable_irq(irq);
|
||||
|
||||
ret = devm_spi_register_controller(&pdev->dev, controller);
|
||||
if (ret < 0) {
|
||||
|
@ -294,6 +294,8 @@ static void spi_geni_set_cs(struct spi_device *slv, bool set_flag)
|
||||
mas->cs_flag = set_flag;
|
||||
/* set xfer_mode to FIFO to complete cs_done in isr */
|
||||
mas->cur_xfer_mode = GENI_SE_FIFO;
|
||||
geni_se_select_mode(se, mas->cur_xfer_mode);
|
||||
|
||||
reinit_completion(&mas->cs_done);
|
||||
if (set_flag)
|
||||
geni_se_setup_m_cmd(se, SPI_CS_ASSERT, 0);
|
||||
|
@ -1276,6 +1276,9 @@ static void mtk_spi_remove(struct platform_device *pdev)
|
||||
struct mtk_spi *mdata = spi_master_get_devdata(master);
|
||||
int ret;
|
||||
|
||||
if (mdata->use_spimem && !completion_done(&mdata->spimem_done))
|
||||
complete(&mdata->spimem_done);
|
||||
|
||||
ret = pm_runtime_get_sync(&pdev->dev);
|
||||
if (ret < 0) {
|
||||
dev_warn(&pdev->dev, "Failed to resume hardware (%pe)\n", ERR_PTR(ret));
|
||||
|
@ -1028,23 +1028,8 @@ static int spi_qup_probe(struct platform_device *pdev)
|
||||
return -ENXIO;
|
||||
}
|
||||
|
||||
ret = clk_prepare_enable(cclk);
|
||||
if (ret) {
|
||||
dev_err(dev, "cannot enable core clock\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = clk_prepare_enable(iclk);
|
||||
if (ret) {
|
||||
clk_disable_unprepare(cclk);
|
||||
dev_err(dev, "cannot enable iface clock\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
master = spi_alloc_master(dev, sizeof(struct spi_qup));
|
||||
if (!master) {
|
||||
clk_disable_unprepare(cclk);
|
||||
clk_disable_unprepare(iclk);
|
||||
dev_err(dev, "cannot allocate master\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
@ -1092,6 +1077,19 @@ static int spi_qup_probe(struct platform_device *pdev)
|
||||
spin_lock_init(&controller->lock);
|
||||
init_completion(&controller->done);
|
||||
|
||||
ret = clk_prepare_enable(cclk);
|
||||
if (ret) {
|
||||
dev_err(dev, "cannot enable core clock\n");
|
||||
goto error_dma;
|
||||
}
|
||||
|
||||
ret = clk_prepare_enable(iclk);
|
||||
if (ret) {
|
||||
clk_disable_unprepare(cclk);
|
||||
dev_err(dev, "cannot enable iface clock\n");
|
||||
goto error_dma;
|
||||
}
|
||||
|
||||
iomode = readl_relaxed(base + QUP_IO_M_MODES);
|
||||
|
||||
size = QUP_IO_M_OUTPUT_BLOCK_SIZE(iomode);
|
||||
@ -1121,7 +1119,7 @@ static int spi_qup_probe(struct platform_device *pdev)
|
||||
ret = spi_qup_set_state(controller, QUP_STATE_RESET);
|
||||
if (ret) {
|
||||
dev_err(dev, "cannot set RESET state\n");
|
||||
goto error_dma;
|
||||
goto error_clk;
|
||||
}
|
||||
|
||||
writel_relaxed(0, base + QUP_OPERATIONAL);
|
||||
@ -1145,7 +1143,7 @@ static int spi_qup_probe(struct platform_device *pdev)
|
||||
ret = devm_request_irq(dev, irq, spi_qup_qup_irq,
|
||||
IRQF_TRIGGER_HIGH, pdev->name, controller);
|
||||
if (ret)
|
||||
goto error_dma;
|
||||
goto error_clk;
|
||||
|
||||
pm_runtime_set_autosuspend_delay(dev, MSEC_PER_SEC);
|
||||
pm_runtime_use_autosuspend(dev);
|
||||
@ -1160,11 +1158,12 @@ static int spi_qup_probe(struct platform_device *pdev)
|
||||
|
||||
disable_pm:
|
||||
pm_runtime_disable(&pdev->dev);
|
||||
error_clk:
|
||||
clk_disable_unprepare(cclk);
|
||||
clk_disable_unprepare(iclk);
|
||||
error_dma:
|
||||
spi_qup_release_dma(master);
|
||||
error:
|
||||
clk_disable_unprepare(cclk);
|
||||
clk_disable_unprepare(iclk);
|
||||
spi_master_put(master);
|
||||
return ret;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user