From 9169051617df7fca597274e9e43324332cb8f0ee Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Sat, 8 Nov 2014 10:28:10 +0000 Subject: spi: spidev: Don't mangle max_speed_hz in underlying spi device Currently spidev allows callers to set the default speed by overriding the max_speed_hz in the underlying device. This achieves the immediate goal but is not what devices expect and can easily lead to userspace trying to set unsupported speeds and succeeding, apart from anything else drivers can't set a limit on the speed using max_speed_hz as they'd expect and any other devices on the bus will be affected. Instead store the default speed in the spidev struct and fill this in on each transfer. Signed-off-by: Mark Brown --- drivers/spi/spidev.c | 16 +++++++++++++--- 1 file 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 -- cgit v1.2.3-59-g8ed1b From 7d57cd8946f21db2194154af1b95238af8579f9e Mon Sep 17 00:00:00 2001 From: Markus Elfring Date: Sat, 29 Nov 2014 18:34:20 +0100 Subject: spi/txx9: Deletion of an unnecessary check before the function call "clk_disable" The clk_disable() function tests whether its argument is NULL and then returns immediately. Thus the test around the call is not needed. This issue was detected by using the Coccinelle software. Signed-off-by: Markus Elfring Signed-off-by: Mark Brown --- drivers/spi/spi-txx9.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/spi/spi-txx9.c b/drivers/spi/spi-txx9.c index 2501a8373e89..f2ab827c81bb 100644 --- a/drivers/spi/spi-txx9.c +++ b/drivers/spi/spi-txx9.c @@ -402,8 +402,7 @@ exit_busy: exit: if (c->workqueue) destroy_workqueue(c->workqueue); - if (c->clk) - clk_disable(c->clk); + clk_disable(c->clk); spi_master_put(master); return ret; } -- cgit v1.2.3-59-g8ed1b