aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMark Brown <broonie@kernel.org>2014-11-08 05:28:10 -0500
committerMark Brown <broonie@kernel.org>2014-11-11 13:01:28 -0500
commit9169051617df7fca597274e9e43324332cb8f0ee (patch)
treeb5d32017b56bb8566d30dbb359c7b9948f94e720
parent0df1f2487d2f0d04703f142813d53615d62a1da4 (diff)
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 <broonie@kernel.org>
-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 {
87 unsigned users; 87 unsigned users;
88 u8 *tx_buffer; 88 u8 *tx_buffer;
89 u8 *rx_buffer; 89 u8 *rx_buffer;
90 u32 speed_hz;
90}; 91};
91 92
92static LIST_HEAD(device_list); 93static LIST_HEAD(device_list);
@@ -138,6 +139,7 @@ spidev_sync_write(struct spidev_data *spidev, size_t len)
138 struct spi_transfer t = { 139 struct spi_transfer t = {
139 .tx_buf = spidev->tx_buffer, 140 .tx_buf = spidev->tx_buffer,
140 .len = len, 141 .len = len,
142 .speed_hz = spidev->speed_hz,
141 }; 143 };
142 struct spi_message m; 144 struct spi_message m;
143 145
@@ -152,6 +154,7 @@ spidev_sync_read(struct spidev_data *spidev, size_t len)
152 struct spi_transfer t = { 154 struct spi_transfer t = {
153 .rx_buf = spidev->rx_buffer, 155 .rx_buf = spidev->rx_buffer,
154 .len = len, 156 .len = len,
157 .speed_hz = spidev->speed_hz,
155 }; 158 };
156 struct spi_message m; 159 struct spi_message m;
157 160
@@ -274,6 +277,8 @@ static int spidev_message(struct spidev_data *spidev,
274 k_tmp->bits_per_word = u_tmp->bits_per_word; 277 k_tmp->bits_per_word = u_tmp->bits_per_word;
275 k_tmp->delay_usecs = u_tmp->delay_usecs; 278 k_tmp->delay_usecs = u_tmp->delay_usecs;
276 k_tmp->speed_hz = u_tmp->speed_hz; 279 k_tmp->speed_hz = u_tmp->speed_hz;
280 if (!k_tmp->speed_hz)
281 k_tmp->speed_hz = spidev->speed_hz;
277#ifdef VERBOSE 282#ifdef VERBOSE
278 dev_dbg(&spidev->spi->dev, 283 dev_dbg(&spidev->spi->dev,
279 " xfer len %zd %s%s%s%dbits %u usec %uHz\n", 284 " 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)
377 retval = __put_user(spi->bits_per_word, (__u8 __user *)arg); 382 retval = __put_user(spi->bits_per_word, (__u8 __user *)arg);
378 break; 383 break;
379 case SPI_IOC_RD_MAX_SPEED_HZ: 384 case SPI_IOC_RD_MAX_SPEED_HZ:
380 retval = __put_user(spi->max_speed_hz, (__u32 __user *)arg); 385 retval = __put_user(spidev->speed_hz, (__u32 __user *)arg);
381 break; 386 break;
382 387
383 /* write requests */ 388 /* write requests */
@@ -441,10 +446,11 @@ spidev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
441 446
442 spi->max_speed_hz = tmp; 447 spi->max_speed_hz = tmp;
443 retval = spi_setup(spi); 448 retval = spi_setup(spi);
444 if (retval < 0) 449 if (retval >= 0)
445 spi->max_speed_hz = save; 450 spidev->speed_hz = tmp;
446 else 451 else
447 dev_dbg(&spi->dev, "%d Hz (max)\n", tmp); 452 dev_dbg(&spi->dev, "%d Hz (max)\n", tmp);
453 spi->max_speed_hz = save;
448 } 454 }
449 break; 455 break;
450 456
@@ -570,6 +576,8 @@ static int spidev_release(struct inode *inode, struct file *filp)
570 kfree(spidev->rx_buffer); 576 kfree(spidev->rx_buffer);
571 spidev->rx_buffer = NULL; 577 spidev->rx_buffer = NULL;
572 578
579 spidev->speed_hz = spidev->spi->max_speed_hz;
580
573 /* ... after we unbound from the underlying device? */ 581 /* ... after we unbound from the underlying device? */
574 spin_lock_irq(&spidev->spi_lock); 582 spin_lock_irq(&spidev->spi_lock);
575 dofree = (spidev->spi == NULL); 583 dofree = (spidev->spi == NULL);
@@ -650,6 +658,8 @@ static int spidev_probe(struct spi_device *spi)
650 } 658 }
651 mutex_unlock(&device_list_lock); 659 mutex_unlock(&device_list_lock);
652 660
661 spidev->speed_hz = spi->max_speed_hz;
662
653 if (status == 0) 663 if (status == 0)
654 spi_set_drvdata(spi, spidev); 664 spi_set_drvdata(spi, spidev);
655 else 665 else