Merge branch 'spi-4.18' into spi-linus
This commit is contained in:
commit
c3c7126248
|
@ -319,7 +319,7 @@ static void cdns_spi_fill_tx_fifo(struct cdns_spi *xspi)
|
|||
*/
|
||||
if (cdns_spi_read(xspi, CDNS_SPI_ISR) &
|
||||
CDNS_SPI_IXR_TXFULL)
|
||||
usleep_range(10, 20);
|
||||
udelay(10);
|
||||
|
||||
if (xspi->txbuf)
|
||||
cdns_spi_write(xspi, CDNS_SPI_TXD, *xspi->txbuf++);
|
||||
|
@ -739,7 +739,7 @@ static int __maybe_unused cnds_runtime_resume(struct device *dev)
|
|||
ret = clk_prepare_enable(xspi->ref_clk);
|
||||
if (ret) {
|
||||
dev_err(dev, "Cannot enable device clock.\n");
|
||||
clk_disable(xspi->pclk);
|
||||
clk_disable_unprepare(xspi->pclk);
|
||||
return ret;
|
||||
}
|
||||
return 0;
|
||||
|
|
|
@ -217,7 +217,7 @@ static void davinci_spi_chipselect(struct spi_device *spi, int value)
|
|||
pdata = &dspi->pdata;
|
||||
|
||||
/* program delay transfers if tx_delay is non zero */
|
||||
if (spicfg->wdelay)
|
||||
if (spicfg && spicfg->wdelay)
|
||||
spidat1 |= SPIDAT1_WDEL;
|
||||
|
||||
/*
|
||||
|
|
|
@ -485,6 +485,8 @@ int dw_spi_add_host(struct device *dev, struct dw_spi *dws)
|
|||
dws->dma_inited = 0;
|
||||
dws->dma_addr = (dma_addr_t)(dws->paddr + DW_SPI_DR);
|
||||
|
||||
spi_controller_set_devdata(master, dws);
|
||||
|
||||
ret = request_irq(dws->irq, dw_spi_irq, IRQF_SHARED, dev_name(dev),
|
||||
master);
|
||||
if (ret < 0) {
|
||||
|
@ -518,7 +520,6 @@ int dw_spi_add_host(struct device *dev, struct dw_spi *dws)
|
|||
}
|
||||
}
|
||||
|
||||
spi_controller_set_devdata(master, dws);
|
||||
ret = devm_spi_register_controller(dev, master);
|
||||
if (ret) {
|
||||
dev_err(&master->dev, "problem registering spi master\n");
|
||||
|
|
|
@ -943,11 +943,23 @@ static int dspi_resume(struct device *dev)
|
|||
|
||||
static SIMPLE_DEV_PM_OPS(dspi_pm, dspi_suspend, dspi_resume);
|
||||
|
||||
static const struct regmap_range dspi_volatile_ranges[] = {
|
||||
regmap_reg_range(SPI_MCR, SPI_TCR),
|
||||
regmap_reg_range(SPI_SR, SPI_SR),
|
||||
regmap_reg_range(SPI_PUSHR, SPI_RXFR3),
|
||||
};
|
||||
|
||||
static const struct regmap_access_table dspi_volatile_table = {
|
||||
.yes_ranges = dspi_volatile_ranges,
|
||||
.n_yes_ranges = ARRAY_SIZE(dspi_volatile_ranges),
|
||||
};
|
||||
|
||||
static const struct regmap_config dspi_regmap_config = {
|
||||
.reg_bits = 32,
|
||||
.val_bits = 32,
|
||||
.reg_stride = 4,
|
||||
.max_register = 0x88,
|
||||
.volatile_table = &dspi_volatile_table,
|
||||
};
|
||||
|
||||
static void dspi_init(struct fsl_dspi *dspi)
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#include <linux/of.h>
|
||||
#include <linux/of_address.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/of_gpio.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/sizes.h>
|
||||
#include <linux/gpio.h>
|
||||
|
@ -681,9 +682,9 @@ static int orion_spi_probe(struct platform_device *pdev)
|
|||
goto out_rel_axi_clk;
|
||||
}
|
||||
|
||||
/* Scan all SPI devices of this controller for direct mapped devices */
|
||||
for_each_available_child_of_node(pdev->dev.of_node, np) {
|
||||
u32 cs;
|
||||
int cs_gpio;
|
||||
|
||||
/* Get chip-select number from the "reg" property */
|
||||
status = of_property_read_u32(np, "reg", &cs);
|
||||
|
@ -694,6 +695,44 @@ static int orion_spi_probe(struct platform_device *pdev)
|
|||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize the CS GPIO:
|
||||
* - properly request the actual GPIO signal
|
||||
* - de-assert the logical signal so that all GPIO CS lines
|
||||
* are inactive when probing for slaves
|
||||
* - find an unused physical CS which will be driven for any
|
||||
* slave which uses a CS GPIO
|
||||
*/
|
||||
cs_gpio = of_get_named_gpio(pdev->dev.of_node, "cs-gpios", cs);
|
||||
if (cs_gpio > 0) {
|
||||
char *gpio_name;
|
||||
int cs_flags;
|
||||
|
||||
if (spi->unused_hw_gpio == -1) {
|
||||
dev_info(&pdev->dev,
|
||||
"Selected unused HW CS#%d for any GPIO CSes\n",
|
||||
cs);
|
||||
spi->unused_hw_gpio = cs;
|
||||
}
|
||||
|
||||
gpio_name = devm_kasprintf(&pdev->dev, GFP_KERNEL,
|
||||
"%s-CS%d", dev_name(&pdev->dev), cs);
|
||||
if (!gpio_name) {
|
||||
status = -ENOMEM;
|
||||
goto out_rel_axi_clk;
|
||||
}
|
||||
|
||||
cs_flags = of_property_read_bool(np, "spi-cs-high") ?
|
||||
GPIOF_OUT_INIT_LOW : GPIOF_OUT_INIT_HIGH;
|
||||
status = devm_gpio_request_one(&pdev->dev, cs_gpio,
|
||||
cs_flags, gpio_name);
|
||||
if (status) {
|
||||
dev_err(&pdev->dev,
|
||||
"Can't request GPIO for CS %d\n", cs);
|
||||
goto out_rel_axi_clk;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Check if an address is configured for this SPI device. If
|
||||
* not, the MBus mapping via the 'ranges' property in the 'soc'
|
||||
|
@ -740,44 +779,8 @@ static int orion_spi_probe(struct platform_device *pdev)
|
|||
if (status < 0)
|
||||
goto out_rel_pm;
|
||||
|
||||
if (master->cs_gpios) {
|
||||
int i;
|
||||
for (i = 0; i < master->num_chipselect; ++i) {
|
||||
char *gpio_name;
|
||||
|
||||
if (!gpio_is_valid(master->cs_gpios[i])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
gpio_name = devm_kasprintf(&pdev->dev, GFP_KERNEL,
|
||||
"%s-CS%d", dev_name(&pdev->dev), i);
|
||||
if (!gpio_name) {
|
||||
status = -ENOMEM;
|
||||
goto out_rel_master;
|
||||
}
|
||||
|
||||
status = devm_gpio_request(&pdev->dev,
|
||||
master->cs_gpios[i], gpio_name);
|
||||
if (status) {
|
||||
dev_err(&pdev->dev,
|
||||
"Can't request GPIO for CS %d\n",
|
||||
master->cs_gpios[i]);
|
||||
goto out_rel_master;
|
||||
}
|
||||
if (spi->unused_hw_gpio == -1) {
|
||||
dev_info(&pdev->dev,
|
||||
"Selected unused HW CS#%d for any GPIO CSes\n",
|
||||
i);
|
||||
spi->unused_hw_gpio = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return status;
|
||||
|
||||
out_rel_master:
|
||||
spi_unregister_master(master);
|
||||
out_rel_pm:
|
||||
pm_runtime_disable(&pdev->dev);
|
||||
out_rel_axi_clk:
|
||||
|
|
|
@ -49,6 +49,7 @@ struct sh_msiof_spi_priv {
|
|||
struct platform_device *pdev;
|
||||
struct sh_msiof_spi_info *info;
|
||||
struct completion done;
|
||||
struct completion done_txdma;
|
||||
unsigned int tx_fifo_size;
|
||||
unsigned int rx_fifo_size;
|
||||
unsigned int min_div_pow;
|
||||
|
@ -649,19 +650,21 @@ static int sh_msiof_slave_abort(struct spi_master *master)
|
|||
|
||||
p->slave_aborted = true;
|
||||
complete(&p->done);
|
||||
complete(&p->done_txdma);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sh_msiof_wait_for_completion(struct sh_msiof_spi_priv *p)
|
||||
static int sh_msiof_wait_for_completion(struct sh_msiof_spi_priv *p,
|
||||
struct completion *x)
|
||||
{
|
||||
if (spi_controller_is_slave(p->master)) {
|
||||
if (wait_for_completion_interruptible(&p->done) ||
|
||||
if (wait_for_completion_interruptible(x) ||
|
||||
p->slave_aborted) {
|
||||
dev_dbg(&p->pdev->dev, "interrupted\n");
|
||||
return -EINTR;
|
||||
}
|
||||
} else {
|
||||
if (!wait_for_completion_timeout(&p->done, HZ)) {
|
||||
if (!wait_for_completion_timeout(x, HZ)) {
|
||||
dev_err(&p->pdev->dev, "timeout\n");
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
|
@ -711,7 +714,7 @@ static int sh_msiof_spi_txrx_once(struct sh_msiof_spi_priv *p,
|
|||
}
|
||||
|
||||
/* wait for tx fifo to be emptied / rx fifo to be filled */
|
||||
ret = sh_msiof_wait_for_completion(p);
|
||||
ret = sh_msiof_wait_for_completion(p, &p->done);
|
||||
if (ret)
|
||||
goto stop_reset;
|
||||
|
||||
|
@ -740,10 +743,7 @@ static int sh_msiof_spi_txrx_once(struct sh_msiof_spi_priv *p,
|
|||
|
||||
static void sh_msiof_dma_complete(void *arg)
|
||||
{
|
||||
struct sh_msiof_spi_priv *p = arg;
|
||||
|
||||
sh_msiof_write(p, IER, 0);
|
||||
complete(&p->done);
|
||||
complete(arg);
|
||||
}
|
||||
|
||||
static int sh_msiof_dma_once(struct sh_msiof_spi_priv *p, const void *tx,
|
||||
|
@ -764,7 +764,7 @@ static int sh_msiof_dma_once(struct sh_msiof_spi_priv *p, const void *tx,
|
|||
return -EAGAIN;
|
||||
|
||||
desc_rx->callback = sh_msiof_dma_complete;
|
||||
desc_rx->callback_param = p;
|
||||
desc_rx->callback_param = &p->done;
|
||||
cookie = dmaengine_submit(desc_rx);
|
||||
if (dma_submit_error(cookie))
|
||||
return cookie;
|
||||
|
@ -782,13 +782,8 @@ static int sh_msiof_dma_once(struct sh_msiof_spi_priv *p, const void *tx,
|
|||
goto no_dma_tx;
|
||||
}
|
||||
|
||||
if (rx) {
|
||||
/* No callback */
|
||||
desc_tx->callback = NULL;
|
||||
} else {
|
||||
desc_tx->callback = sh_msiof_dma_complete;
|
||||
desc_tx->callback_param = p;
|
||||
}
|
||||
desc_tx->callback = sh_msiof_dma_complete;
|
||||
desc_tx->callback_param = &p->done_txdma;
|
||||
cookie = dmaengine_submit(desc_tx);
|
||||
if (dma_submit_error(cookie)) {
|
||||
ret = cookie;
|
||||
|
@ -805,6 +800,8 @@ static int sh_msiof_dma_once(struct sh_msiof_spi_priv *p, const void *tx,
|
|||
sh_msiof_write(p, IER, ier_bits);
|
||||
|
||||
reinit_completion(&p->done);
|
||||
if (tx)
|
||||
reinit_completion(&p->done_txdma);
|
||||
p->slave_aborted = false;
|
||||
|
||||
/* Now start DMA */
|
||||
|
@ -819,17 +816,24 @@ static int sh_msiof_dma_once(struct sh_msiof_spi_priv *p, const void *tx,
|
|||
goto stop_dma;
|
||||
}
|
||||
|
||||
/* wait for tx/rx DMA completion */
|
||||
ret = sh_msiof_wait_for_completion(p);
|
||||
if (ret)
|
||||
goto stop_reset;
|
||||
if (tx) {
|
||||
/* wait for tx DMA completion */
|
||||
ret = sh_msiof_wait_for_completion(p, &p->done_txdma);
|
||||
if (ret)
|
||||
goto stop_reset;
|
||||
}
|
||||
|
||||
if (!rx) {
|
||||
reinit_completion(&p->done);
|
||||
sh_msiof_write(p, IER, IER_TEOFE);
|
||||
if (rx) {
|
||||
/* wait for rx DMA completion */
|
||||
ret = sh_msiof_wait_for_completion(p, &p->done);
|
||||
if (ret)
|
||||
goto stop_reset;
|
||||
|
||||
sh_msiof_write(p, IER, 0);
|
||||
} else {
|
||||
/* wait for tx fifo to be emptied */
|
||||
ret = sh_msiof_wait_for_completion(p);
|
||||
sh_msiof_write(p, IER, IER_TEOFE);
|
||||
ret = sh_msiof_wait_for_completion(p, &p->done);
|
||||
if (ret)
|
||||
goto stop_reset;
|
||||
}
|
||||
|
@ -1327,6 +1331,7 @@ static int sh_msiof_spi_probe(struct platform_device *pdev)
|
|||
p->min_div_pow = chipdata->min_div_pow;
|
||||
|
||||
init_completion(&p->done);
|
||||
init_completion(&p->done_txdma);
|
||||
|
||||
p->clk = devm_clk_get(&pdev->dev, NULL);
|
||||
if (IS_ERR(p->clk)) {
|
||||
|
|
Loading…
Reference in New Issue