From nobody Fri Feb 13 00:07:59 2026 Received: from mail-pl1-f176.google.com (mail-pl1-f176.google.com [209.85.214.176]) (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 E7AF1146A98 for ; Tue, 4 Jun 2024 16:01:44 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.214.176 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1717516906; cv=none; b=e/qw2fsvm+Y0+Cc3iJ7SG1g9cmbt1PNcdX8Z5v/6vf0j25ylYjYTCxHmgu5+lpgZ6WQkYIoaNQYFi3YLpfQia9tNVmZPdSTOIWNfvS1oxTWOR68ueQuxypmry8IX6Eh8lMxZyq13lbpecoXmSQNLaEgeuQ6flapFoUjxN0pN6zU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1717516906; c=relaxed/simple; bh=eNI9NbGlMBE/dfZEleY3KsoUvrO1tZDSmMJ0X+X0MGY=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=KrwKPyOi+2UPQ/8Ci9C7fD1dEBh2vf2RvlX4S8LqMyXPIoj6xYpbMs/wIOaob51lOs6UVrwldygLGf7mRL42hiJ9FYTLazP52AQTKK3SzMetBwnaBx5gGRR/o11ojhvwlF3+m5iXsRocaynZam9vJuM3tNwpbpLxg1FDYfHfWmU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=chromium.org; spf=pass smtp.mailfrom=chromium.org; dkim=pass (1024-bit key) header.d=chromium.org header.i=@chromium.org header.b=dWWmY77M; arc=none smtp.client-ip=209.85.214.176 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=chromium.org Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=chromium.org Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=chromium.org header.i=@chromium.org header.b="dWWmY77M" Received: by mail-pl1-f176.google.com with SMTP id d9443c01a7336-1f4a52b9413so45192715ad.2 for ; Tue, 04 Jun 2024 09:01:44 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; t=1717516904; x=1718121704; 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=Dk/4AF49oXXnNFUX5+Su2//neZ/RJyiCOhQzShR517w=; b=dWWmY77MmJz1wcpYB9iFB3yKS0xNqv84Xw/fhPN9m/htFT7/fTyURD+8xkwz/rQQAl jf+w68fA16Cn1lH8CI7ceB4ubbZGqDxOyrD+HU7jLkziZF8Bh6e4i+zn3QZ3HHPB/02A fkoEhnjRzoA/6Jibkyl21DYxNfRgpJa2JVKOQ= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1717516904; x=1718121704; 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=Dk/4AF49oXXnNFUX5+Su2//neZ/RJyiCOhQzShR517w=; b=UQhtSP2bHaDyR+lF8/jlBcLr54sFszqg2K99bnsaSJTvq4dgGLrQaJdxuNsXv3xsQv GfoCo9cIMdHtpNSSZ8eM6XepYiF9e2suUlwwHlkPiW/i8MKarQBlt9vBTMZlHZoiDfDP WMMNx7RihqX/Se295vWNRZCqrkf2+8vyib9yUexg7KcSRoksPvh2sxSO//MNqNPwb1D5 wGErNNJDY+v5YcfAGGqzkxRlDE0sqUXHQxfUzGHgeduOrBwC5LGwtBhFvYBpGbSQ0Bv5 liq5JwJSjiC0yEC2V+c/owFnQ95YzkYaAmkeJpLJs2WrhHbpkShjH+fY1NzUZn7j1xdD vwyQ== X-Forwarded-Encrypted: i=1; AJvYcCWCtLaYJlwmJt9oAACZoA7NTyBOgRreN9fYQzl/Jj6ACTMcHsr2uFJn/+U/Y0q/10/X0I/QcnmZ0Bh7GgXikzsLHqVtG+v95olOti2z X-Gm-Message-State: AOJu0Yzs6Ss0tvVhDkyL5QvCOd1duHNZAw0aE4rGMZZGXBrA75yRMu56 YK3KoSdBmgHVWzUupajV3XogEGZBGhPJpXM15qRBmL7/F7/lSrNAYmYscbwjaA== X-Google-Smtp-Source: AGHT+IH3gIE1OtM086DyyhTOWjAt4JmRQYlQLYPgpkVt7dUI95yVU9Qm9mU9ANKuP1Vy3e7A+IdyKg== X-Received: by 2002:a17:902:ce82:b0:1e4:c8b3:dbaf with SMTP id d9443c01a7336-1f6370296c6mr142181615ad.33.1717516904142; Tue, 04 Jun 2024 09:01:44 -0700 (PDT) Received: from dianders.sjc.corp.google.com ([2620:15c:9d:2:3609:ff79:4625:8a71]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-1f632358519sm86118385ad.82.2024.06.04.09.01.42 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 04 Jun 2024 09:01:43 -0700 (PDT) From: Douglas Anderson To: Greg Kroah-Hartman , Jiri Slaby Cc: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= , Andy Shevchenko , linux-arm-msm@vger.kernel.org, Konrad Dybcio , linux-kernel@vger.kernel.org, linux-serial@vger.kernel.org, John Ogness , =?UTF-8?q?Ilpo=20J=C3=A4rvinen?= , Yicong Yang , Tony Lindgren , Stephen Boyd , Johan Hovold , Bjorn Andersson , Douglas Anderson Subject: [PATCH v3 1/7] soc: qcom: geni-se: Add GP_LENGTH/IRQ_EN_SET/IRQ_EN_CLEAR registers Date: Tue, 4 Jun 2024 09:00:27 -0700 Message-ID: <20240604090028.v3.1.Ife7ced506aef1be3158712aa3ff34a006b973559@changeid> X-Mailer: git-send-email 2.45.1.288.g0e0cd299f1-goog In-Reply-To: <20240604160123.2029413-1-dianders@chromium.org> References: <20240604160123.2029413-1-dianders@chromium.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" For UART devices the M_GP_LENGTH is the TX word count. For other devices this is the transaction word count. For UART devices the S_GP_LENGTH is the RX word count. The IRQ_EN set/clear registers allow you to set or clear bits in the IRQ_EN register without needing a read-modify-write. Acked-by: Bjorn Andersson Signed-off-by: Douglas Anderson --- Since these new definitions are used in the future UART patches and Bjorn has Acked them, I'd expect them to go through the same tree as the UART patches that need them. (no changes since v2) Changes in v2: - New include/linux/soc/qcom/geni-se.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/include/linux/soc/qcom/geni-se.h b/include/linux/soc/qcom/geni= -se.h index 0f038a1a0330..8d07c442029b 100644 --- a/include/linux/soc/qcom/geni-se.h +++ b/include/linux/soc/qcom/geni-se.h @@ -88,11 +88,15 @@ struct geni_se { #define SE_GENI_M_IRQ_STATUS 0x610 #define SE_GENI_M_IRQ_EN 0x614 #define SE_GENI_M_IRQ_CLEAR 0x618 +#define SE_GENI_M_IRQ_EN_SET 0x61c +#define SE_GENI_M_IRQ_EN_CLEAR 0x620 #define SE_GENI_S_CMD0 0x630 #define SE_GENI_S_CMD_CTRL_REG 0x634 #define SE_GENI_S_IRQ_STATUS 0x640 #define SE_GENI_S_IRQ_EN 0x644 #define SE_GENI_S_IRQ_CLEAR 0x648 +#define SE_GENI_S_IRQ_EN_SET 0x64c +#define SE_GENI_S_IRQ_EN_CLEAR 0x650 #define SE_GENI_TX_FIFOn 0x700 #define SE_GENI_RX_FIFOn 0x780 #define SE_GENI_TX_FIFO_STATUS 0x800 @@ -101,6 +105,8 @@ struct geni_se { #define SE_GENI_RX_WATERMARK_REG 0x810 #define SE_GENI_RX_RFR_WATERMARK_REG 0x814 #define SE_GENI_IOS 0x908 +#define SE_GENI_M_GP_LENGTH 0x910 +#define SE_GENI_S_GP_LENGTH 0x914 #define SE_DMA_TX_IRQ_STAT 0xc40 #define SE_DMA_TX_IRQ_CLR 0xc44 #define SE_DMA_TX_FSM_RST 0xc58 --=20 2.45.1.288.g0e0cd299f1-goog From nobody Fri Feb 13 00:07:59 2026 Received: from mail-pl1-f174.google.com (mail-pl1-f174.google.com [209.85.214.174]) (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 5C8CA14830E for ; Tue, 4 Jun 2024 16:01:47 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.214.174 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1717516908; cv=none; b=cVyBJowjUpNo4axUq/PDvKmEozuB1GVHZPc4YQKtlIhLZIbFD6W3PVcojJT5ulxVU9YWjD+4Ze4ph1zAz64e0RPnLWVMRCC6i3ot96uNAGCILKDoVl3gXxT/8ZRETeGiGXtNZrnTM95OH/1/FD1axtXB5Imz6gatg8Hyk2Inzow= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1717516908; c=relaxed/simple; bh=SZcj9nvPAkd/Cv7HVInVaV/p1RAb1UQMCQMy3RYGV4k=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=HHg1qcho+3uZwpPkqHH0Eo2L9ohuHdNQckTd3dXNDaWe9DIm2uUiA8wC86UpVUMDu3ZJOpQoyq7GItZH5XfIJSoJSu+I3TvP57loXbcM7CVlddIaXp//swvyBUJhTGVg+JXpBIdKXRMa80t2kPYhn0UU+aCRpSrcu/epP5PpsTY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=chromium.org; spf=pass smtp.mailfrom=chromium.org; dkim=pass (1024-bit key) header.d=chromium.org header.i=@chromium.org header.b=PHDZhjU8; arc=none smtp.client-ip=209.85.214.174 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=chromium.org Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=chromium.org Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=chromium.org header.i=@chromium.org header.b="PHDZhjU8" Received: by mail-pl1-f174.google.com with SMTP id d9443c01a7336-1f48b825d8cso11037985ad.2 for ; Tue, 04 Jun 2024 09:01:47 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; t=1717516906; x=1718121706; 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=8L66kUAR7RZnRxdJympn4knIixZh8QJnRreM7SkXnIs=; b=PHDZhjU87FCa/woTn5B+LsXFc5SLP9rge/BHqrkT3JozpMrCsueD/6Q1onRGdn99QZ GQWlYPxTNzjkeSaD43MbarGuRa3aPMDGAa0tLXrI4Kv9P+Fd35s6t30x6kW97dl82ECx vK/K+RoS9ZHBT5+hPCYiGre7cYLQ2Mry62/1g= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1717516906; x=1718121706; 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=8L66kUAR7RZnRxdJympn4knIixZh8QJnRreM7SkXnIs=; b=b6X5L5lnUa+NM5USzlEz1XJC1/OiZc4R841XQF98tnOiNfVuUWGJTfO9O/ifroyzvt Be6gv1WZ3POjn4eJOir5dn9uAdN7ByKuMWT+2hlbtJstJoP0/GRwC4+8h2msI7iWXTHu Rm6rZ/7JZtBIpZ8lHHOsAfwsEKo2o3Is0amMur7G2EWlsNM9XVJHS23TwxVDrTuCh0kg uBV/uODhkoK5SsXDcJbJbSYv8nptL/bdD4C3kek+33/tEhNteCwnNVIo67Afi9raSEvr ubIRY6R7y3EOVTOoWecBbPaqIQ8abVU57mL30Jv1heCPHm0V6Ci3nwvHK0jnuayJr1S1 jRJg== X-Forwarded-Encrypted: i=1; AJvYcCVtD+LdzgnltKfQKagwmBMrayFtDtq4NLrS5H5pCP+FTxjsPuSv7ICSQRe7avV/3O3Ih9KFiW64lTCk4xlLanh1U/rmFAqavWrRIAS1 X-Gm-Message-State: AOJu0YzXjLfM/OD/PTFt2gDBVoTsQ+M2LfkxQi2QoI9cMaHy1Zt7Oe4j QmaBWWVLzTogPCfN9J5hevdd8JRDYAQ8OvvAkH61iO/6ziywn+3IQK2aeBDT+g== X-Google-Smtp-Source: AGHT+IFWJPCmpq0DFcieDsuM0+aWSb9NMUBLcE0cIna9MhVfPCFPZ5c3x+pgfaV2fn4lU+Pr+8VKRg== X-Received: by 2002:a17:903:32c4:b0:1f6:1f90:987a with SMTP id d9443c01a7336-1f636ffe77fmr169865145ad.3.1717516906396; Tue, 04 Jun 2024 09:01:46 -0700 (PDT) Received: from dianders.sjc.corp.google.com ([2620:15c:9d:2:3609:ff79:4625:8a71]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-1f632358519sm86118385ad.82.2024.06.04.09.01.44 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 04 Jun 2024 09:01:45 -0700 (PDT) From: Douglas Anderson To: Greg Kroah-Hartman , Jiri Slaby Cc: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= , Andy Shevchenko , linux-arm-msm@vger.kernel.org, Konrad Dybcio , linux-kernel@vger.kernel.org, linux-serial@vger.kernel.org, John Ogness , =?UTF-8?q?Ilpo=20J=C3=A4rvinen?= , Yicong Yang , Tony Lindgren , Stephen Boyd , Johan Hovold , Bjorn Andersson , Douglas Anderson , Thomas Gleixner , Vijaya Krishna Nivarthi Subject: [PATCH v3 2/7] serial: qcom-geni: Fix the timeout in qcom_geni_serial_poll_bit() Date: Tue, 4 Jun 2024 09:00:28 -0700 Message-ID: <20240604090028.v3.2.I3e1968bbeee67e28fd4e15509950805b6665484a@changeid> X-Mailer: git-send-email 2.45.1.288.g0e0cd299f1-goog In-Reply-To: <20240604160123.2029413-1-dianders@chromium.org> References: <20240604160123.2029413-1-dianders@chromium.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable The qcom_geni_serial_poll_bit() is supposed to be able to be used to poll a bit that's will become set when a TX transfer finishes. Because of this it tries to set its timeout based on how long the UART will take to shift out all of the queued bytes. There are two problems here: 1. There appears to be a hidden extra word on the firmware side which is the word that the firmware has already taken out of the FIFO and is currently shifting out. We need to account for this. 2. The timeout calculation was assuming that it would only need 8 bits on the wire to shift out 1 byte. This isn't true. Typically 10 bits are used (8 data bits, 1 start and 1 stop bit), but as much as 13 bits could be used (14 if we allowed 9 bits per byte, which we don't). The too-short timeout was seen causing problems in a future patch which more properly waited for bytes to transfer out of the UART before cancelling. Rather than fix the calculation, replace it with the core-provided uart_fifo_timeout() function. NOTE: during earlycon, uart_fifo_timeout() has the same limitations about not being able to figure out the exact timeout that the old function did. Luckily uart_fifo_timeout() returns the same default timeout of 20ms in this case. We'll add a comment about it, though, to make it more obvious what's happening. Fixes: c4f528795d1a ("tty: serial: msm_geni_serial: Add serial driver suppo= rt for GENI based QUP") Suggested-by: Ilpo J=C3=A4rvinen Signed-off-by: Douglas Anderson --- Changes in v3: - Use uart_fifo_timeout() for timeout. Changes in v2: - New drivers/tty/serial/qcom_geni_serial.c | 37 +++++++++++++-------------- 1 file changed, 18 insertions(+), 19 deletions(-) diff --git a/drivers/tty/serial/qcom_geni_serial.c b/drivers/tty/serial/qco= m_geni_serial.c index 2bd25afe0d92..a48a15c2555e 100644 --- a/drivers/tty/serial/qcom_geni_serial.c +++ b/drivers/tty/serial/qcom_geni_serial.c @@ -124,7 +124,6 @@ struct qcom_geni_serial_port { dma_addr_t tx_dma_addr; dma_addr_t rx_dma_addr; bool setup; - unsigned int baud; unsigned long clk_rate; void *rx_buf; u32 loopback; @@ -269,24 +268,25 @@ static bool qcom_geni_serial_poll_bit(struct uart_por= t *uport, int offset, int field, bool set) { u32 reg; - struct qcom_geni_serial_port *port; - unsigned int baud; - unsigned int fifo_bits; - unsigned long timeout_us =3D 20000; - struct qcom_geni_private_data *private_data =3D uport->private_data; + unsigned long timeout_us; =20 - if (private_data->drv) { - port =3D to_dev_port(uport); - baud =3D port->baud; - if (!baud) - baud =3D 115200; - fifo_bits =3D port->tx_fifo_depth * port->tx_fifo_width; - /* - * Total polling iterations based on FIFO worth of bytes to be - * sent at current baud. Add a little fluff to the wait. - */ - timeout_us =3D ((fifo_bits * USEC_PER_SEC) / baud) + 500; - } + /* + * This function is used to poll bits, some of which (like CMD_DONE) + * might take as long as it takes for the FIFO plus the temp register + * on the geni side to drain. The Linux core calculates such a timeout + * for us and we can get it from uart_fifo_timeout(). + * + * It should be noted that during earlycon the variables that + * uart_fifo_timeout() makes use of in "uport" may not be setup yet. + * It's difficult to set things up for earlycon since it can't + * necessarily figure out the baud rate and reading the FIFO depth + * from the wrapper means some extra MMIO maps that we don't get by + * default. This isn't a big problem, though, since uart_fifo_timeout() + * gives back its "slop" of 20ms as a minimum and that should be + * plenty of time for earlycon unless we're running at an extremely + * low baud rate. + */ + timeout_us =3D jiffies_to_usecs(uart_fifo_timeout(uport)); =20 /* * Use custom implementation instead of readl_poll_atomic since ktimer @@ -1224,7 +1224,6 @@ static void qcom_geni_serial_set_termios(struct uart_= port *uport, qcom_geni_serial_stop_rx(uport); /* baud rate */ baud =3D uart_get_baud_rate(uport, termios, old, 300, 4000000); - port->baud =3D baud; =20 sampling_rate =3D UART_OVERSAMPLING; /* Sampling rate is halved for IP versions >=3D 2.5 */ --=20 2.45.1.288.g0e0cd299f1-goog From nobody Fri Feb 13 00:07:59 2026 Received: from mail-pl1-f173.google.com (mail-pl1-f173.google.com [209.85.214.173]) (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 C4452146A98 for ; Tue, 4 Jun 2024 16:01:49 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.214.173 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1717516911; cv=none; b=pt9ISHsznKiqi/stI8sMbzLMT0Z9JKZF/VVrEvF2BCB/yzGehMkZ3oBkt5ZDSP9MFsr0HkZEFW0xLMbd93+v8HEH03XnDlqy8p0K3LMC6WLzURHRpc/zAO+0jQAA+SxuzDJZ7Cf300XPCjGwOuLA7saQel9kM4G1/mpH1xGbHmo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1717516911; c=relaxed/simple; bh=2XiXCEZWGzGuogpB7UrNVjSqiElFtO0aCEYdeEc0X1w=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=oGNJxV3ju7SDt5vZdrpoYhKFkVyv0vO9fV4i1bRDmgSWKAF4HNZtFI2ZyXO+8MZiKqgMTRQkCkJ3rHw1wT+E0/c8Oh8XzriiynSn749AcjT6aVcvDzCHz8H426AF0km7dnC8ZJsWYE7IBQWNgztbUAxF7bwHAz/OMgHJn555PKo= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=chromium.org; spf=pass smtp.mailfrom=chromium.org; dkim=pass (1024-bit key) header.d=chromium.org header.i=@chromium.org header.b=KNDNcKUT; arc=none smtp.client-ip=209.85.214.173 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=chromium.org Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=chromium.org Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=chromium.org header.i=@chromium.org header.b="KNDNcKUT" Received: by mail-pl1-f173.google.com with SMTP id d9443c01a7336-1f62fae8c3cso42443905ad.3 for ; Tue, 04 Jun 2024 09:01:49 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; t=1717516909; x=1718121709; 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=a+b1f17eVJb80Zj1W53g2Cg6ZxrWFmpqnvW69q4l7Uo=; b=KNDNcKUT0lvSNVCsy6BrWeidvN+LQJ3AGkk3v27IMzZ9UCqL4Fu8sI/OvXgGPHdK+1 ba5dyIL/nKVn6ARWYX34RvAHpKcWSEDIomcncWepEvZPOycejY21cXB9cyoiRtfxCgEP c3dlHNObLyCz5XHEL8tW5VLqhZdmV6wfKAKR4= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1717516909; x=1718121709; 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=a+b1f17eVJb80Zj1W53g2Cg6ZxrWFmpqnvW69q4l7Uo=; b=VELqyyr6hsfbwcUs9vGK2HbL2OPLtDInfkTY7lcStukiptQEghDL410kUpRQkbsRkT c83yP6qrlbqzHqw5xkjpMGQSHPZJSnJxOVb0N9u/ZWJkSZgKv7esFBy5vfbMOaD+kWWj Y5Stu8uPfHo8vxwxHL+JLnrHB2Xlu8Uy0bxqi98Kcm/I93a+uTLz8wCLgFr7zgOktzZX sNRfLClIswyyXhgs5v539L366K7u384Uj5Z0hLe4QZlHhHWYiJbMbEGZ1OeclT+9vtam Be00vXaKYhp+Dj2M+m8P/cQ65LYfIpBI6QdkiZ24Mi+7+UbR/4whsH3tzshujYB6kqD7 IXig== X-Forwarded-Encrypted: i=1; AJvYcCWVLhJH7KHepZcktIw7a6Wkt78ACrby/At3Pu6XeT/myyZmvvkGTud5ZGFBfPMXPSb+0yPHFGzeRONJBhpswkIpCTFsJ35Oi+OK+68F X-Gm-Message-State: AOJu0Yw8VpsGVgmEklYkzQu174Bzx5tW5yIb2dAg5rq4DPksiT4rHw6Z 7T1kC3QbL8cw+BvvKe5DNCp11dL3z+Y9RtIMHKnroNLM3AJ6ir6rvyAiLbB7iA== X-Google-Smtp-Source: AGHT+IGiBs6CoEcjZoTZjvUybhOhGJoQkUpTWYueMh4xEVk/MVLaHWzkiQ429PcJ6uh2d03TU8ZR5g== X-Received: by 2002:a17:902:e152:b0:1f4:9138:8178 with SMTP id d9443c01a7336-1f63709e30amr92494075ad.49.1717516908948; Tue, 04 Jun 2024 09:01:48 -0700 (PDT) Received: from dianders.sjc.corp.google.com ([2620:15c:9d:2:3609:ff79:4625:8a71]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-1f632358519sm86118385ad.82.2024.06.04.09.01.46 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 04 Jun 2024 09:01:47 -0700 (PDT) From: Douglas Anderson To: Greg Kroah-Hartman , Jiri Slaby Cc: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= , Andy Shevchenko , linux-arm-msm@vger.kernel.org, Konrad Dybcio , linux-kernel@vger.kernel.org, linux-serial@vger.kernel.org, John Ogness , =?UTF-8?q?Ilpo=20J=C3=A4rvinen?= , Yicong Yang , Tony Lindgren , Stephen Boyd , Johan Hovold , Bjorn Andersson , Douglas Anderson , Thomas Gleixner Subject: [PATCH v3 3/7] serial: qcom-geni: Fix arg types for qcom_geni_serial_poll_bit() Date: Tue, 4 Jun 2024 09:00:29 -0700 Message-ID: <20240604090028.v3.3.I24a0de52dd7336908df180fa6b698e001f3aff82@changeid> X-Mailer: git-send-email 2.45.1.288.g0e0cd299f1-goog In-Reply-To: <20240604160123.2029413-1-dianders@chromium.org> References: <20240604160123.2029413-1-dianders@chromium.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" The "offset" passed in should be unsigned since it's always a positive offset from our memory mapped IO. The "field" should be u32 since we're anding it with a 32-bit value read from the device. Suggested-by: Stephen Boyd Signed-off-by: Douglas Anderson --- (no changes since v2) Changes in v2: - New drivers/tty/serial/qcom_geni_serial.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/tty/serial/qcom_geni_serial.c b/drivers/tty/serial/qco= m_geni_serial.c index a48a15c2555e..e5effc2f5878 100644 --- a/drivers/tty/serial/qcom_geni_serial.c +++ b/drivers/tty/serial/qcom_geni_serial.c @@ -265,7 +265,7 @@ static bool qcom_geni_serial_secondary_active(struct ua= rt_port *uport) } =20 static bool qcom_geni_serial_poll_bit(struct uart_port *uport, - int offset, int field, bool set) + unsigned int offset, u32 field, bool set) { u32 reg; unsigned long timeout_us; --=20 2.45.1.288.g0e0cd299f1-goog From nobody Fri Feb 13 00:07:59 2026 Received: from mail-pl1-f172.google.com (mail-pl1-f172.google.com [209.85.214.172]) (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 EF9B5148FFF for ; Tue, 4 Jun 2024 16:01:52 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.214.172 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1717516915; cv=none; b=gOc9z4/VSRDjfz8eMlxYj5JyG7E54/gwxgzLvajSIpx+o86ww0gSpdtYpSLz2gE8RLjVxkChYxbFJ/Rl+9UKrfyvYG1il6cJpSd/6HY6loAVBuiLw7cbbAJAP+IJeQtOybZ1Y+jCfkOtqm+J6R2NttGtA1yla7VY78M9sdZVyog= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1717516915; c=relaxed/simple; bh=bM+CwYviE8hbC61Ao8++7cm40ioyxFsXZdRy+wbbZqI=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=VcqobCYAbdVCENllR08OZh0F6088GEUmsucfBUnvwMLr66zdPysYBx0cAenkvhlWjVnE+pykKmgk0vGsei8d/mh/b6NoD8aEbPWV9OvB8tVQzfSdzPJJURK2asUOT0GvvrCZIS60o9Ocpq5qiDI8hS/H6jvP56kRGbtlMy2hXqw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=chromium.org; spf=pass smtp.mailfrom=chromium.org; dkim=pass (1024-bit key) header.d=chromium.org header.i=@chromium.org header.b=Zotcbhvs; arc=none smtp.client-ip=209.85.214.172 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=chromium.org Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=chromium.org Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=chromium.org header.i=@chromium.org header.b="Zotcbhvs" Received: by mail-pl1-f172.google.com with SMTP id d9443c01a7336-1f62a628b4cso37845665ad.1 for ; Tue, 04 Jun 2024 09:01:52 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; t=1717516912; x=1718121712; 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=Tz1mGlcK+k8OO+Zf/s5Aw5nRh+dYCllETeWsEDeJzE8=; b=ZotcbhvsEHfXUHRIqQo6fCbK2+uQXYRy4Ac045qckmy6ih8EOZU1XHXBol6nE0X6xu zomh2Lbw3QFF8Wq2b4fBc5tEGkp/MGVlkIaNuAEaGI4uCd2iHAmBDQhVx7RL//QxySwA RSZSxbVdU3f3CP3q6A3Mu3ESwDyC0VhIogVs8= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1717516912; x=1718121712; 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=Tz1mGlcK+k8OO+Zf/s5Aw5nRh+dYCllETeWsEDeJzE8=; b=FnAv1yayRv5O8ugjbDD5EC4ojumRrUcJ7+ZKa+wYpIcijKTAIbugbHYnPs3yH3X8zf oN5co2K6Hi0benFtiJUWcW3ThOj5/+ClrQ9lP/ZAqvOOjfFDc6p5OXUK9GUlrgRUdAlw i/Ahz7Icxn92dTEjbqCKgPPQkAHhSDSahq11kHXon36Coer8hZALy3/Hu/mbE4gKNYqY 5D4SDk3d+wyAu6MpvZyZYN6FTS/ZYzhme+5KJsOehHzihDCu1ZK4lT7ysq60mJWvQnQJ m/Rn7k3rk5UtBJg4OrNjeTimF5QoD7D2rnjZj47R0wD9xdhsw8il01fIhCwyw2Vjk8Qr EEJg== X-Forwarded-Encrypted: i=1; AJvYcCXSmy9OtugHmFC5Dcqfbd5CRdYH72h2hJT+dNSRkOsFRHVcCR6XH1zggJzaoORMYkmb1K3v9bFwHqln/JYFQ+bdpimDjd4XCKJQ1hnW X-Gm-Message-State: AOJu0YykMVyHncBH9ggT4+LtMS1mOV4WTF7s2uzbqXRZTa725IeZgynS RkEcJllGgfhOy3tGGSHqzw5w9RrbfKCs7ghUz7EDbITRwePO+HNCBqnwHv6qpw== X-Google-Smtp-Source: AGHT+IFjFsK7b5jeJuRmXNUJeTh0/w0Lyx/zDUdM1spc/2b7tXWGJLUB/NlaOIxAnXtZTLPBHn40MA== X-Received: by 2002:a17:903:2448:b0:1f6:74e6:1ec1 with SMTP id d9443c01a7336-1f674e62022mr75670415ad.68.1717516912287; Tue, 04 Jun 2024 09:01:52 -0700 (PDT) Received: from dianders.sjc.corp.google.com ([2620:15c:9d:2:3609:ff79:4625:8a71]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-1f632358519sm86118385ad.82.2024.06.04.09.01.49 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 04 Jun 2024 09:01:51 -0700 (PDT) From: Douglas Anderson To: Greg Kroah-Hartman , Jiri Slaby Cc: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= , Andy Shevchenko , linux-arm-msm@vger.kernel.org, Konrad Dybcio , linux-kernel@vger.kernel.org, linux-serial@vger.kernel.org, John Ogness , =?UTF-8?q?Ilpo=20J=C3=A4rvinen?= , Yicong Yang , Tony Lindgren , Stephen Boyd , Johan Hovold , Bjorn Andersson , Douglas Anderson , Rob Herring , Vijaya Krishna Nivarthi Subject: [PATCH v3 4/7] serial: qcom-geni: Introduce qcom_geni_serial_poll_bitfield() Date: Tue, 4 Jun 2024 09:00:30 -0700 Message-ID: <20240604090028.v3.4.Ic6411eab8d9d37acc451705f583fb535cd6dadb2@changeid> X-Mailer: git-send-email 2.45.1.288.g0e0cd299f1-goog In-Reply-To: <20240604160123.2029413-1-dianders@chromium.org> References: <20240604160123.2029413-1-dianders@chromium.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" With a small modification the qcom_geni_serial_poll_bit() function could be used to poll more than just a single bit. Let's generalize it. We'll make the qcom_geni_serial_poll_bit() into just a wrapper of the general function. Signed-off-by: Douglas Anderson --- The new function isn't used yet (except by the wrapper) but will be used in a future change. (no changes since v2) Changes in v2: - New drivers/tty/serial/qcom_geni_serial.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/drivers/tty/serial/qcom_geni_serial.c b/drivers/tty/serial/qco= m_geni_serial.c index e5effc2f5878..c4c54359d32d 100644 --- a/drivers/tty/serial/qcom_geni_serial.c +++ b/drivers/tty/serial/qcom_geni_serial.c @@ -264,8 +264,8 @@ static bool qcom_geni_serial_secondary_active(struct ua= rt_port *uport) return readl(uport->membase + SE_GENI_STATUS) & S_GENI_CMD_ACTIVE; } =20 -static bool qcom_geni_serial_poll_bit(struct uart_port *uport, - unsigned int offset, u32 field, bool set) +static bool qcom_geni_serial_poll_bitfield(struct uart_port *uport, + unsigned int offset, u32 field, u32 val) { u32 reg; unsigned long timeout_us; @@ -295,7 +295,7 @@ static bool qcom_geni_serial_poll_bit(struct uart_port = *uport, timeout_us =3D DIV_ROUND_UP(timeout_us, 10) * 10; while (timeout_us) { reg =3D readl(uport->membase + offset); - if ((bool)(reg & field) =3D=3D set) + if ((reg & field) =3D=3D val) return true; udelay(10); timeout_us -=3D 10; @@ -303,6 +303,12 @@ static bool qcom_geni_serial_poll_bit(struct uart_port= *uport, return false; } =20 +static bool qcom_geni_serial_poll_bit(struct uart_port *uport, + unsigned int offset, u32 field, bool set) +{ + return qcom_geni_serial_poll_bitfield(uport, offset, field, set ? field := 0); +} + static void qcom_geni_serial_setup_tx(struct uart_port *uport, u32 xmit_si= ze) { u32 m_cmd; --=20 2.45.1.288.g0e0cd299f1-goog From nobody Fri Feb 13 00:07:59 2026 Received: from mail-pl1-f182.google.com (mail-pl1-f182.google.com [209.85.214.182]) (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 71550149009 for ; Tue, 4 Jun 2024 16:01:56 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.214.182 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1717516917; cv=none; b=m73PKYcXG7SLwuNZ8tFDEIf1ZyQ+aRYxxlNatsQJlm/yGGUh0R1aplpIR7lUn9mNG5cumlkJfpwVwi4zpeV6ThZVPa2VEEncqF2iYcQqMcvsRpqoTdcMwfGT5c51DqiD30ztS2RIdSkyOYsx+Yv8BPwi4yddqpeey/DUrO3L1yg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1717516917; c=relaxed/simple; bh=15DzlyVMUcTOkeXAubhI5pLAwA7wvcRYCR8M+MhF4rU=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=quJrGAXcmNX/7EhWlaSrj+DI2xMGl5XiHl8xktfIJKSjWcA2LvbnkOqoDHYo9QrJQkt9n8sbSJo6ofAOl+KIan9YIcFGqfF9FB9IyHoCruewpH0je7kIXKzL3n2vYsgO0NBDTPIQ6A0iZzd2v3H/z/xT+eCB2mrEJp3HfkL/jVc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=chromium.org; spf=pass smtp.mailfrom=chromium.org; dkim=pass (1024-bit key) header.d=chromium.org header.i=@chromium.org header.b=lpffwFK2; arc=none smtp.client-ip=209.85.214.182 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=chromium.org Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=chromium.org Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=chromium.org header.i=@chromium.org header.b="lpffwFK2" Received: by mail-pl1-f182.google.com with SMTP id d9443c01a7336-1f68834bfdfso10243515ad.3 for ; Tue, 04 Jun 2024 09:01:56 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; t=1717516916; x=1718121716; 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=sE0jSu3gNAz5TfFVSt4q33fv9zdqOZE0PPbSpjByTxM=; b=lpffwFK2xfCt1/gc9dKE32ALQEER2WrcsSL0cecueJF+gnoxkLsPFhV2YbOR7A41Kg hlE4Ss2STBgIddxikhB2efH5CmPnpNs1RXVLPaHRf11OTD48qAN3F4FChu6+OanGyHZX RfBeAEkZtahGJo1Xk7FcDDkf8+Ra+vSQ9Q7iA= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1717516916; x=1718121716; 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=sE0jSu3gNAz5TfFVSt4q33fv9zdqOZE0PPbSpjByTxM=; b=Za5cKqoH4nrJxY7jmcbq2fOTZiRAdpgJ6SmNeO8q9Y77xVepyEiUDIrfEluEtuyMDz nwwuUZCGEwYzTQPJsAvV7NrZTtEG++xqfFChMrJ88qSyNDPZJOAFkPhkCtaJFz7yxJtf CGaXqmfVE8Q8wUgj3GSnSaF2DYSvFafXeOS/e15dFSUEsE9vA1eHi++7BV38161sKxc5 OeGyl8uRSvD4ubhZUAYt+uMbVy8OKOCw862LQXIikBkBHb4mNMtKM2uSF/3z6nf1wPt2 RPKc2avvQNI54svDs3BPVFshn9rhuwBt3VlaYtjNUFmxCVj99zv0lfmGyeaad6p7m9/v k+lQ== X-Forwarded-Encrypted: i=1; AJvYcCW/3pJoZr8rgkw26GXJTZE5ZVOsd+2Z620sbDAKNL+LU+8E9C7/NZwO0Zu2WyQQMQw3ct4tngdICZD04MkHYD7iOZUfW3CrDjBx0Sii X-Gm-Message-State: AOJu0YyGSLUAAWdXkGWYXHLKEzFm8YeQmPfcpFIPp4dIPr2R2+xi2uR5 lu8Taq/XikJsKjt4H31WhvPsjttZ3FDWy6JaDw0b7PHld7GN5KQPXNndqa1SCw== X-Google-Smtp-Source: AGHT+IFkIwPtOoypvgPqLNqXAQBGQokER/5fhFdY+L+D7rn8exKZ8pBPYZy4Fs9smBGqvwO1LGphxQ== X-Received: by 2002:a17:903:41ce:b0:1f6:7ee8:8935 with SMTP id d9443c01a7336-1f67ee88adfmr68395605ad.59.1717516915589; Tue, 04 Jun 2024 09:01:55 -0700 (PDT) Received: from dianders.sjc.corp.google.com ([2620:15c:9d:2:3609:ff79:4625:8a71]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-1f632358519sm86118385ad.82.2024.06.04.09.01.52 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 04 Jun 2024 09:01:54 -0700 (PDT) From: Douglas Anderson To: Greg Kroah-Hartman , Jiri Slaby Cc: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= , Andy Shevchenko , linux-arm-msm@vger.kernel.org, Konrad Dybcio , linux-kernel@vger.kernel.org, linux-serial@vger.kernel.org, John Ogness , =?UTF-8?q?Ilpo=20J=C3=A4rvinen?= , Yicong Yang , Tony Lindgren , Stephen Boyd , Johan Hovold , Bjorn Andersson , Douglas Anderson , Vijaya Krishna Nivarthi Subject: [PATCH v3 5/7] serial: qcom-geni: Just set the watermark level once Date: Tue, 4 Jun 2024 09:00:31 -0700 Message-ID: <20240604090028.v3.5.Ie02dcdf46089457026de3bd665c08f0210711966@changeid> X-Mailer: git-send-email 2.45.1.288.g0e0cd299f1-goog In-Reply-To: <20240604160123.2029413-1-dianders@chromium.org> References: <20240604160123.2029413-1-dianders@chromium.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" There's no reason to set the TX watermark level to 0 when we disable TX since we're disabling the interrupt anyway. Just set the watermark level once at init time and leave it alone. Signed-off-by: Douglas Anderson --- (no changes since v2) Changes in v2: - New drivers/tty/serial/qcom_geni_serial.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/drivers/tty/serial/qcom_geni_serial.c b/drivers/tty/serial/qco= m_geni_serial.c index c4c54359d32d..4dbc59873b34 100644 --- a/drivers/tty/serial/qcom_geni_serial.c +++ b/drivers/tty/serial/qcom_geni_serial.c @@ -392,7 +392,6 @@ static int qcom_geni_serial_get_char(struct uart_port *= uport) static void qcom_geni_serial_poll_put_char(struct uart_port *uport, unsigned char c) { - writel(DEF_TX_WM, uport->membase + SE_GENI_TX_WATERMARK_REG); qcom_geni_serial_setup_tx(uport, 1); WARN_ON(!qcom_geni_serial_poll_bit(uport, SE_GENI_M_IRQ_STATUS, M_TX_FIFO_WATERMARK_EN, true)); @@ -436,7 +435,6 @@ __qcom_geni_serial_console_write(struct uart_port *upor= t, const char *s, bytes_to_send++; } =20 - writel(DEF_TX_WM, uport->membase + SE_GENI_TX_WATERMARK_REG); qcom_geni_serial_setup_tx(uport, bytes_to_send); for (i =3D 0; i < count; ) { size_t chars_to_write =3D 0; @@ -664,7 +662,6 @@ static void qcom_geni_serial_start_tx_fifo(struct uart_= port *uport) irq_en =3D readl(uport->membase + SE_GENI_M_IRQ_EN); irq_en |=3D M_TX_FIFO_WATERMARK_EN | M_CMD_DONE_EN; =20 - writel(DEF_TX_WM, uport->membase + SE_GENI_TX_WATERMARK_REG); writel(irq_en, uport->membase + SE_GENI_M_IRQ_EN); } =20 @@ -675,7 +672,6 @@ static void qcom_geni_serial_stop_tx_fifo(struct uart_p= ort *uport) =20 irq_en =3D readl(uport->membase + SE_GENI_M_IRQ_EN); irq_en &=3D ~(M_CMD_DONE_EN | M_TX_FIFO_WATERMARK_EN); - writel(0, uport->membase + SE_GENI_TX_WATERMARK_REG); writel(irq_en, uport->membase + SE_GENI_M_IRQ_EN); /* Possible stop tx is called multiple times. */ if (!qcom_geni_serial_main_active(uport)) @@ -1127,6 +1123,7 @@ static int qcom_geni_serial_port_setup(struct uart_po= rt *uport) false, true, true); geni_se_init(&port->se, UART_RX_WM, port->rx_fifo_depth - 2); geni_se_select_mode(&port->se, port->dev_data->mode); + writel(DEF_TX_WM, uport->membase + SE_GENI_TX_WATERMARK_REG); qcom_geni_serial_start_rx(uport); port->setup =3D true; =20 --=20 2.45.1.288.g0e0cd299f1-goog From nobody Fri Feb 13 00:07:59 2026 Received: from mail-pl1-f181.google.com (mail-pl1-f181.google.com [209.85.214.181]) (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 30CC6149C6E for ; Tue, 4 Jun 2024 16:02:00 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.214.181 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1717516921; cv=none; b=VxfUnOZmeyLwlyjKAazNHVvOvo+wZO4C1FdE5aP7D/q7B1usChsPl1F39dOt08QX8h9uA9CPuy9IrpzMvqDfpQnOHpTUD6TVAg2917+m4bWv4H1+RFi3x7dmR0F0dUzi3jLSx/QyNUcUcALXswg0B9iG/797F273F4vlXfEJlzM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1717516921; c=relaxed/simple; bh=ObtNj6rjCVjW2T5iMzjYuSOL8U7EWQcPv2CwxAiHVwY=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=bEd76IrNQcx8bM1J8N8M+HJuD5HLYxQ+l3T+WewK2wHO3F/J/JSkNyxwWeFRlXI0tJp3bQ08Dkb5Z0ypZ9YwBzanJj1LLCB6YOKSVqsYnf/r0N11Y1Ed1ERLNy01VxVzEJ0Gepcsh8V3GV+2ND2XLNZOv4SJvj8m5PVkBGUcy44= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=chromium.org; spf=pass smtp.mailfrom=chromium.org; dkim=pass (1024-bit key) header.d=chromium.org header.i=@chromium.org header.b=hHhfR9E2; arc=none smtp.client-ip=209.85.214.181 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=chromium.org Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=chromium.org Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=chromium.org header.i=@chromium.org header.b="hHhfR9E2" Received: by mail-pl1-f181.google.com with SMTP id d9443c01a7336-1f6559668e1so23918885ad.3 for ; Tue, 04 Jun 2024 09:02:00 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; t=1717516919; x=1718121719; 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=u97ZAbEtZ1L64P2LpaM/3tu5it6GPftWXFpfcFUjbZI=; b=hHhfR9E2zruTiNJDOIGnySmpUmqbh3fxLZgvbcfid4M0epWKPQp0gaYNzu1s8PLpf0 T51xMdrrpb/suzeURwhfQ4au7UXqc7cpF5kLtFIpzox7E/osb7Z6TFdDsUUpAdmfzddt onJl6rSORlkTArrpv5WXUSfuNs45jkJqOwTOg= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1717516919; x=1718121719; 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=u97ZAbEtZ1L64P2LpaM/3tu5it6GPftWXFpfcFUjbZI=; b=L6jy0JZPNaxsTpn2XD/1SGnsEfjg+KsIo0X0s8FWYQqkLSSxFhycsZkWPsThpziG3Q zvIbuwU1IYXoM5XAZQgpev8ZlBDatfF4Er/CNEcp5l8X2GNy68fA7Pgm8qkynxtP5G0N 8znGBGEKiUnTOvwsuycAmGsPWm/3P2TZnzO7u/omDWsoDQYz71EYgeDkyinLe3OKg2dh +xC+ErSyImiltDpu9gpX35ZEL04cT5tAcnoEMXHDPi92KXyOHraS/i6aud7LFyboE/d8 jxYF60oYEfYcptUDQyd8Qgk8XTjzjcNfSywOyc7NLB5+Vf+xPqGETCNI0sSZfcJvHX3P CEmw== X-Forwarded-Encrypted: i=1; AJvYcCUCaYC5RfVug6o+yHa6et3Nidk8BOzRdAtpdszOq/nr0neO9KHnIpxthQuAcIsBgrX6eqfGn3efcO+gmJCVghqS4kce3UvvHvOxu5bz X-Gm-Message-State: AOJu0YxLMGLoXVIOw5Ubeb/kLjsW7yGBdXC7HiJrW4ZyqBrQrN3CRoOK LIpfflcyZH8prn8HzyOvMVyqDtQEtwpCSdv/FbZKRnNlGYG33qgpdfwaU4VwcQ== X-Google-Smtp-Source: AGHT+IGmXg/0jbFEnM2y3wf5yaCkuP92p/JJeadGUBooCLQ9wjYQ+ewAobCZ6YU1JYKB+ljtMp+80Q== X-Received: by 2002:a17:903:32d2:b0:1e5:3c5:55a5 with SMTP id d9443c01a7336-1f636fd9da4mr140529395ad.8.1717516918750; Tue, 04 Jun 2024 09:01:58 -0700 (PDT) Received: from dianders.sjc.corp.google.com ([2620:15c:9d:2:3609:ff79:4625:8a71]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-1f632358519sm86118385ad.82.2024.06.04.09.01.56 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 04 Jun 2024 09:01:57 -0700 (PDT) From: Douglas Anderson To: Greg Kroah-Hartman , Jiri Slaby Cc: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= , Andy Shevchenko , linux-arm-msm@vger.kernel.org, Konrad Dybcio , linux-kernel@vger.kernel.org, linux-serial@vger.kernel.org, John Ogness , =?UTF-8?q?Ilpo=20J=C3=A4rvinen?= , Yicong Yang , Tony Lindgren , Stephen Boyd , Johan Hovold , Bjorn Andersson , Douglas Anderson , Thomas Gleixner , Vijaya Krishna Nivarthi Subject: [PATCH v3 6/7] serial: qcom-geni: Fix suspend while active UART xfer Date: Tue, 4 Jun 2024 09:00:32 -0700 Message-ID: <20240604090028.v3.6.I0f81a5baa37d368f291c96ee4830abca337e3c87@changeid> X-Mailer: git-send-email 2.45.1.288.g0e0cd299f1-goog In-Reply-To: <20240604160123.2029413-1-dianders@chromium.org> References: <20240604160123.2029413-1-dianders@chromium.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" On devices using Qualcomm's GENI UART it is possible to get the UART stuck such that it no longer outputs data. Specifically, logging in via an agetty on the debug serial port (which was _not_ used for kernel console) and running: cat /var/log/messages ...and then (via an SSH session) forcing a few suspend/resume cycles causes the UART to stop transmitting. The root of the problems was with qcom_geni_serial_stop_tx_fifo() which is called as part of the suspend process. Specific problems with that function: - When an in-progress "tx" command is cancelled it doesn't appear to fully drain the FIFO. That meant qcom_geni_serial_tx_empty() continued to report that the FIFO wasn't empty. The qcom_geni_serial_start_tx_fifo() function didn't re-enable interrupts in this case so the driver would never start transferring again. - When the driver cancelled the current "tx" command but it forgot to zero out "tx_remaining". This confused logic elsewhere in the driver. - From experimentation, it appears that cancelling the "tx" command could drop some of the queued up bytes. While qcom_geni_serial_stop_tx_fifo() could be fixed to drain the FIFO and shut things down properly, stop_tx() isn't supposed to be a slow function. It is run with local interrupts off and is documented to stop transmitting "as soon as possible". Change the function to just stop new bytes from being queued. In order to make this work, change qcom_geni_serial_start_tx_fifo() to remove some conditions. It's always safe to enable the watermark interrupt and the IRQ handler will disable it if it's not needed. For system suspend the queue still needs to be drained. Failure to do so means that the hardware won't provide new interrupts until a "cancel" command is sent. Add draining logic (fixing the issues noted above) at suspend time. NOTE: It would be ideal if qcom_geni_serial_stop_tx_fifo() could "pause" the transmitter right away. There is no obvious way to do this in the docs and experimentation didn't find any tricks either, so stopping TX "as soon as possible" isn't very soon but is the best possible. Fixes: c4f528795d1a ("tty: serial: msm_geni_serial: Add serial driver suppo= rt for GENI based QUP") Signed-off-by: Douglas Anderson --- There are still a number of problems with GENI UART after this but I've kept this change separate to make it easier to understand. Specifically on mainline just hitting "Ctrl-C" after dumping /var/log/messages to the serial port hangs things after the kfifo changes. Those issues will be addressed in future patches. It should also be noted that the "Fixes" tag here is a bit of a swag. I haven't gone and tested on ancient code, but at least the problems exist on kernel 5.15 and much of the code touched here has been here since the beginning, or at least since as long as the driver was stable. Changes in v3: - 0xffffffff =3D> GENMASK(31, 0) - Reword commit message. Changes in v2: - Totally rework / rename patch to handle suspend while active xfer drivers/tty/serial/qcom_geni_serial.c | 97 +++++++++++++++++++++------ 1 file changed, 75 insertions(+), 22 deletions(-) diff --git a/drivers/tty/serial/qcom_geni_serial.c b/drivers/tty/serial/qco= m_geni_serial.c index 4dbc59873b34..46b6674d90c5 100644 --- a/drivers/tty/serial/qcom_geni_serial.c +++ b/drivers/tty/serial/qcom_geni_serial.c @@ -130,6 +130,7 @@ struct qcom_geni_serial_port { bool brk; =20 unsigned int tx_remaining; + unsigned int tx_total; int wakeup_irq; bool rx_tx_swap; bool cts_rts_swap; @@ -311,11 +312,14 @@ static bool qcom_geni_serial_poll_bit(struct uart_por= t *uport, =20 static void qcom_geni_serial_setup_tx(struct uart_port *uport, u32 xmit_si= ze) { + struct qcom_geni_serial_port *port =3D to_dev_port(uport); u32 m_cmd; =20 writel(xmit_size, uport->membase + SE_UART_TX_TRANS_LEN); m_cmd =3D UART_START_TX << M_OPCODE_SHFT; writel(m_cmd, uport->membase + SE_GENI_M_CMD0); + + port->tx_total =3D xmit_size; } =20 static void qcom_geni_serial_poll_tx_done(struct uart_port *uport) @@ -335,6 +339,64 @@ static void qcom_geni_serial_poll_tx_done(struct uart_= port *uport) writel(irq_clear, uport->membase + SE_GENI_M_IRQ_CLEAR); } =20 +static void qcom_geni_serial_drain_tx_fifo(struct uart_port *uport) +{ + struct qcom_geni_serial_port *port =3D to_dev_port(uport); + + /* + * If the main sequencer is inactive it means that the TX command has + * been completed and all bytes have been sent. Nothing to do in that + * case. + */ + if (!qcom_geni_serial_main_active(uport)) + return; + + /* + * Wait until the FIFO has been drained. We've already taken bytes out + * of the higher level queue in qcom_geni_serial_send_chunk_fifo() so + * if we don't drain the FIFO but send the "cancel" below they seem to + * get lost. + */ + qcom_geni_serial_poll_bitfield(uport, SE_GENI_M_GP_LENGTH, GENMASK(31, 0), + port->tx_total - port->tx_remaining); + + /* + * If clearing the FIFO made us inactive then we're done--no need for + * a cancel. + */ + if (!qcom_geni_serial_main_active(uport)) + return; + + /* + * Cancel the current command. After this the main sequencer will + * stop reporting that it's active and we'll have to start a new + * transfer command. + * + * If we skip doing this cancel and then continue with a system + * suspend while there's an active command in the main sequencer + * then after resume time we won't get any more interrupts on the + * main sequencer until we send the cancel. + */ + geni_se_cancel_m_cmd(&port->se); + if (!qcom_geni_serial_poll_bit(uport, SE_GENI_M_IRQ_STATUS, + M_CMD_CANCEL_EN, true)) { + /* The cancel failed; try an abort as a fallback. */ + geni_se_abort_m_cmd(&port->se); + qcom_geni_serial_poll_bit(uport, SE_GENI_M_IRQ_STATUS, + M_CMD_ABORT_EN, true); + writel(M_CMD_ABORT_EN, uport->membase + SE_GENI_M_IRQ_CLEAR); + } + writel(M_CMD_CANCEL_EN, uport->membase + SE_GENI_M_IRQ_CLEAR); + + /* + * We've cancelled the current command. "tx_remaining" stores how + * many bytes are left to finish in the current command so we know + * when to start a new command. Since the command was cancelled we + * need to zero "tx_remaining". + */ + port->tx_remaining =3D 0; +} + static void qcom_geni_serial_abort_rx(struct uart_port *uport) { u32 irq_clear =3D S_CMD_DONE_EN | S_CMD_ABORT_EN; @@ -655,37 +717,18 @@ static void qcom_geni_serial_start_tx_fifo(struct uar= t_port *uport) { u32 irq_en; =20 - if (qcom_geni_serial_main_active(uport) || - !qcom_geni_serial_tx_empty(uport)) - return; - irq_en =3D readl(uport->membase + SE_GENI_M_IRQ_EN); irq_en |=3D M_TX_FIFO_WATERMARK_EN | M_CMD_DONE_EN; - writel(irq_en, uport->membase + SE_GENI_M_IRQ_EN); } =20 static void qcom_geni_serial_stop_tx_fifo(struct uart_port *uport) { u32 irq_en; - struct qcom_geni_serial_port *port =3D to_dev_port(uport); =20 irq_en =3D readl(uport->membase + SE_GENI_M_IRQ_EN); irq_en &=3D ~(M_CMD_DONE_EN | M_TX_FIFO_WATERMARK_EN); writel(irq_en, uport->membase + SE_GENI_M_IRQ_EN); - /* Possible stop tx is called multiple times. */ - if (!qcom_geni_serial_main_active(uport)) - return; - - geni_se_cancel_m_cmd(&port->se); - if (!qcom_geni_serial_poll_bit(uport, SE_GENI_M_IRQ_STATUS, - M_CMD_CANCEL_EN, true)) { - geni_se_abort_m_cmd(&port->se); - qcom_geni_serial_poll_bit(uport, SE_GENI_M_IRQ_STATUS, - M_CMD_ABORT_EN, true); - writel(M_CMD_ABORT_EN, uport->membase + SE_GENI_M_IRQ_CLEAR); - } - writel(M_CMD_CANCEL_EN, uport->membase + SE_GENI_M_IRQ_CLEAR); } =20 static void qcom_geni_serial_handle_rx_fifo(struct uart_port *uport, bool = drop) @@ -1067,7 +1110,15 @@ static int setup_fifos(struct qcom_geni_serial_port = *port) } =20 =20 -static void qcom_geni_serial_shutdown(struct uart_port *uport) +static void qcom_geni_serial_shutdown_dma(struct uart_port *uport) +{ + disable_irq(uport->irq); + + qcom_geni_serial_stop_tx(uport); + qcom_geni_serial_stop_rx(uport); +} + +static void qcom_geni_serial_shutdown_fifo(struct uart_port *uport) { disable_irq(uport->irq); =20 @@ -1076,6 +1127,8 @@ static void qcom_geni_serial_shutdown(struct uart_por= t *uport) =20 qcom_geni_serial_stop_tx(uport); qcom_geni_serial_stop_rx(uport); + + qcom_geni_serial_drain_tx_fifo(uport); } =20 static int qcom_geni_serial_port_setup(struct uart_port *uport) @@ -1533,7 +1586,7 @@ static const struct uart_ops qcom_geni_console_pops = =3D { .startup =3D qcom_geni_serial_startup, .request_port =3D qcom_geni_serial_request_port, .config_port =3D qcom_geni_serial_config_port, - .shutdown =3D qcom_geni_serial_shutdown, + .shutdown =3D qcom_geni_serial_shutdown_fifo, .type =3D qcom_geni_serial_get_type, .set_mctrl =3D qcom_geni_serial_set_mctrl, .get_mctrl =3D qcom_geni_serial_get_mctrl, @@ -1555,7 +1608,7 @@ static const struct uart_ops qcom_geni_uart_pops =3D { .startup =3D qcom_geni_serial_startup, .request_port =3D qcom_geni_serial_request_port, .config_port =3D qcom_geni_serial_config_port, - .shutdown =3D qcom_geni_serial_shutdown, + .shutdown =3D qcom_geni_serial_shutdown_dma, .type =3D qcom_geni_serial_get_type, .set_mctrl =3D qcom_geni_serial_set_mctrl, .get_mctrl =3D qcom_geni_serial_get_mctrl, --=20 2.45.1.288.g0e0cd299f1-goog From nobody Fri Feb 13 00:07:59 2026 Received: from mail-pl1-f180.google.com (mail-pl1-f180.google.com [209.85.214.180]) (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 512331482F8 for ; Tue, 4 Jun 2024 16:02:02 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.214.180 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1717516924; cv=none; b=p193AMO00UMp5ZAXy4XIN96LvkRy7xawimDc4C6JzTXyRLnZ4XoYQcUdeEM4g20KFoG/gwo0DG1Q6y8EJOp0Ca7ETTwRIzJ1j9s7/6HX4yw7ga95D66fT0uhF1m/8poH5vi3rIkKP6ggQdRjFuaXtiRq16Q78rCLeo9bbxrHVcU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1717516924; c=relaxed/simple; bh=bnvsRG5I2xgj/nMe+fZjbxhUWUQfNMm0FIil9Q0JqCs=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=Pu9yu7b70Y48XWey+pqV7g8qsOXOLCdXE8FoRw4WLyusE+QlUudB+ipysacNZTmGcJijDMKrnQmw+DaKxi3qjpqR/FHP9Cy8bUZkqrACf4hwmb5zRU83yT1/VPpRqB8Du0+hrpMGaf/f2hph0/oJFMMlSZ8M2/+rtLNt6Eh9rHU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=chromium.org; spf=pass smtp.mailfrom=chromium.org; dkim=pass (1024-bit key) header.d=chromium.org header.i=@chromium.org header.b=BmNw6+PM; arc=none smtp.client-ip=209.85.214.180 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=chromium.org Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=chromium.org Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=chromium.org header.i=@chromium.org header.b="BmNw6+PM" Received: by mail-pl1-f180.google.com with SMTP id d9443c01a7336-1f4c7b022f8so51248485ad.1 for ; Tue, 04 Jun 2024 09:02:02 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; t=1717516921; x=1718121721; 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=Fl3mbGzyk4HljmvFNsl550cvFIcOHwxgUQ0l64G0kBw=; b=BmNw6+PM7341w4rAXK/bL/ikeZ4DJSyz4u4kwHae6L48U7FVEH615T+zgvap3mZiSI //ykHBzkTHADPdGCphQga1y2SJrf/J3Itz2ytdTndF5XwCHpQkavxMWI6dVa41fDgXrH 4GugemANtGNbhd4RTDqpQ21/Pw2ZGpgMolats= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1717516921; x=1718121721; 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=Fl3mbGzyk4HljmvFNsl550cvFIcOHwxgUQ0l64G0kBw=; b=X+pCifIfOXjOslYzyxz8Onf11u3KDHZw5bDOYWw+RAkVi7xJb1fdbC763oDNkxG7PN HWJOigKBXQMksbP7i3lDmuhu86mFMdjf61LrQv/vvm3WMXmLq+XTfjDpN/txZGuQoyvS U7WmEObpR+ICkgpFTEH0c59TMIlxp0Lf7DdUnYR359EHwg5+cL0wADTDv9nkuyaRDpC7 9/8bOTzL1pAgl7snxnvFuST/Fzv3sJ/YHGy9I6cXKLIHQbwsfDMa9HLyfEGWpY305sV7 06dSdo5IT7EoOMqJK2Xy7i0WoefF7UzNlBjs0WEJcn9p7bnIL3EMNK+joEp3Y2VEWL3z YObg== X-Forwarded-Encrypted: i=1; AJvYcCVRjLkyYICcLZPVKu499SnaUZcoVVUHOp+fEk6dIp2ToY/foxCSeset0FLNbnp/r67LpjOAa03qq/I6+Aq27AptNSz+4G/sMEXqC9HY X-Gm-Message-State: AOJu0YwPMXF4uqVLF0NGUuoAC+Ap5Z1e6PFtN0/J1DGk5kPqDQQTJAph cGawMBHKIAtjCKICzyBO17hDGg9YguQXTe/7pDAhlwyQQzJR3f5adJRfWi6YxQ== X-Google-Smtp-Source: AGHT+IH0W12pPrk3QAm58DX3gocCykT6vzA0P6NewVA10PgYOuE9cfuxJVdhKeLWyi85TIIPwMP4Nw== X-Received: by 2002:a17:902:d4cf:b0:1f6:73cb:4877 with SMTP id d9443c01a7336-1f673cb4a69mr80614295ad.6.1717516921156; Tue, 04 Jun 2024 09:02:01 -0700 (PDT) Received: from dianders.sjc.corp.google.com ([2620:15c:9d:2:3609:ff79:4625:8a71]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-1f632358519sm86118385ad.82.2024.06.04.09.01.59 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 04 Jun 2024 09:02:00 -0700 (PDT) From: Douglas Anderson To: Greg Kroah-Hartman , Jiri Slaby Cc: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= , Andy Shevchenko , linux-arm-msm@vger.kernel.org, Konrad Dybcio , linux-kernel@vger.kernel.org, linux-serial@vger.kernel.org, John Ogness , =?UTF-8?q?Ilpo=20J=C3=A4rvinen?= , Yicong Yang , Tony Lindgren , Stephen Boyd , Johan Hovold , Bjorn Andersson , Douglas Anderson , Vijaya Krishna Nivarthi Subject: [PATCH v3 7/7] serial: qcom-geni: Rework TX in FIFO mode to fix hangs/lockups Date: Tue, 4 Jun 2024 09:00:33 -0700 Message-ID: <20240604090028.v3.7.I1af05e555c42a9c98435bb7aee0ee60e3dcd015e@changeid> X-Mailer: git-send-email 2.45.1.288.g0e0cd299f1-goog In-Reply-To: <20240604160123.2029413-1-dianders@chromium.org> References: <20240604160123.2029413-1-dianders@chromium.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" The fact that the Qualcomm GENI hardware interface is based around "packets" is really awkward to fit into Linux's UART design. Specifically, in order to send bytes you need to start up a new "command" saying how many bytes you want to send and then you need to send all those bytes. Once you've committed to sending that number of bytes it's very awkward to change your mind and send fewer, especially if you want to do so without dropping bytes on the ground. There may be a few cases where you might want to send fewer bytes than you originally expected: 1. You might want to interrupt the transfer with something higher priority, like the kernel console or kdb. 2. You might want to enter system suspend. 3. The user might have killed the program that had queued bytes for sending over the UART. Despite this awkwardness the Linux driver has still tried to send bytes using large transfers. Whenever the driver started a new transfer it would look at the number of bytes in the OS's queue and start a transfer for that many. The idea of using larger transfers is that it should be more efficient. When you're in the middle of a large transfer you can get interrupted when the hardware FIFO is close to empty and add more bytes in. Whenever you get to the end of a transfer you have to wait until the transfer is totally done before you can add more bytes and, depending on interrupt latency, that can cause the UART to idle a bit. Unfortunately there were lots of corner cases that the Linux driver didn't handle. One problem with the current driver is that if the user killed the program that queued bytes for sending over the UART then bad things would happen. Before commit 1788cf6a91d9 ("tty: serial: switch from circ_buf to kfifo") we'd just send stale data out the UART. After that commit we'll hard lockup. Another problem with the current driver can be seen if you queue a bunch of data to the UART and enter kdb. Specifically on a device _without_ kernel console on the UART, with an agetty on the UART, and with kgdb on the UART, doing `cat /var/log/messages` and then dropping into kdb and resuming caused console output to stop. Give up on trying to use large transfers in FIFO mode on GENI UART since there doesn't appear to be any way to solve these problems cleanly. Visually inspecting the console output even after these patches doesn't show any big pauses. In order to make this all work: - Switch the watermark interrupt to just being used to prime the TX pump. Once transfers are running, use "done" to queue the next batch. As part of this, change the watermark to fire whenever the queue is empty. - Never queue more than what can fit in the FIFO. This means we don't need to keep track of a command we're partway through. - For the console code and kgdb code where we can safely block while the queue empties, just do that rather than trying to queue a command when one was already in progress (which didn't work so well and is why there were some weird/awkward hacks in qcom_geni_serial_console_write()). - Leave the CMD_DONE interrupt enabled all the time since there's never any reason we don't want to see it. - Start using the "SE_GENI_M_IRQ_EN_SET" and "SE_GENI_M_IRQ_EN_CLEAR" registers to avoid read-modify-write of the "SE_GENI_M_IRQ_EN" register. This could be done in more of the driver if needed but for now just update code that's touched. Fixes: 1788cf6a91d9 ("tty: serial: switch from circ_buf to kfifo") Fixes: a1fee899e5be ("tty: serial: qcom_geni_serial: Fix softlock") Signed-off-by: Douglas Anderson --- I'm listing two "fixes" commits here. The first is the kfifo change since it is very easy to see a hardlockup after that change. Almost certainly anyone with the kfifo patch wants this patch. I've also listed a much earlier patch as one being fixed since that was the one that made us send larger transfers. I've tested this commit on an sc7180-trogdor board both with and without kernel console going to the UART. I've tested across some suspend/resume cycles and with kgdb. I've also confirmed that bluetooth, which uses the DMA paths in this driver, continues to work. That all being said, a lot of things change here so I'd love any testing folks want to do. I'm not explicitly CCing stable here. The only truly terrible problem is the hardlockup introduced by the kfifo change. The rest of the issue have been around for years. If someone wants the fixes ported back to stable that's fine but IMO unless you're seeing problems it's not 100% required. Changes in v3: - Reword commit message. Changes in v2: - New drivers/tty/serial/qcom_geni_serial.c | 192 +++++++++++++------------- 1 file changed, 94 insertions(+), 98 deletions(-) diff --git a/drivers/tty/serial/qcom_geni_serial.c b/drivers/tty/serial/qco= m_geni_serial.c index 46b6674d90c5..204c6f40d7f2 100644 --- a/drivers/tty/serial/qcom_geni_serial.c +++ b/drivers/tty/serial/qcom_geni_serial.c @@ -78,7 +78,7 @@ #define GENI_UART_CONS_PORTS 1 #define GENI_UART_PORTS 3 #define DEF_FIFO_DEPTH_WORDS 16 -#define DEF_TX_WM 2 +#define DEF_TX_WM 1 #define DEF_FIFO_WIDTH_BITS 32 #define UART_RX_WM 2 =20 @@ -128,8 +128,8 @@ struct qcom_geni_serial_port { void *rx_buf; u32 loopback; bool brk; + bool tx_fifo_stopped; =20 - unsigned int tx_remaining; unsigned int tx_total; int wakeup_irq; bool rx_tx_swap; @@ -337,6 +337,14 @@ static void qcom_geni_serial_poll_tx_done(struct uart_= port *uport) M_CMD_ABORT_EN, true); } writel(irq_clear, uport->membase + SE_GENI_M_IRQ_CLEAR); + + /* + * Re-enable the TX watermark interrupt when we clear the "done" + * in case we were waiting on the "done" bit before starting a new + * command. The interrupt routine will re-disable this if it's not + * appropriate. + */ + writel(M_TX_FIFO_WATERMARK_EN, uport->membase + SE_GENI_M_IRQ_EN_SET); } =20 static void qcom_geni_serial_drain_tx_fifo(struct uart_port *uport) @@ -358,7 +366,7 @@ static void qcom_geni_serial_drain_tx_fifo(struct uart_= port *uport) * get lost. */ qcom_geni_serial_poll_bitfield(uport, SE_GENI_M_GP_LENGTH, GENMASK(31, 0), - port->tx_total - port->tx_remaining); + port->tx_total); =20 /* * If clearing the FIFO made us inactive then we're done--no need for @@ -387,14 +395,6 @@ static void qcom_geni_serial_drain_tx_fifo(struct uart= _port *uport) writel(M_CMD_ABORT_EN, uport->membase + SE_GENI_M_IRQ_CLEAR); } writel(M_CMD_CANCEL_EN, uport->membase + SE_GENI_M_IRQ_CLEAR); - - /* - * We've cancelled the current command. "tx_remaining" stores how - * many bytes are left to finish in the current command so we know - * when to start a new command. Since the command was cancelled we - * need to zero "tx_remaining". - */ - port->tx_remaining =3D 0; } =20 static void qcom_geni_serial_abort_rx(struct uart_port *uport) @@ -454,11 +454,12 @@ static int qcom_geni_serial_get_char(struct uart_port= *uport) static void qcom_geni_serial_poll_put_char(struct uart_port *uport, unsigned char c) { + qcom_geni_serial_drain_tx_fifo(uport); + qcom_geni_serial_setup_tx(uport, 1); WARN_ON(!qcom_geni_serial_poll_bit(uport, SE_GENI_M_IRQ_STATUS, M_TX_FIFO_WATERMARK_EN, true)); writel(c, uport->membase + SE_GENI_TX_FIFOn); - writel(M_TX_FIFO_WATERMARK_EN, uport->membase + SE_GENI_M_IRQ_CLEAR); qcom_geni_serial_poll_tx_done(uport); } #endif @@ -488,6 +489,8 @@ __qcom_geni_serial_console_write(struct uart_port *upor= t, const char *s, int i; u32 bytes_to_send =3D count; =20 + qcom_geni_serial_drain_tx_fifo(uport); + for (i =3D 0; i < count; i++) { /* * uart_console_write() adds a carriage return for each newline. @@ -538,7 +541,6 @@ static void qcom_geni_serial_console_write(struct conso= le *co, const char *s, bool locked =3D true; unsigned long flags; u32 geni_status; - u32 irq_en; =20 WARN_ON(co->index < 0 || co->index >=3D GENI_UART_CONS_PORTS); =20 @@ -554,38 +556,10 @@ static void qcom_geni_serial_console_write(struct con= sole *co, const char *s, =20 geni_status =3D readl(uport->membase + SE_GENI_STATUS); =20 - if (!locked) { - /* - * We can only get here if an oops is in progress then we were - * unable to get the lock. This means we can't safely access - * our state variables like tx_remaining. About the best we - * can do is wait for the FIFO to be empty before we start our - * transfer, so we'll do that. - */ - qcom_geni_serial_poll_bit(uport, SE_GENI_M_IRQ_STATUS, - M_TX_FIFO_NOT_EMPTY_EN, false); - } else if ((geni_status & M_GENI_CMD_ACTIVE) && !port->tx_remaining) { - /* - * It seems we can't interrupt existing transfers if all data - * has been sent, in which case we need to look for done first. - */ - qcom_geni_serial_poll_tx_done(uport); - - if (!kfifo_is_empty(&uport->state->port.xmit_fifo)) { - irq_en =3D readl(uport->membase + SE_GENI_M_IRQ_EN); - writel(irq_en | M_TX_FIFO_WATERMARK_EN, - uport->membase + SE_GENI_M_IRQ_EN); - } - } - __qcom_geni_serial_console_write(uport, s, count); =20 - - if (locked) { - if (port->tx_remaining) - qcom_geni_serial_setup_tx(uport, port->tx_remaining); + if (locked) uart_port_unlock_irqrestore(uport, flags); - } } =20 static void handle_rx_console(struct uart_port *uport, u32 bytes, bool dro= p) @@ -662,9 +636,9 @@ static void qcom_geni_serial_stop_tx_dma(struct uart_po= rt *uport) =20 if (port->tx_dma_addr) { geni_se_tx_dma_unprep(&port->se, port->tx_dma_addr, - port->tx_remaining); + port->tx_total); port->tx_dma_addr =3D 0; - port->tx_remaining =3D 0; + port->tx_total =3D 0; } =20 geni_se_cancel_m_cmd(&port->se); @@ -709,26 +683,27 @@ static void qcom_geni_serial_start_tx_dma(struct uart= _port *uport) qcom_geni_serial_stop_tx_dma(uport); return; } - - port->tx_remaining =3D xmit_size; } =20 static void qcom_geni_serial_start_tx_fifo(struct uart_port *uport) { - u32 irq_en; + struct qcom_geni_serial_port *port =3D to_dev_port(uport); =20 - irq_en =3D readl(uport->membase + SE_GENI_M_IRQ_EN); - irq_en |=3D M_TX_FIFO_WATERMARK_EN | M_CMD_DONE_EN; - writel(irq_en, uport->membase + SE_GENI_M_IRQ_EN); + port->tx_fifo_stopped =3D false; + + /* Prime the pump to get data flowing. */ + writel(M_TX_FIFO_WATERMARK_EN, uport->membase + SE_GENI_M_IRQ_EN_SET); } =20 static void qcom_geni_serial_stop_tx_fifo(struct uart_port *uport) { - u32 irq_en; + struct qcom_geni_serial_port *port =3D to_dev_port(uport); =20 - irq_en =3D readl(uport->membase + SE_GENI_M_IRQ_EN); - irq_en &=3D ~(M_CMD_DONE_EN | M_TX_FIFO_WATERMARK_EN); - writel(irq_en, uport->membase + SE_GENI_M_IRQ_EN); + /* + * We can't do anything to safely pause the bytes that have already + * been queued up so just set a flag saying we shouldn't queue any more. + */ + port->tx_fifo_stopped =3D true; } =20 static void qcom_geni_serial_handle_rx_fifo(struct uart_port *uport, bool = drop) @@ -896,10 +871,20 @@ static void qcom_geni_serial_stop_tx(struct uart_port= *uport) uport->ops->stop_tx(uport); } =20 +static void qcom_geni_serial_enable_cmd_done(struct uart_port *uport) +{ + struct qcom_geni_serial_port *port =3D to_dev_port(uport); + + /* If we're not in FIFO mode we don't use CMD_DONE. */ + if (port->dev_data->mode !=3D GENI_SE_FIFO) + return; + + writel(M_CMD_DONE_EN, uport->membase + SE_GENI_M_IRQ_EN_SET); +} + static void qcom_geni_serial_send_chunk_fifo(struct uart_port *uport, unsigned int chunk) { - struct qcom_geni_serial_port *port =3D to_dev_port(uport); unsigned int tx_bytes, remaining =3D chunk; u8 buf[BYTES_PER_FIFO_WORD]; =20 @@ -912,52 +897,74 @@ static void qcom_geni_serial_send_chunk_fifo(struct u= art_port *uport, iowrite32_rep(uport->membase + SE_GENI_TX_FIFOn, buf, 1); =20 remaining -=3D tx_bytes; - port->tx_remaining -=3D tx_bytes; } } =20 -static void qcom_geni_serial_handle_tx_fifo(struct uart_port *uport, - bool done, bool active) +static void qcom_geni_serial_handle_tx_fifo(struct uart_port *uport) { struct qcom_geni_serial_port *port =3D to_dev_port(uport); struct tty_port *tport =3D &uport->state->port; size_t avail; size_t pending; u32 status; - u32 irq_en; unsigned int chunk; + bool active; =20 - status =3D readl(uport->membase + SE_GENI_TX_FIFO_STATUS); - - /* Complete the current tx command before taking newly added data */ - if (active) - pending =3D port->tx_remaining; - else - pending =3D kfifo_len(&tport->xmit_fifo); + /* + * The TX watermark interrupt is only used to "prime the pump" for + * transfers. Once transfers have been kicked off we always use the + * "done" interrupt to queue the next batch. Once were here we can + * always disable the TX watermark interrupt. + * + * NOTE: we use the TX watermark in this way because we don't ever + * kick off TX transfers larger than we can stuff into the FIFO. This + * is because bytes from the OS's circular queue can disappear and + * there's no known safe/non-blocking way to cancel the larger + * transfer when bytes disappear. See qcom_geni_serial_drain_tx_fifo() + * for an example of a safe (but blocking) way to drain, but that's + * not appropriate in an IRQ handler. We also can't just kick off one + * large transfer and queue bytes whenever because we're using 4 bytes + * per FIFO word and thus we can only queue non-multiple-of-4 bytes as + * in the last word of a transfer. + */ + writel(M_TX_FIFO_WATERMARK_EN, uport->membase + SE_GENI_M_IRQ_EN_CLEAR); =20 - /* All data has been transmitted and acknowledged as received */ - if (!pending && !status && done) { - qcom_geni_serial_stop_tx_fifo(uport); + /* + * If we've got an active TX command running then we expect to still + * see the "done" bit in the future and we can't kick off another + * transfer till then. Bail. NOTE: it's important that we read "active" + * after we've cleared the "done" interrupt (which the caller already + * did for us) so that we know that if we show as non-active we're + * guaranteed to later get "done". + * + * If nothing is pending we _also_ want to bail. Later start_tx() + * will start transfers again by temporarily turning on the TX + * watermark. + */ + active =3D readl(uport->membase + SE_GENI_STATUS) & M_GENI_CMD_ACTIVE; + pending =3D port->tx_fifo_stopped ? 0 : kfifo_len(&tport->xmit_fifo); + if (active || !pending) goto out_write_wakeup; - } =20 + /* Calculate how much space is available in the FIFO right now. */ + status =3D readl(uport->membase + SE_GENI_TX_FIFO_STATUS); avail =3D port->tx_fifo_depth - (status & TX_FIFO_WC); avail *=3D BYTES_PER_FIFO_WORD; =20 - chunk =3D min(avail, pending); - if (!chunk) + /* + * It's a bit odd if we get here and have bytes pending and we're + * handling a "done" or "TX watermark" interrupt but we don't + * have space in the FIFO. Stick in a warning and bail. + */ + if (!avail) { + dev_warn(uport->dev, "FIFO unexpectedly out of space\n"); goto out_write_wakeup; - - if (!port->tx_remaining) { - qcom_geni_serial_setup_tx(uport, pending); - port->tx_remaining =3D pending; - - irq_en =3D readl(uport->membase + SE_GENI_M_IRQ_EN); - if (!(irq_en & M_TX_FIFO_WATERMARK_EN)) - writel(irq_en | M_TX_FIFO_WATERMARK_EN, - uport->membase + SE_GENI_M_IRQ_EN); } =20 + + /* We're ready to throw some bytes into the FIFO. */ + chunk =3D min(avail, pending); + qcom_geni_serial_setup_tx(uport, chunk); qcom_geni_serial_send_chunk_fifo(uport, chunk); =20 /* @@ -965,17 +972,9 @@ static void qcom_geni_serial_handle_tx_fifo(struct uar= t_port *uport, * cleared it in qcom_geni_serial_isr it will have already reasserted * so we must clear it again here after our writes. */ - writel(M_TX_FIFO_WATERMARK_EN, - uport->membase + SE_GENI_M_IRQ_CLEAR); + writel(M_TX_FIFO_WATERMARK_EN, uport->membase + SE_GENI_M_IRQ_CLEAR); =20 out_write_wakeup: - if (!port->tx_remaining) { - irq_en =3D readl(uport->membase + SE_GENI_M_IRQ_EN); - if (irq_en & M_TX_FIFO_WATERMARK_EN) - writel(irq_en & ~M_TX_FIFO_WATERMARK_EN, - uport->membase + SE_GENI_M_IRQ_EN); - } - if (kfifo_len(&tport->xmit_fifo) < WAKEUP_CHARS) uart_write_wakeup(uport); } @@ -985,10 +984,10 @@ static void qcom_geni_serial_handle_tx_dma(struct uar= t_port *uport) struct qcom_geni_serial_port *port =3D to_dev_port(uport); struct tty_port *tport =3D &uport->state->port; =20 - uart_xmit_advance(uport, port->tx_remaining); - geni_se_tx_dma_unprep(&port->se, port->tx_dma_addr, port->tx_remaining); + uart_xmit_advance(uport, port->tx_total); + geni_se_tx_dma_unprep(&port->se, port->tx_dma_addr, port->tx_total); port->tx_dma_addr =3D 0; - port->tx_remaining =3D 0; + port->tx_total =3D 0; =20 if (!kfifo_is_empty(&tport->xmit_fifo)) qcom_geni_serial_start_tx_dma(uport); @@ -1002,7 +1001,6 @@ static irqreturn_t qcom_geni_serial_isr(int isr, void= *dev) u32 m_irq_en; u32 m_irq_status; u32 s_irq_status; - u32 geni_status; u32 dma; u32 dma_tx_status; u32 dma_rx_status; @@ -1020,7 +1018,6 @@ static irqreturn_t qcom_geni_serial_isr(int isr, void= *dev) s_irq_status =3D readl(uport->membase + SE_GENI_S_IRQ_STATUS); dma_tx_status =3D readl(uport->membase + SE_DMA_TX_IRQ_STAT); dma_rx_status =3D readl(uport->membase + SE_DMA_RX_IRQ_STAT); - geni_status =3D readl(uport->membase + SE_GENI_STATUS); dma =3D readl(uport->membase + SE_GENI_DMA_MODE_EN); m_irq_en =3D readl(uport->membase + SE_GENI_M_IRQ_EN); writel(m_irq_status, uport->membase + SE_GENI_M_IRQ_CLEAR); @@ -1067,9 +1064,7 @@ static irqreturn_t qcom_geni_serial_isr(int isr, void= *dev) } else { if (m_irq_status & m_irq_en & (M_TX_FIFO_WATERMARK_EN | M_CMD_DONE_EN)) - qcom_geni_serial_handle_tx_fifo(uport, - m_irq_status & M_CMD_DONE_EN, - geni_status & M_GENI_CMD_ACTIVE); + qcom_geni_serial_handle_tx_fifo(uport); =20 if (s_irq_status & (S_RX_FIFO_WATERMARK_EN | S_RX_FIFO_LAST_EN)) qcom_geni_serial_handle_rx_fifo(uport, drop_rx); @@ -1177,6 +1172,7 @@ static int qcom_geni_serial_port_setup(struct uart_po= rt *uport) geni_se_init(&port->se, UART_RX_WM, port->rx_fifo_depth - 2); geni_se_select_mode(&port->se, port->dev_data->mode); writel(DEF_TX_WM, uport->membase + SE_GENI_TX_WATERMARK_REG); + qcom_geni_serial_enable_cmd_done(uport); qcom_geni_serial_start_rx(uport); port->setup =3D true; =20 --=20 2.45.1.288.g0e0cd299f1-goog