From patchwork Sat Nov 8 10:29:49 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mark Brown X-Patchwork-Id: 5256471 Return-Path: X-Original-To: patchwork-linux-spi@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 5C3159F2F1 for ; Sat, 8 Nov 2014 10:30:26 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 63DDA2012E for ; Sat, 8 Nov 2014 10:30:25 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 7A87720122 for ; Sat, 8 Nov 2014 10:30:24 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753486AbaKHKaV (ORCPT ); Sat, 8 Nov 2014 05:30:21 -0500 Received: from mezzanine.sirena.org.uk ([106.187.55.193]:51621 "EHLO mezzanine.sirena.org.uk" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753476AbaKHKaU (ORCPT ); Sat, 8 Nov 2014 05:30:20 -0500 Received: from 188.29.164.249.threembb.co.uk ([188.29.164.249] helo=finisterre) by mezzanine.sirena.org.uk with esmtpsa (TLS1.2:RSA_AES_128_CBC_SHA1:128) (Exim 4.80) (envelope-from ) id 1Xn3HS-0002p8-GB; Sat, 08 Nov 2014 10:30:16 +0000 Received: from broonie by finisterre with local (Exim 4.84) (envelope-from ) id 1Xn3HE-0007fN-KI; Sat, 08 Nov 2014 10:29:52 +0000 From: Mark Brown To: Thor Thayer Cc: linux-spi@vger.kernel.org, linux-kernel@vger.kernel.org, Mark Brown Date: Sat, 8 Nov 2014 10:29:49 +0000 Message-Id: <1415442589-29434-1-git-send-email-broonie@kernel.org> X-Mailer: git-send-email 2.1.1 X-SA-Exim-Connect-IP: 188.29.164.249 X-SA-Exim-Mail-From: broonie@sirena.org.uk X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Spam-Level: X-Spam-Status: No, score=-7.5 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 Subject: [PATCH] spi: spidev: Don't mangle max_speed_hz in underlying spi device X-SA-Exim-Version: 4.2.1 (built Mon, 26 Dec 2011 16:24:06 +0000) X-SA-Exim-Scanned: Yes (on mezzanine.sirena.org.uk) Sender: linux-spi-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-spi@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP 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 --- I've not tested this at all yet. drivers/spi/spidev.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/drivers/spi/spidev.c b/drivers/spi/spidev.c index e50039f..42239fd 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); @@ -274,6 +275,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 +380,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 */ @@ -442,9 +445,10 @@ 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; + spidev->speed_hz = tmp; else dev_dbg(&spi->dev, "%d Hz (max)\n", tmp); + spi->max_speed_hz = save; } break; @@ -570,6 +574,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 +656,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