From patchwork Thu Nov 6 19:54:27 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: tthayer@opensource.altera.com X-Patchwork-Id: 5246571 Return-Path: X-Original-To: patchwork-linux-spi@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 7C7ADC11AC for ; Thu, 6 Nov 2014 19:54:20 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id A70592011E for ; Thu, 6 Nov 2014 19:54:19 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 9F89B2011D for ; Thu, 6 Nov 2014 19:54:18 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751278AbaKFTyS (ORCPT ); Thu, 6 Nov 2014 14:54:18 -0500 Received: from mail-bn1bon0094.outbound.protection.outlook.com ([157.56.111.94]:4344 "EHLO na01-bn1-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1751133AbaKFTyR (ORCPT ); Thu, 6 Nov 2014 14:54:17 -0500 Received: from dinh-ubuntu.altera.com (64.129.157.38) by BLUPR03MB120.namprd03.prod.outlook.com (10.255.212.26) with Microsoft SMTP Server (TLS) id 15.1.11.14; Thu, 6 Nov 2014 19:54:04 +0000 From: To: CC: , , , , , Thor Thayer Subject: [PATCHv2] spi: dw: Fix dynamic speed change. Date: Thu, 6 Nov 2014 13:54:27 -0600 Message-ID: <1415303667-31584-1-git-send-email-tthayer@opensource.altera.com> X-Mailer: git-send-email 1.7.9.5 MIME-Version: 1.0 X-Originating-IP: [64.129.157.38] X-ClientProxiedBy: DB4PR04CA0021.eurprd04.prod.outlook.com (25.160.41.31) To BLUPR03MB120.namprd03.prod.outlook.com (10.255.212.26) X-MS-Exchange-Transport-FromEntityHeader: Hosted X-Microsoft-Antispam: UriScan:; X-Microsoft-Antispam: BCL:0;PCL:0;RULEID:;SRVR:BLUPR03MB120; X-Exchange-Antispam-Report-Test: UriScan:; X-Forefront-PRVS: 0387D64A71 X-Forefront-Antispam-Report: SFV:NSPM; SFS:(10009020)(6009001)(199003)(189002)(87976001)(50226001)(48376002)(69596002)(33646002)(575784001)(110136001)(66066001)(64706001)(77096003)(86362001)(20776003)(19580405001)(104166001)(50466002)(77156002)(62966003)(89996001)(87286001)(31966008)(40100003)(93916002)(88136002)(86152002)(50986999)(47776003)(4396001)(46102003)(99396003)(120916001)(97736003)(92726001)(81156004)(92566001)(229853001)(101416001)(21056001)(19580395003)(106356001)(2351001)(122386002)(105586002)(102836001)(551934003)(53416004)(95666004)(107046002)(42186005); DIR:OUT; SFP:1101; SCL:1; SRVR:BLUPR03MB120; H:dinh-ubuntu.altera.com; FPR:; MLV:sfv; PTR:InfoNoRecords; A:0; MX:1; LANG:en; X-OriginatorOrg: opensource.altera.com Sender: linux-spi-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-spi@vger.kernel.org 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 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Thor Thayer An IOCTL call that calls spi_setup() and then dw_spi_setup() will overwrite the persisted last transfer speed. On each transfer, the SPI speed is compared to the last transfer speed to determine if the clock divider registers need to be updated (did the speed change?). This bug was observed with the spidev driver using spi-config to update the max transfer speed. This fix: Don't overwrite the persisted last transaction clock speed when updating the SPI parameters in dw_spi_setup(). On the next transaction, the new speed won't match the persisted last speed and the hardware registers will be updated. On initialization, the persisted last transaction clock speed will be 0 but will be updated after the first SPI transaction. Move zeroed clock divider check into clock change test because chip->clk_div is zero on startup and would cause a divide-by-zero error. The calculation was wrong as well (can't support odd #). Reported-by: Vlastimil Setka Signed-off-by: Vlastimil Setka Signed-off-by: Thor Thayer --- v2: Simplify fix so that last persistent SPI transfer speed is not overwritten. --- drivers/spi/spi-dw.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/drivers/spi/spi-dw.c b/drivers/spi/spi-dw.c index 72e12ba..d0d5542 100644 --- a/drivers/spi/spi-dw.c +++ b/drivers/spi/spi-dw.c @@ -376,9 +376,6 @@ static void pump_transfers(unsigned long data) chip = dws->cur_chip; spi = message->spi; - if (unlikely(!chip->clk_div)) - chip->clk_div = dws->max_freq / chip->speed_hz; - if (message->state == ERROR_STATE) { message->status = -EIO; goto early_exit; @@ -419,7 +416,7 @@ static void pump_transfers(unsigned long data) if (transfer->speed_hz) { speed = chip->speed_hz; - if (transfer->speed_hz != speed) { + if ((transfer->speed_hz != speed) || (!chip->clk_div)) { speed = transfer->speed_hz; /* clk_div doesn't support odd number */ @@ -581,7 +578,6 @@ static int dw_spi_setup(struct spi_device *spi) dev_err(&spi->dev, "No max speed HZ parameter\n"); return -EINVAL; } - chip->speed_hz = spi->max_speed_hz; chip->tmode = 0; /* Tx & Rx */ /* Default SPI mode is SCPOL = 0, SCPH = 0 */