aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/spi/spidev.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-12-11 12:03:34 -0800
committerLinus Torvalds <torvalds@linux-foundation.org>2014-12-11 12:03:34 -0800
commitb859e7d13bcc18b56faa7e2f78db5ba8ab874a15 (patch)
tree2762ac481bc2b2a472832473b888fff3d7d9b9d4 /drivers/spi/spidev.c
parentMerge tag 'edac/v3.19-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-edac (diff)
parentMerge remote-tracking branches 'spi/topic/spidev' and 'spi/topic/txx9' into spi-next (diff)
downloadlinux-dev-b859e7d13bcc18b56faa7e2f78db5ba8ab874a15.tar.xz
linux-dev-b859e7d13bcc18b56faa7e2f78db5ba8ab874a15.zip
Merge tag 'spi-v3.19' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi
Pull spi updates from Mark Brown: "Not a huge amount going on this release, mainly new drivers (there's a couple more waiting that didn't quite make the cut for this release too): - An interface for querying if the current transfer is the last in a message, allowing controllers that need special handling for the final transfer to use the core message parsing. - Support for Amlogic Meson SPIFC, Imagination Technologies SFPI, Intel Quark X1000 and Samsung Exynos 7 controllers" * tag 'spi-v3.19' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi: (38 commits) spi/s3c64xx: Remove redundant runtime PM management spi: fsl-spi: remove unused variable assignment spi: spi-fsl-spi: Return an error code in fsl_spi_do_one_msg() spi: core: Do not mangle error code from kthread_run() spi: fsl-espi: add (un)prepare_transfer_hardware calls to save power if SPI is not in use spi: fsl-(e)spi: migrate to generic master queueing spi/txx9: Deletion of an unnecessary check before the function call "clk_disable" spi: cadence: Fix 3-to-8 mux mode spi: cadence: Init HW after reading devicetree attributes spi: meson: Select REGMAP_MMIO spi: s3c64xx: add support for exynos7 SPI controller spi: spi-pxa2xx: SPI support for Intel Quark X1000 spi: meson: meson_spifc_setup_speed() can be static spi: spi-pxa2xx: Add helpers for regiseters' accessing spi: spi-mxs: Fix mapping from vmalloc-ed buffer to scatter list spi: atmel: introduce probe deferring spi: atmel: remove compat for non DT board when requesting dma chan spi: meson: Add support for Amlogic Meson SPIFC spi: meson: Add device tree bindings documentation for SPIFC spi: core: Add spi_transfer_is_last() helper ...
Diffstat (limited to 'drivers/spi/spidev.c')
-rw-r--r--drivers/spi/spidev.c16
1 files changed, 13 insertions, 3 deletions
diff --git a/drivers/spi/spidev.c b/drivers/spi/spidev.c
index e50039fb1474..6941e04afb8c 100644
--- a/drivers/spi/spidev.c
+++ b/drivers/spi/spidev.c
@@ -87,6 +87,7 @@ struct spidev_data {
unsigned users;
u8 *tx_buffer;
u8 *rx_buffer;
+ u32 speed_hz;
};
static LIST_HEAD(device_list);
@@ -138,6 +139,7 @@ spidev_sync_write(struct spidev_data *spidev, size_t len)
struct spi_transfer t = {
.tx_buf = spidev->tx_buffer,
.len = len,
+ .speed_hz = spidev->speed_hz,
};
struct spi_message m;
@@ -152,6 +154,7 @@ spidev_sync_read(struct spidev_data *spidev, size_t len)
struct spi_transfer t = {
.rx_buf = spidev->rx_buffer,
.len = len,
+ .speed_hz = spidev->speed_hz,
};
struct spi_message m;
@@ -274,6 +277,8 @@ static int spidev_message(struct spidev_data *spidev,
k_tmp->bits_per_word = u_tmp->bits_per_word;
k_tmp->delay_usecs = u_tmp->delay_usecs;
k_tmp->speed_hz = u_tmp->speed_hz;
+ if (!k_tmp->speed_hz)
+ k_tmp->speed_hz = spidev->speed_hz;
#ifdef VERBOSE
dev_dbg(&spidev->spi->dev,
" xfer len %zd %s%s%s%dbits %u usec %uHz\n",
@@ -377,7 +382,7 @@ spidev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
retval = __put_user(spi->bits_per_word, (__u8 __user *)arg);
break;
case SPI_IOC_RD_MAX_SPEED_HZ:
- retval = __put_user(spi->max_speed_hz, (__u32 __user *)arg);
+ retval = __put_user(spidev->speed_hz, (__u32 __user *)arg);
break;
/* write requests */
@@ -441,10 +446,11 @@ spidev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
spi->max_speed_hz = tmp;
retval = spi_setup(spi);
- if (retval < 0)
- spi->max_speed_hz = save;
+ if (retval >= 0)
+ spidev->speed_hz = tmp;
else
dev_dbg(&spi->dev, "%d Hz (max)\n", tmp);
+ spi->max_speed_hz = save;
}
break;
@@ -570,6 +576,8 @@ static int spidev_release(struct inode *inode, struct file *filp)
kfree(spidev->rx_buffer);
spidev->rx_buffer = NULL;
+ spidev->speed_hz = spidev->spi->max_speed_hz;
+
/* ... after we unbound from the underlying device? */
spin_lock_irq(&spidev->spi_lock);
dofree = (spidev->spi == NULL);
@@ -650,6 +658,8 @@ static int spidev_probe(struct spi_device *spi)
}
mutex_unlock(&device_list_lock);
+ spidev->speed_hz = spi->max_speed_hz;
+
if (status == 0)
spi_set_drvdata(spi, spidev);
else