From patchwork Mon Feb 19 22:33:19 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Lechner X-Patchwork-Id: 203295 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:693c:2685:b0:108:e6aa:91d0 with SMTP id mn5csp73392dyc; Mon, 19 Feb 2024 14:36:01 -0800 (PST) X-Forwarded-Encrypted: i=3; AJvYcCUusKVwF1B1zPjM4RX7cVbMGo9uBG2J51PFku3vJfOLskXfsxZzaDTVT/S3le3JJ1OtkCzA03YnSavgAnDb6pgxhzUnFA== X-Google-Smtp-Source: AGHT+IFV85XZL+hglJ55PP7cnhYK4j7rNvpctBsEzkKtbwGPAuqkMlrF3UFB9pB9+gLAb8t36q9z X-Received: by 2002:a25:bccf:0:b0:dc7:45f4:44f7 with SMTP id l15-20020a25bccf000000b00dc745f444f7mr9144172ybm.14.1708382161086; Mon, 19 Feb 2024 14:36:01 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1708382161; cv=pass; d=google.com; s=arc-20160816; b=VvzOMHo4ekfXo1mT9/iwkB2i690FH9+kJTOGvsEubXW4Lu8v30JYeZWrO95dYN3E60 p8pVfZlqYtjFIG/IBpAtzX0kUMKGnKB+b98Eg8nyu2G3shsKqTlzog3jtNpF7GfNvCa6 hZ1cI7c67xCjWXghmVv5IF3zJVyAo2d+GPsMfF5bTTJG2GcdSPEZ0u3mZvqH1gg8QTnh hEptTQXWJO0xN0vJTkMHGbROZUfeCtt85nOFHlnCSelvD61UAO8sVOKNWxoDhwk/qYH7 /e+OTHYPNnVBgrb/mZjDOWOGmgBv8pRqwhLWNZnhHM0jSReUxsw58jzfBZDBmI8f0u0m qTXw== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=content-transfer-encoding:mime-version:list-unsubscribe :list-subscribe:list-id:precedence:references:in-reply-to:message-id :date:subject:cc:to:from:dkim-signature; bh=MXFb+RtnzRHPAv3WrnV5x/KjkLxl12244GFTo5rtzY0=; fh=oYR8g7IDVLpcyR8CfwRNmLCZyk6/zhkNRecHFMULs1A=; b=qpVL+jrdHFK5SOmRQzlVn8zGnvB4n8XklvvbNhQnJG/Kt3hg6oW6vTgKE8xE0g/Tck EJDZnI5RtfRnL/ILnqI8nvE8IsB3sLavdzWCdTM+O53D1fpshvWJZpZJBqGZxUraVOMT qA31QhOWFFpm/BQOZ5+o0loJ+ycV1LOx7tLNFsS/6pZ3LFUuY15B4efOKJXDjgR5DgyT uhG9XSK7x3c9K+DbxUgA9eufloElrXJTn6Se6KWmAB7IL4CTMcA+Yp/SUYvqWTubjGxh GNTMgAIXb+XoKdghHCMxhmhbgcVIaVumbUImz3LFM1zKjLlGpQTupvhbBjau3cuPd427 lR7w==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@baylibre-com.20230601.gappssmtp.com header.s=20230601 header.b=EXC9etBQ; arc=pass (i=1 spf=pass spfdomain=baylibre.com dkim=pass dkdomain=baylibre-com.20230601.gappssmtp.com); spf=pass (google.com: domain of linux-kernel+bounces-72066-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:45d1:ec00::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-72066-ouuuleilei=gmail.com@vger.kernel.org" Received: from ny.mirrors.kernel.org (ny.mirrors.kernel.org. [2604:1380:45d1:ec00::1]) by mx.google.com with ESMTPS id c12-20020a05620a134c00b00787221ee5acsi7376811qkl.579.2024.02.19.14.36.00 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 19 Feb 2024 14:36:01 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-72066-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:45d1:ec00::1 as permitted sender) client-ip=2604:1380:45d1:ec00::1; Authentication-Results: mx.google.com; dkim=pass header.i=@baylibre-com.20230601.gappssmtp.com header.s=20230601 header.b=EXC9etBQ; arc=pass (i=1 spf=pass spfdomain=baylibre.com dkim=pass dkdomain=baylibre-com.20230601.gappssmtp.com); spf=pass (google.com: domain of linux-kernel+bounces-72066-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:45d1:ec00::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-72066-ouuuleilei=gmail.com@vger.kernel.org" Received: from smtp.subspace.kernel.org (wormhole.subspace.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ny.mirrors.kernel.org (Postfix) with ESMTPS id C25A41C20EF5 for ; Mon, 19 Feb 2024 22:36:00 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id CC72C58109; Mon, 19 Feb 2024 22:35:04 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=baylibre-com.20230601.gappssmtp.com header.i=@baylibre-com.20230601.gappssmtp.com header.b="EXC9etBQ" Received: from mail-ot1-f43.google.com (mail-ot1-f43.google.com [209.85.210.43]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 05BA120335 for ; Mon, 19 Feb 2024 22:34:58 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.210.43 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1708382100; cv=none; b=ur3w6EBn1XVOaxa6sSBpAMnAAhK4Z1Ja8OD1qlbZub/AFSRfNq+lR413R2DXzP6FpZAaxftaTrV0HaxaVS0lCBoGQEOX1Qa4A3BV2k7bd3PAOO/IYxpOuWq9X+j/K9xMVK4hMwz31+fUZ6r0TAi6MBo7hn84uNjKri3zzHgSvyA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1708382100; c=relaxed/simple; bh=sSmWV+EMEyVWLEUpEqFePlqyEc61WeEx3NpFQkH6xKY=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=X8d5x0ntxNCdazSUrGadccWn8bgdvTKOkzRkzCwZqD5IwFLiiPDCh0drwOvsueYidvCKhLNRbgT+Rq0hZW+pF+KEdxPqgls42SO00WELgXZaZ4PgHlktGduVFGnPt/ZTkN7ZSsEMl8HzN/XY22XWhJ1BOVgiL1LwiusJ/oitUvI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=baylibre.com; spf=pass smtp.mailfrom=baylibre.com; dkim=pass (2048-bit key) header.d=baylibre-com.20230601.gappssmtp.com header.i=@baylibre-com.20230601.gappssmtp.com header.b=EXC9etBQ; arc=none smtp.client-ip=209.85.210.43 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=baylibre.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=baylibre.com Received: by mail-ot1-f43.google.com with SMTP id 46e09a7af769-6e2e5824687so1587111a34.0 for ; Mon, 19 Feb 2024 14:34:58 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baylibre-com.20230601.gappssmtp.com; s=20230601; t=1708382098; x=1708986898; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=MXFb+RtnzRHPAv3WrnV5x/KjkLxl12244GFTo5rtzY0=; b=EXC9etBQKuw9L0LX5Qq5BQ1xKiKBy+qFfdRsxfHU1o+W1NGtdFoNY3kdY9i2AgzpRv gyJz3awidTYySxFx2SVXhjEc+HPhy1u4gk+DMdubyd+bCto/pBVlLv6YDiSl0dbo6M/7 zUVHOAHEnS5yMzF2/eMWuDAhe7NVZqU8gU10JuwO+56DwPJSNU+Z9ZGd+U2riHa6aAYT f43C9/mkSw1jmyWT1m7Y+zJ3lGf0KwbLlMEEuKQxcizRETvUAFXlrU6mcMl50oHbxq3E ljQPSbRKtRnon/52XAt8bscc7T17HUeYWEes12ilK4xbVq1do4EPY/vivIjNXPdcCPB/ 87Fw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1708382098; x=1708986898; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=MXFb+RtnzRHPAv3WrnV5x/KjkLxl12244GFTo5rtzY0=; b=NdvcQLSfj+vHWSdr6Vva/oY0dqn8jAI/AYYmMEtV1f/AeYIZ5OiJNpQZe6po7dHpWE P76zY+SsR7dNVPLV5/besUwJXSDUWsvUNvkBgIxaU5wlJf3onUGuRaEVDtt2eUnWid9Z kFBfzqkR6dmARDvLX2KirY47xvhCfa50h9mZuUpF8DmvLtGxFIkW28iJ0hPBodEwAxSm AfKYlQHgrdfwQJhAroF58O+0PZKCEsJd/yxhBr5MJ6xx4tomOJTROrkAEj+d6Czc9H8T IiNfxS0UOZWrlQhQUXu2NmvnIXHkbXfS7H4DPA6MK9uUDEVfvgarCU+mLfOyGESQ5MUV C3cA== X-Forwarded-Encrypted: i=1; AJvYcCVLoosRaePhRDa3nFZOv23kQTNGoUvlTTtxZ28FBSZx1WMkDFm+lAN3wrqxQ/D/eiNTynM1kRq2bzjb4e2+cnIb+pz0xOq/G4S9bms4 X-Gm-Message-State: AOJu0YwAUvVeJDpy7kkIOHLufOG9+7GD/kvQzZHRBbyfYBg7DOTpij39 qbzqrhbGmDCIvLa77Q1+rDAYc7r0X0/zQMOf0VzXJhfcWlqxy4myPXsE8DL4Ou4= X-Received: by 2002:a05:6830:1355:b0:6e2:dd64:c53e with SMTP id r21-20020a056830135500b006e2dd64c53emr12780325otq.2.1708382098245; Mon, 19 Feb 2024 14:34:58 -0800 (PST) Received: from freyr.lechnology.com (ip98-183-112-25.ok.ok.cox.net. [98.183.112.25]) by smtp.gmail.com with ESMTPSA id h25-20020a9d6419000000b006e45a5f0a70sm171776otl.49.2024.02.19.14.34.57 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 19 Feb 2024 14:34:57 -0800 (PST) From: David Lechner To: Mark Brown Cc: David Lechner , Martin Sperl , David Jander , Jonathan Cameron , Michael Hennerich , =?utf-8?q?Nuno_S=C3=A1?= , Alain Volmat , Maxime Coquelin , Alexandre Torgue , linux-spi@vger.kernel.org, linux-kernel@vger.kernel.org, linux-stm32@st-md-mailman.stormreply.com, linux-arm-kernel@lists.infradead.org, linux-iio@vger.kernel.org, Jonathan Cameron , Julien Stephan Subject: [PATCH v2 2/5] spi: move splitting transfers to spi_optimize_message() Date: Mon, 19 Feb 2024 16:33:19 -0600 Message-ID: <20240219-mainline-spi-precook-message-v2-2-4a762c6701b9@baylibre.com> X-Mailer: git-send-email 2.43.2 In-Reply-To: <20240219-mainline-spi-precook-message-v2-0-4a762c6701b9@baylibre.com> References: <20240219-mainline-spi-precook-message-v2-0-4a762c6701b9@baylibre.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Mailer: b4 0.12.4 X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1791368533256807290 X-GMAIL-MSGID: 1791368533256807290 Splitting transfers is an expensive operation so we can potentially optimize it by doing it only once per optimization of the message instead of repeating each time the message is transferred. The transfer splitting functions are currently the only user of spi_res_alloc() so spi_res_release() can be safely moved at this time from spi_finalize_current_message() to spi_unoptimize_message(). The doc comments of the public functions for splitting transfers are also updated so that callers will know when it is safe to call them to ensure proper resource management. Reviewed-by: Jonathan Cameron Signed-off-by: David Lechner Acked-by: Nuno Sa --- v2 changes: - Changed line break for multiline if condition - Removed kernel doc inclusion (/** -> /*) from static members - Picked up Jonathan's Reviewed-by drivers/spi/spi.c | 110 +++++++++++++++++++++++++++++++++--------------------- 1 file changed, 68 insertions(+), 42 deletions(-) diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index f68d92b57543..ba4d3fde2054 100644 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c @@ -1747,38 +1747,6 @@ static int __spi_pump_transfer_message(struct spi_controller *ctlr, trace_spi_message_start(msg); - /* - * If an SPI controller does not support toggling the CS line on each - * transfer (indicated by the SPI_CS_WORD flag) or we are using a GPIO - * for the CS line, we can emulate the CS-per-word hardware function by - * splitting transfers into one-word transfers and ensuring that - * cs_change is set for each transfer. - */ - if ((msg->spi->mode & SPI_CS_WORD) && (!(ctlr->mode_bits & SPI_CS_WORD) || - spi_is_csgpiod(msg->spi))) { - ret = spi_split_transfers_maxwords(ctlr, msg, 1); - if (ret) { - msg->status = ret; - spi_finalize_current_message(ctlr); - return ret; - } - - list_for_each_entry(xfer, &msg->transfers, transfer_list) { - /* Don't change cs_change on the last entry in the list */ - if (list_is_last(&xfer->transfer_list, &msg->transfers)) - break; - xfer->cs_change = 1; - } - } else { - ret = spi_split_transfers_maxsize(ctlr, msg, - spi_max_transfer_size(msg->spi)); - if (ret) { - msg->status = ret; - spi_finalize_current_message(ctlr); - return ret; - } - } - if (ctlr->prepare_message) { ret = ctlr->prepare_message(ctlr, msg); if (ret) { @@ -2124,6 +2092,8 @@ static void __spi_unoptimize_message(struct spi_message *msg) if (ctlr->unoptimize_message) ctlr->unoptimize_message(msg); + spi_res_release(ctlr, msg); + msg->optimized = false; msg->opt_state = NULL; } @@ -2169,15 +2139,6 @@ void spi_finalize_current_message(struct spi_controller *ctlr) spi_unmap_msg(ctlr, mesg); - /* - * In the prepare_messages callback the SPI bus has the opportunity - * to split a transfer to smaller chunks. - * - * Release the split transfers here since spi_map_msg() is done on - * the split transfers. - */ - spi_res_release(ctlr, mesg); - if (mesg->prepared && ctlr->unprepare_message) { ret = ctlr->unprepare_message(ctlr, mesg); if (ret) { @@ -3819,6 +3780,10 @@ static int __spi_split_transfer_maxsize(struct spi_controller *ctlr, * @msg: the @spi_message to transform * @maxsize: the maximum when to apply this * + * This function allocates resources that are automatically freed during the + * spi message unoptimize phase so this function should only be called from + * optimize_message callbacks. + * * Return: status of transformation */ int spi_split_transfers_maxsize(struct spi_controller *ctlr, @@ -3857,6 +3822,10 @@ EXPORT_SYMBOL_GPL(spi_split_transfers_maxsize); * @msg: the @spi_message to transform * @maxwords: the number of words to limit each transfer to * + * This function allocates resources that are automatically freed during the + * spi message unoptimize phase so this function should only be called from + * optimize_message callbacks. + * * Return: status of transformation */ int spi_split_transfers_maxwords(struct spi_controller *ctlr, @@ -4231,6 +4200,57 @@ static int __spi_validate(struct spi_device *spi, struct spi_message *message) return 0; } +/* + * spi_split_transfers - generic handling of transfer splitting + * @msg: the message to split + * + * Under certain conditions, a SPI controller may not support arbitrary + * transfer sizes or other features required by a peripheral. This function + * will split the transfers in the message into smaller transfers that are + * supported by the controller. + * + * Controllers with special requirements not covered here can also split + * transfers in the optimize_message() callback. + * + * Context: can sleep + * Return: zero on success, else a negative error code + */ +static int spi_split_transfers(struct spi_message *msg) +{ + struct spi_controller *ctlr = msg->spi->controller; + struct spi_transfer *xfer; + int ret; + + /* + * If an SPI controller does not support toggling the CS line on each + * transfer (indicated by the SPI_CS_WORD flag) or we are using a GPIO + * for the CS line, we can emulate the CS-per-word hardware function by + * splitting transfers into one-word transfers and ensuring that + * cs_change is set for each transfer. + */ + if ((msg->spi->mode & SPI_CS_WORD) && + (!(ctlr->mode_bits & SPI_CS_WORD) || spi_is_csgpiod(msg->spi))) { + ret = spi_split_transfers_maxwords(ctlr, msg, 1); + if (ret) + return ret; + + list_for_each_entry(xfer, &msg->transfers, transfer_list) { + /* Don't change cs_change on the last entry in the list */ + if (list_is_last(&xfer->transfer_list, &msg->transfers)) + break; + + xfer->cs_change = 1; + } + } else { + ret = spi_split_transfers_maxsize(ctlr, msg, + spi_max_transfer_size(msg->spi)); + if (ret) + return ret; + } + + return 0; +} + /* * __spi_optimize_message - shared implementation for spi_optimize_message() * and spi_maybe_optimize_message() @@ -4254,10 +4274,16 @@ static int __spi_optimize_message(struct spi_device *spi, if (ret) return ret; + ret = spi_split_transfers(msg); + if (ret) + return ret; + if (ctlr->optimize_message) { ret = ctlr->optimize_message(msg); - if (ret) + if (ret) { + spi_res_release(ctlr, msg); return ret; + } } msg->optimized = true;