summaryrefslogtreecommitdiffstats
path: root/drivers/spi/spi-cadence.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-08-05 16:18:13 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2014-08-05 16:18:13 -0700
commit1325b6550a7b9cda52ee4c0da04fa9f93d2618fc (patch)
tree07c5f64e7c3484a21553378ca3f256a3ce569b85 /drivers/spi/spi-cadence.c
parentdc7aafba6bfa1ea5806c6ac402e690682f950f75 (diff)
parentfab6a0410d20ef09238ef54b8726d170578da752 (diff)
downloadop-kernel-dev-1325b6550a7b9cda52ee4c0da04fa9f93d2618fc.zip
op-kernel-dev-1325b6550a7b9cda52ee4c0da04fa9f93d2618fc.tar.gz
Merge tag 'spi-v3.17' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi
Pull spi updates from Mark Brown: "A quiet release, more bug fixes than anything else. A few things do stand out though: - updates to several drivers to move towards the standard GPIO chip select handling in the core. - DMA support for the SH MSIOF driver. - support for Rockchip SPI controllers (their first mainline submission)" * tag 'spi-v3.17' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi: (64 commits) spi: davinci: use spi_device.cs_gpio to store gpio cs per spi device spi: davinci: add support to configure gpio cs through dt spi/pl022: Explicitly truncate large bitmask spi/atmel: Fix pointer to int conversion warnings on 64 bit builds spi: davinci: fix to support more than 2 chip selects spi: topcliff-pch: don't hardcode PCI slot to get DMA device spi: orion: fix incorrect handling of cell-index DT property spi: orion: Fix error return code in orion_spi_probe() spi/rockchip: fix error return code in rockchip_spi_probe() spi/rockchip: remove redundant dev_err call in rockchip_spi_probe() spi/rockchip: remove duplicated include from spi-rockchip.c ARM: dts: fix the chip select gpios definition in the SPI nodes spi: s3c64xx: Update binding documentation spi: s3c64xx: use the generic SPI "cs-gpios" property spi: s3c64xx: Revert "spi: s3c64xx: Added provision for dedicated cs pin" spi: atmel: Use dmaengine_prep_slave_sg() API spi: topcliff-pch: Update error messages for dmaengine_prep_slave_sg() API spi: sh-msiof: Use correct device for DMA mapping with IOMMU spi: sh-msiof: Handle dmaengine_prep_slave_single() failures gracefully spi: rspi: Handle dmaengine_prep_slave_sg() failures gracefully ...
Diffstat (limited to 'drivers/spi/spi-cadence.c')
-rw-r--r--drivers/spi/spi-cadence.c37
1 files changed, 27 insertions, 10 deletions
diff --git a/drivers/spi/spi-cadence.c b/drivers/spi/spi-cadence.c
index bb75897..562ff83 100644
--- a/drivers/spi/spi-cadence.c
+++ b/drivers/spi/spi-cadence.c
@@ -205,18 +205,30 @@ static void cdns_spi_chipselect(struct spi_device *spi, bool is_high)
static void cdns_spi_config_clock_mode(struct spi_device *spi)
{
struct cdns_spi *xspi = spi_master_get_devdata(spi->master);
- u32 ctrl_reg;
+ u32 ctrl_reg, new_ctrl_reg;
- ctrl_reg = cdns_spi_read(xspi, CDNS_SPI_CR_OFFSET);
+ new_ctrl_reg = ctrl_reg = cdns_spi_read(xspi, CDNS_SPI_CR_OFFSET);
/* Set the SPI clock phase and clock polarity */
- ctrl_reg &= ~(CDNS_SPI_CR_CPHA_MASK | CDNS_SPI_CR_CPOL_MASK);
+ new_ctrl_reg &= ~(CDNS_SPI_CR_CPHA_MASK | CDNS_SPI_CR_CPOL_MASK);
if (spi->mode & SPI_CPHA)
- ctrl_reg |= CDNS_SPI_CR_CPHA_MASK;
+ new_ctrl_reg |= CDNS_SPI_CR_CPHA_MASK;
if (spi->mode & SPI_CPOL)
- ctrl_reg |= CDNS_SPI_CR_CPOL_MASK;
-
- cdns_spi_write(xspi, CDNS_SPI_CR_OFFSET, ctrl_reg);
+ new_ctrl_reg |= CDNS_SPI_CR_CPOL_MASK;
+
+ if (new_ctrl_reg != ctrl_reg) {
+ /*
+ * Just writing the CR register does not seem to apply the clock
+ * setting changes. This is problematic when changing the clock
+ * polarity as it will cause the SPI slave to see spurious clock
+ * transitions. To workaround the issue toggle the ER register.
+ */
+ cdns_spi_write(xspi, CDNS_SPI_ER_OFFSET,
+ CDNS_SPI_ER_DISABLE_MASK);
+ cdns_spi_write(xspi, CDNS_SPI_CR_OFFSET, new_ctrl_reg);
+ cdns_spi_write(xspi, CDNS_SPI_ER_OFFSET,
+ CDNS_SPI_ER_ENABLE_MASK);
+ }
}
/**
@@ -370,6 +382,12 @@ static irqreturn_t cdns_spi_irq(int irq, void *dev_id)
return status;
}
+static int cdns_prepare_message(struct spi_master *master,
+ struct spi_message *msg)
+{
+ cdns_spi_config_clock_mode(msg->spi);
+ return 0;
+}
/**
* cdns_transfer_one - Initiates the SPI transfer
@@ -416,8 +434,6 @@ static int cdns_prepare_transfer_hardware(struct spi_master *master)
{
struct cdns_spi *xspi = spi_master_get_devdata(master);
- cdns_spi_config_clock_mode(master->cur_msg->spi);
-
cdns_spi_write(xspi, CDNS_SPI_ER_OFFSET,
CDNS_SPI_ER_ENABLE_MASK);
@@ -532,6 +548,7 @@ static int cdns_spi_probe(struct platform_device *pdev)
xspi->is_decoded_cs = 0;
master->prepare_transfer_hardware = cdns_prepare_transfer_hardware;
+ master->prepare_message = cdns_prepare_message;
master->transfer_one = cdns_transfer_one;
master->unprepare_transfer_hardware = cdns_unprepare_transfer_hardware;
master->set_cs = cdns_spi_chipselect;
@@ -647,7 +664,7 @@ static int __maybe_unused cdns_spi_resume(struct device *dev)
static SIMPLE_DEV_PM_OPS(cdns_spi_dev_pm_ops, cdns_spi_suspend,
cdns_spi_resume);
-static struct of_device_id cdns_spi_of_match[] = {
+static const struct of_device_id cdns_spi_of_match[] = {
{ .compatible = "xlnx,zynq-spi-r1p6" },
{ .compatible = "cdns,spi-r1p6" },
{ /* end of table */ }
OpenPOWER on IntegriCloud