aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/spi/spi-pxa2xx.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2019-05-07 07:44:33 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2019-05-07 07:44:33 -0700
commit9bff9dfc513bd5de72cb59f4bffb72cf0a5aa526 (patch)
tree3229206f8aa93ca4d34585b7eb4d3ed272397ae2 /drivers/spi/spi-pxa2xx.c
parentMerge tag 'regulator-v5.2' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regulator (diff)
parentMerge branch 'spi-5.2' into spi-next (diff)
downloadlinux-dev-9bff9dfc513bd5de72cb59f4bffb72cf0a5aa526.tar.xz
linux-dev-9bff9dfc513bd5de72cb59f4bffb72cf0a5aa526.zip
Merge tag 'spi-v5.2' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi
Pull spi updates from Mark Brown: "One small feature was added this release but the bulk of the diffstat and the changelog comes from the fact that several older drivers got some fairly hefty reworks and a couple of new drivers were added: - Support for detailed control of timing around chip selects from Sowjanya Komatineni. - A big set of fixes and imrovements for the Tegra114 driver from Sowjanya Komatineni. - A big simplification of the GPIO driver from Andrey Smirnov. - DMA support and fixes for the Freescale LPSPI driver from Clark Wang. - Fixes and optimizations for the bcm2835aux from Martin Sparl. - New drivers for Mediatek MT7621 (graduated from staging) and Zynq QSPI" [ This is a so-called "evil merge" that additionally removes a warning due to an unused variable 'i' introduced by commit 1dfbf334f123 ("spi: ep93xx: Convert to use CS GPIO descriptors") - Linus ] * tag 'spi-v5.2' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi: (127 commits) spi: rspi: Fix handling of QSPI code when transmit and receive spi: atmel-quadspi: fix crash while suspending spi: stm32: return the get_irq error spi: tegra114: fix PIO transfer spi: pxa2xx: fix SCR (divisor) calculation spi: Clear SPI_CS_HIGH flag from bad_bits for GPIO chip-select spi: ep93xx: Convert to use CS GPIO descriptors spi: AD ASoC: declare missing of table spi: spi-mem: zynq-qspi: Fix build error on architectures missing readsl/writesl spi: stm32-qspi: manage the get_irq error case spi/spi-bcm2835: Split transfers that exceed DLEN spi: expand mode support dt-bindings: spi: spi-mt65xx: add support for MT8516 spi: pxa2xx: Add support for Intel Comet Lake spi/trace: Cap buffer contents at 64 bytes spi: Release spi_res after finalizing message spi: Remove warning in spi_split_transfers_maxsize() spi: Remove one needless transfer speed fall back case spi: sh-msiof: Document r8a77470 bindings spi: pxa2xx: use a module softdep for dw_dmac ...
Diffstat (limited to 'drivers/spi/spi-pxa2xx.c')
-rw-r--r--drivers/spi/spi-pxa2xx.c38
1 files changed, 26 insertions, 12 deletions
diff --git a/drivers/spi/spi-pxa2xx.c b/drivers/spi/spi-pxa2xx.c
index b6ddba833d02..e59c8b27b155 100644
--- a/drivers/spi/spi-pxa2xx.c
+++ b/drivers/spi/spi-pxa2xx.c
@@ -884,10 +884,14 @@ static unsigned int ssp_get_clk_div(struct driver_data *drv_data, int rate)
rate = min_t(int, ssp_clk, rate);
+ /*
+ * Calculate the divisor for the SCR (Serial Clock Rate), avoiding
+ * that the SSP transmission rate can be greater than the device rate
+ */
if (ssp->type == PXA25x_SSP || ssp->type == CE4100_SSP)
- return (ssp_clk / (2 * rate) - 1) & 0xff;
+ return (DIV_ROUND_UP(ssp_clk, 2 * rate) - 1) & 0xff;
else
- return (ssp_clk / rate - 1) & 0xfff;
+ return (DIV_ROUND_UP(ssp_clk, rate) - 1) & 0xfff;
}
static unsigned int pxa2xx_ssp_get_clk_div(struct driver_data *drv_data,
@@ -925,7 +929,7 @@ static int pxa2xx_spi_transfer_one(struct spi_controller *controller,
{
struct driver_data *drv_data = spi_controller_get_devdata(controller);
struct spi_message *message = controller->cur_msg;
- struct chip_data *chip = spi_get_ctldata(message->spi);
+ struct chip_data *chip = spi_get_ctldata(spi);
u32 dma_thresh = chip->dma_threshold;
u32 dma_burst = chip->dma_burst_size;
u32 change_mask = pxa2xx_spi_get_ssrc1_change_mask(drv_data);
@@ -943,21 +947,21 @@ static int pxa2xx_spi_transfer_one(struct spi_controller *controller,
/* reject already-mapped transfers; PIO won't always work */
if (message->is_dma_mapped
|| transfer->rx_dma || transfer->tx_dma) {
- dev_err(&drv_data->pdev->dev,
+ dev_err(&spi->dev,
"Mapped transfer length of %u is greater than %d\n",
transfer->len, MAX_DMA_LEN);
return -EINVAL;
}
/* warn ... we force this to PIO mode */
- dev_warn_ratelimited(&message->spi->dev,
+ dev_warn_ratelimited(&spi->dev,
"DMA disabled for transfer length %ld greater than %d\n",
(long)transfer->len, MAX_DMA_LEN);
}
/* Setup the transfer state based on the type of transfer */
if (pxa2xx_spi_flush(drv_data) == 0) {
- dev_err(&drv_data->pdev->dev, "Flush failed\n");
+ dev_err(&spi->dev, "Flush failed\n");
return -EIO;
}
drv_data->n_bytes = chip->n_bytes;
@@ -999,15 +1003,15 @@ static int pxa2xx_spi_transfer_one(struct spi_controller *controller,
*/
if (chip->enable_dma) {
if (pxa2xx_spi_set_dma_burst_and_threshold(chip,
- message->spi,
+ spi,
bits, &dma_burst,
&dma_thresh))
- dev_warn_ratelimited(&message->spi->dev,
+ dev_warn_ratelimited(&spi->dev,
"DMA burst size reduced to match bits_per_word\n");
}
dma_mapped = controller->can_dma &&
- controller->can_dma(controller, message->spi, transfer) &&
+ controller->can_dma(controller, spi, transfer) &&
controller->cur_msg_mapped;
if (dma_mapped) {
@@ -1035,12 +1039,12 @@ static int pxa2xx_spi_transfer_one(struct spi_controller *controller,
/* NOTE: PXA25x_SSP _could_ use external clocking ... */
cr0 = pxa2xx_configure_sscr0(drv_data, clk_div, bits);
if (!pxa25x_ssp_comp(drv_data))
- dev_dbg(&message->spi->dev, "%u Hz actual, %s\n",
+ dev_dbg(&spi->dev, "%u Hz actual, %s\n",
controller->max_speed_hz
/ (1 + ((cr0 & SSCR0_SCR(0xfff)) >> 8)),
dma_mapped ? "DMA" : "PIO");
else
- dev_dbg(&message->spi->dev, "%u Hz actual, %s\n",
+ dev_dbg(&spi->dev, "%u Hz actual, %s\n",
controller->max_speed_hz / 2
/ (1 + ((cr0 & SSCR0_SCR(0x0ff)) >> 8)),
dma_mapped ? "DMA" : "PIO");
@@ -1333,6 +1337,9 @@ static int setup(struct spi_device *spi)
dev_warn(&spi->dev,
"in setup: DMA burst size reduced to match bits_per_word\n");
}
+ dev_dbg(&spi->dev,
+ "in setup: DMA burst size set to %u\n",
+ chip->dma_burst_size);
}
switch (drv_data->ssp_type) {
@@ -1451,6 +1458,10 @@ static const struct pci_device_id pxa2xx_spi_pci_compound_match[] = {
{ PCI_VDEVICE(INTEL, 0xa32a), LPSS_CNL_SSP },
{ PCI_VDEVICE(INTEL, 0xa32b), LPSS_CNL_SSP },
{ PCI_VDEVICE(INTEL, 0xa37b), LPSS_CNL_SSP },
+ /* CML-LP */
+ { PCI_VDEVICE(INTEL, 0x02aa), LPSS_CNL_SSP },
+ { PCI_VDEVICE(INTEL, 0x02ab), LPSS_CNL_SSP },
+ { PCI_VDEVICE(INTEL, 0x02fb), LPSS_CNL_SSP },
{ },
};
@@ -1564,6 +1575,7 @@ pxa2xx_spi_init_pdata(struct platform_device *pdev)
pdata->is_slave = of_property_read_bool(pdev->dev.of_node, "spi-slave");
pdata->num_chipselect = 1;
pdata->enable_dma = true;
+ pdata->dma_burst_size = 1;
return pdata;
}
@@ -1692,7 +1704,7 @@ static int pxa2xx_spi_probe(struct platform_device *pdev)
if (platform_info->enable_dma) {
status = pxa2xx_spi_dma_setup(drv_data);
if (status) {
- dev_dbg(dev, "no DMA channels available, using PIO\n");
+ dev_warn(dev, "no DMA channels available, using PIO\n");
platform_info->enable_dma = false;
} else {
controller->can_dma = pxa2xx_spi_can_dma;
@@ -1953,3 +1965,5 @@ static void __exit pxa2xx_spi_exit(void)
platform_driver_unregister(&driver);
}
module_exit(pxa2xx_spi_exit);
+
+MODULE_SOFTDEP("pre: dw_dmac");