From patchwork Tue Apr 12 11:56:25 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ben Hutchings X-Patchwork-Id: 8809721 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.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 017469F39A for ; Tue, 12 Apr 2016 11:56:33 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 267BB201C8 for ; Tue, 12 Apr 2016 11:56:32 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 34E7D2035B for ; Tue, 12 Apr 2016 11:56:31 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755991AbcDLL4a (ORCPT ); Tue, 12 Apr 2016 07:56:30 -0400 Received: from ducie-dc1.codethink.co.uk ([185.25.241.215]:48070 "EHLO ducie-dc1.codethink.co.uk" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755868AbcDLL4a (ORCPT ); Tue, 12 Apr 2016 07:56:30 -0400 Received: from localhost (localhost [127.0.0.1]) by ducie-dc1.codethink.co.uk (Postfix) with ESMTP id A93984620C4; Tue, 12 Apr 2016 12:56:28 +0100 (BST) X-Virus-Scanned: Debian amavisd-new at ducie-dc1.codethink.co.uk Received: from ducie-dc1.codethink.co.uk ([127.0.0.1]) by localhost (ducie-dc1.codethink.co.uk [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id KujrhZ-5eMXa; Tue, 12 Apr 2016 12:56:27 +0100 (BST) Received: from xylophone (shadbolt.e.decadent.org.uk [88.96.1.126]) by ducie-dc1.codethink.co.uk (Postfix) with ESMTPSA id B08FE46221C; Tue, 12 Apr 2016 12:56:26 +0100 (BST) Message-ID: <1460462185.32355.7.camel@codethink.co.uk> Subject: [PATCH v2 1/2] spi: spi-ti-qspi: Fix FLEN and WLEN settings if bits_per_word is overridden From: Ben Hutchings To: Mark Brown Cc: linux-spi@vger.kernel.org, CT kernel Date: Tue, 12 Apr 2016 12:56:25 +0100 Organization: Codethink Ltd. X-Mailer: Evolution 3.12.9-1+b1 Mime-Version: 1.0 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.9 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 Each transfer can specify 8, 16 or 32 bits per word independently of the default for the device being addressed. However, currently we calculate the number of words in the frame assuming that the word size is the device default. If multiple transfers in the same message have differing bits_per_word, we bitwise-or the different values in the WLEN register field. Fix both of these. Also rename 'frame_length' to 'frame_len_words' to make clear that it's not a byte count like spi_message::frame_length. Cc: stable@vger.kernel.org Signed-off-by: Ben Hutchings --- v2: Rename frame_length to frame_len_words; improve commit message. drivers/spi/spi-ti-qspi.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/drivers/spi/spi-ti-qspi.c b/drivers/spi/spi-ti-qspi.c index 64318fcfacf2..2137f2112804 100644 --- a/drivers/spi/spi-ti-qspi.c +++ b/drivers/spi/spi-ti-qspi.c @@ -94,6 +94,7 @@ struct ti_qspi { #define QSPI_FLEN(n) ((n - 1) << 0) #define QSPI_WLEN_MAX_BITS 128 #define QSPI_WLEN_MAX_BYTES 16 +#define QSPI_WLEN_MASK QSPI_WLEN(QSPI_WLEN_MAX_BITS) /* STATUS REGISTER */ #define BUSY 0x01 @@ -373,7 +374,7 @@ static int ti_qspi_start_transfer_one(struct spi_master *master, struct spi_device *spi = m->spi; struct spi_transfer *t; int status = 0, ret; - int frame_length; + unsigned int frame_len_words; /* setup device control reg */ qspi->dc = 0; @@ -385,21 +386,23 @@ static int ti_qspi_start_transfer_one(struct spi_master *master, if (spi->mode & SPI_CS_HIGH) qspi->dc |= QSPI_CSPOL(spi->chip_select); - frame_length = (m->frame_length << 3) / spi->bits_per_word; - - frame_length = clamp(frame_length, 0, QSPI_FRAME); + frame_len_words = 0; + list_for_each_entry(t, &m->transfers, transfer_list) + frame_len_words += t->len / (t->bits_per_word >> 3); + frame_len_words = min_t(unsigned int, frame_len_words, QSPI_FRAME); /* setup command reg */ qspi->cmd = 0; qspi->cmd |= QSPI_EN_CS(spi->chip_select); - qspi->cmd |= QSPI_FLEN(frame_length); + qspi->cmd |= QSPI_FLEN(frame_len_words); ti_qspi_write(qspi, qspi->dc, QSPI_SPI_DC_REG); mutex_lock(&qspi->list_lock); list_for_each_entry(t, &m->transfers, transfer_list) { - qspi->cmd |= QSPI_WLEN(t->bits_per_word); + qspi->cmd = ((qspi->cmd & ~QSPI_WLEN_MASK) | + QSPI_WLEN(t->bits_per_word)); ret = qspi_transfer_msg(qspi, t); if (ret) {