From patchwork Fri Jun 2 11:57:30 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Rasmus Villemoes X-Patchwork-Id: 13265202 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 7395DC7EE29 for ; Fri, 2 Jun 2023 11:58:23 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235595AbjFBL6V (ORCPT ); Fri, 2 Jun 2023 07:58:21 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45974 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235123AbjFBL6U (ORCPT ); Fri, 2 Jun 2023 07:58:20 -0400 Received: from mail-lf1-x12c.google.com (mail-lf1-x12c.google.com [IPv6:2a00:1450:4864:20::12c]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id E9029E73 for ; Fri, 2 Jun 2023 04:57:51 -0700 (PDT) Received: by mail-lf1-x12c.google.com with SMTP id 2adb3069b0e04-4f3a99b9177so2689977e87.1 for ; Fri, 02 Jun 2023 04:57:51 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=rasmusvillemoes.dk; s=google; t=1685707054; x=1688299054; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:from:to:cc:subject:date:message-id:reply-to; bh=evrwcymqMNKTbAB9nnVcN2soWGAlTnOdSH5Owxy9OYQ=; b=EdZFtjCv0OOg290UqgCv24tqwEyrrNi3aaROlD2uMvEhdZj5TBD7sET7MpjcTA4v+n lBObkojN9igzCLsZp4AfqDTO5FwE+JE77ByU7wKckHKYQg62f2f1fDAjk9Xt7CIQP8+Y HS8cPT2m6rzhoImXthNDxpX3rzRLYZJxe33Vo= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1685707054; x=1688299054; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=evrwcymqMNKTbAB9nnVcN2soWGAlTnOdSH5Owxy9OYQ=; b=gOUdljJU+hYt99aqorY7gR2oQ9YnRt2ccM4lvtiHd67ccc7/cZMITE2sAxBe4aTIeS /qHCxoKE9aPnaWQoI07kCTuCyXZS56bXwQpShprsAY2TTliWNO4YttDuJ65ZYOmtNPTE NKJEKLn4gfnIRVHL7NVd+fYCWkF/U5tpOKODEb11GM8P4dhPDMIp5BbcvvdkPPFBgp+u zQEFm3NCxrZpJhbKTIeNGdFlXOugOj9Mzcgrzfb+1hh/5SfvZZ/II+8XMPraLeQ9lK7s 9mLyiJ8Hz90vm3xuHIAM62LPSpXUOnbHmj1VADzYOjnA/V+ohy4g3Eyk5crVmui8Aldt Q34A== X-Gm-Message-State: AC+VfDznAekN7Wp3zIJpqjynU0RFlP4ypiyEcKPwUMt6uYS/m8MFdako f59KZRPvD3BgSB7BwhSZ28EMMQ== X-Google-Smtp-Source: ACHHUZ5V3Nt2S6IKerF7pPam5XtnNoVjNy9QC/LXBJc5lXRLxmZTqM8KDhn3IwFNGNvt3Fh8ShpeTw== X-Received: by 2002:ac2:4831:0:b0:4f3:b9b1:5683 with SMTP id 17-20020ac24831000000b004f3b9b15683mr1706934lft.62.1685707054242; Fri, 02 Jun 2023 04:57:34 -0700 (PDT) Received: from prevas-ravi.prevas.se ([81.216.59.226]) by smtp.gmail.com with ESMTPSA id e20-20020ac25474000000b004db0d26adb4sm140316lfn.182.2023.06.02.04.57.33 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 02 Jun 2023 04:57:33 -0700 (PDT) From: Rasmus Villemoes To: Mark Brown , Shawn Guo , Sascha Hauer , Pengutronix Kernel Team , Fabio Estevam , NXP Linux Team Cc: Boerge Struempfel , "Mahapatra, Amit Kumar" , Rasmus Villemoes , linux-spi@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org Subject: [PATCH v2] spi: spi-imx: fix mixing of native and gpio chipselects for imx51/imx53/imx6 variants Date: Fri, 2 Jun 2023 13:57:30 +0200 Message-Id: <20230602115731.708883-1-linux@rasmusvillemoes.dk> X-Mailer: git-send-email 2.37.2 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-spi@vger.kernel.org Commit 87c614175bbf (spi: spi-imx: fix MX51_ECSPI_* macros when cs > 3) ensured that the argument passed to the macros was masked with &3, so that we no longer write outside the intended fields in the various control registers. When all chip selects are gpios, this works just fine. However, when a mix of native and gpio chip selects are in use, that masking is too naive. Say, for example, that SS0 is muxed as native chip select, and there is also a chip at 4 (obviously with a gpio cs). In that case, when accessing the latter chip, both the SS0 pin and the gpio pin will be asserted low. The fix for this is to use the ->unused_native_cs value as channel number for any spi device which uses a gpio as chip select. Signed-off-by: Rasmus Villemoes --- Previous submission: https://lore.kernel.org/lkml/20230425134527.483607-1-linux@rasmusvillemoes.dk/ The first two patches have already been applied in -next. This adapts 3/3 to -next as of next-20230602, taking both 6a983ff5102f and 9e264f3f85a5 into account. drivers/spi/spi-imx.c | 35 ++++++++++++++++++++++------------- 1 file changed, 22 insertions(+), 13 deletions(-) diff --git a/drivers/spi/spi-imx.c b/drivers/spi/spi-imx.c index 6f4d3cb81fdf..528ae46c087f 100644 --- a/drivers/spi/spi-imx.c +++ b/drivers/spi/spi-imx.c @@ -517,6 +517,13 @@ static void mx51_ecspi_disable(struct spi_imx_data *spi_imx) writel(ctrl, spi_imx->base + MX51_ECSPI_CTRL); } +static int mx51_ecspi_channel(const struct spi_device *spi) +{ + if (!spi_get_csgpiod(spi, 0)) + return spi_get_chipselect(spi, 0); + return spi->controller->unused_native_cs; +} + static int mx51_ecspi_prepare_message(struct spi_imx_data *spi_imx, struct spi_message *msg) { @@ -527,6 +534,7 @@ static int mx51_ecspi_prepare_message(struct spi_imx_data *spi_imx, u32 testreg, delay; u32 cfg = readl(spi_imx->base + MX51_ECSPI_CONFIG); u32 current_cfg = cfg; + int channel = mx51_ecspi_channel(spi); /* set Master or Slave mode */ if (spi_imx->slave_mode) @@ -541,7 +549,7 @@ static int mx51_ecspi_prepare_message(struct spi_imx_data *spi_imx, ctrl |= MX51_ECSPI_CTRL_DRCTL(spi_imx->spi_drctl); /* set chip select to use */ - ctrl |= MX51_ECSPI_CTRL_CS(spi_get_chipselect(spi, 0)); + ctrl |= MX51_ECSPI_CTRL_CS(channel); /* * The ctrl register must be written first, with the EN bit set other @@ -562,27 +570,27 @@ static int mx51_ecspi_prepare_message(struct spi_imx_data *spi_imx, * BURST_LENGTH + 1 bits are received */ if (spi_imx->slave_mode && is_imx53_ecspi(spi_imx)) - cfg &= ~MX51_ECSPI_CONFIG_SBBCTRL(spi_get_chipselect(spi, 0)); + cfg &= ~MX51_ECSPI_CONFIG_SBBCTRL(channel); else - cfg |= MX51_ECSPI_CONFIG_SBBCTRL(spi_get_chipselect(spi, 0)); + cfg |= MX51_ECSPI_CONFIG_SBBCTRL(channel); if (spi->mode & SPI_CPOL) { - cfg |= MX51_ECSPI_CONFIG_SCLKPOL(spi_get_chipselect(spi, 0)); - cfg |= MX51_ECSPI_CONFIG_SCLKCTL(spi_get_chipselect(spi, 0)); + cfg |= MX51_ECSPI_CONFIG_SCLKPOL(channel); + cfg |= MX51_ECSPI_CONFIG_SCLKCTL(channel); } else { - cfg &= ~MX51_ECSPI_CONFIG_SCLKPOL(spi_get_chipselect(spi, 0)); - cfg &= ~MX51_ECSPI_CONFIG_SCLKCTL(spi_get_chipselect(spi, 0)); + cfg &= ~MX51_ECSPI_CONFIG_SCLKPOL(channel); + cfg &= ~MX51_ECSPI_CONFIG_SCLKCTL(channel); } if (spi->mode & SPI_MOSI_IDLE_LOW) - cfg |= MX51_ECSPI_CONFIG_DATACTL(spi_get_chipselect(spi, 0)); + cfg |= MX51_ECSPI_CONFIG_DATACTL(channel); else - cfg &= ~MX51_ECSPI_CONFIG_DATACTL(spi_get_chipselect(spi, 0)); + cfg &= ~MX51_ECSPI_CONFIG_DATACTL(channel); if (spi->mode & SPI_CS_HIGH) - cfg |= MX51_ECSPI_CONFIG_SSBPOL(spi_get_chipselect(spi, 0)); + cfg |= MX51_ECSPI_CONFIG_SSBPOL(channel); else - cfg &= ~MX51_ECSPI_CONFIG_SSBPOL(spi_get_chipselect(spi, 0)); + cfg &= ~MX51_ECSPI_CONFIG_SSBPOL(channel); if (cfg == current_cfg) return 0; @@ -627,14 +635,15 @@ static void mx51_configure_cpha(struct spi_imx_data *spi_imx, bool cpha = (spi->mode & SPI_CPHA); bool flip_cpha = (spi->mode & SPI_RX_CPHA_FLIP) && spi_imx->rx_only; u32 cfg = readl(spi_imx->base + MX51_ECSPI_CONFIG); + int channel = mx51_ecspi_channel(spi); /* Flip cpha logical value iff flip_cpha */ cpha ^= flip_cpha; if (cpha) - cfg |= MX51_ECSPI_CONFIG_SCLKPHA(spi_get_chipselect(spi, 0)); + cfg |= MX51_ECSPI_CONFIG_SCLKPHA(channel); else - cfg &= ~MX51_ECSPI_CONFIG_SCLKPHA(spi_get_chipselect(spi, 0)); + cfg &= ~MX51_ECSPI_CONFIG_SCLKPHA(channel); writel(cfg, spi_imx->base + MX51_ECSPI_CONFIG); }