From patchwork Tue Aug 20 06:29:36 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: John Ogness X-Patchwork-Id: 820904 Received: from galois.linutronix.de (Galois.linutronix.de [193.142.43.55]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id A2CC71DF682; Tue, 20 Aug 2024 06:30:08 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=193.142.43.55 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1724135410; cv=none; b=r/KW3MBfExDRgyoWQOBNHXiUphGkPa25wSHzWWIv/1Lke0cYPJEHEPnl0hRKYoNKpkd4kPe0NtLvoCcqzxFFUgVMo593CqVYex3J7T1k75TVpNRnqBNhzsUkrrtyFt9x5gfZy+IBgUyUEcGovViduJD53AkYQvazcxaPGrpCnQw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1724135410; c=relaxed/simple; bh=i7g9Rk6E1rRqftOtHZzjKlxcVFM+YP6E/P/94xSlZdE=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=IW/eYXwt++krARhTPiI6Lefm1S1Y7QCmfocSmGDbhqitsz9oRFeXM23Ts6/w/amHxBm+Sw5EgFLqM983CYjAZnIrgOtnszyX+IsPQzA5t/999n2AYnVhp/mi44CdA4j7gp/o7EO4ghQ0AGHAGujUMllokcTRaFFxV/FDF4Yf+9c= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de; spf=pass smtp.mailfrom=linutronix.de; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=O5BQalka; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=LDHwQPqG; arc=none smtp.client-ip=193.142.43.55 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linutronix.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="O5BQalka"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="LDHwQPqG" From: John Ogness DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1724135406; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=EwPBydyTGTYXegM2JVbnpVHJON//wTjw/xvV7q8bAP0=; b=O5BQalkalK7zZPgt3fErkgDV4eC6/ml5srqxQHZrbpScL9I55IJ/DlgwZrEqgya0lk8jih 0Esi66Qud+99remrqw0jOD3/7uN7cZ/SCyP1Zz7xdVl41RLWfEpdrm9IcxRLnruSPePuEC 3AbLceTYJcuE/MTcS6AOeD616RL+CrBONF5qtoWWdiVGBxAMVnWifqU+ZH6F5UzCky3CNL IijmHUy4SxPc+8quLpjXUv42U7fmKX20f5gTImDC3wGMVEfI6JOgDCOZSE/W6IbL8HWLHx l8gk2C5TJ+/8qPPVp1Tqc7j9SgYyAxoWmWCpn+hS8SpEciflXwV/sifBPBI4BA== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1724135406; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=EwPBydyTGTYXegM2JVbnpVHJON//wTjw/xvV7q8bAP0=; b=LDHwQPqGQdH/HPXU+CGwA0xY62VS8vK5IOR4eWPCDuSRgV4kEFZfry7+gzuEtDhA0gIgp8 Pcy0uwTsfb3nLrBQ== To: Petr Mladek Cc: Sergey Senozhatsky , Steven Rostedt , Thomas Gleixner , linux-kernel@vger.kernel.org, Greg Kroah-Hartman , Jiri Slaby , linux-serial@vger.kernel.org Subject: [PATCH printk v8 10/35] serial: core: Provide low-level functions to lock port Date: Tue, 20 Aug 2024 08:35:36 +0206 Message-Id: <20240820063001.36405-11-john.ogness@linutronix.de> In-Reply-To: <20240820063001.36405-1-john.ogness@linutronix.de> References: <20240820063001.36405-1-john.ogness@linutronix.de> Precedence: bulk X-Mailing-List: linux-serial@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 It will be necessary at times for the uart nbcon console drivers to acquire the port lock directly (without the additional nbcon functionality of the port lock wrappers). These are special cases such as the implementation of the device_lock()/device_unlock() callbacks or for internal port lock wrapper synchronization. Provide low-level variants __uart_port_lock_irqsave() and __uart_port_unlock_irqrestore() for this purpose. Signed-off-by: John Ogness Reviewed-by: Petr Mladek Acked-by: Greg Kroah-Hartman --- include/linux/serial_core.h | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h index aea25eef9a1a..8872cd21e70a 100644 --- a/include/linux/serial_core.h +++ b/include/linux/serial_core.h @@ -590,6 +590,24 @@ struct uart_port { void *private_data; /* generic platform data pointer */ }; +/* + * Only for console->device_lock()/_unlock() callbacks and internal + * port lock wrapper synchronization. + */ +static inline void __uart_port_lock_irqsave(struct uart_port *up, unsigned long *flags) +{ + spin_lock_irqsave(&up->lock, *flags); +} + +/* + * Only for console->device_lock()/_unlock() callbacks and internal + * port lock wrapper synchronization. + */ +static inline void __uart_port_unlock_irqrestore(struct uart_port *up, unsigned long flags) +{ + spin_unlock_irqrestore(&up->lock, flags); +} + /** * uart_port_lock - Lock the UART port * @up: Pointer to UART port structure From patchwork Tue Aug 20 06:29:37 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: John Ogness X-Patchwork-Id: 821249 Received: from galois.linutronix.de (Galois.linutronix.de [193.142.43.55]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 28B8A1DF69A; Tue, 20 Aug 2024 06:30:09 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=193.142.43.55 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1724135411; cv=none; b=Jng7CPg/dJVmnWJ6+1l3O05Rlzv0mynorV2RJFG4IP85AqUgSb4dDAWCvDOYmHLugoXWKpbQqaODBh/t5L7hKqQwrZdFjwN/opdpSg+kiVFxwq9NgvACmb/X3OhGJsohm4ByxDwPLjR3yCYndHXeIH59pq+m78/2ALPdTQqKQxo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1724135411; c=relaxed/simple; bh=qu0GAhjXm3Rql3Yn+yPrWxwrSP6aPTYXniSO6W8yPIo=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version:Content-Type; b=m1xoSOK4cBZj6MpJPlLTNZtRrHGd/3RDPgLRjXKoZ2ndz+IfG8zUEKd6MUGqbwwI4FUnyAB3oOY4oMz3uqghdsaCtAbnrUosI3e/CxR5WWnxcgBKQsOslZOkWX5S9VWQwrCEn26KqOnRvShSyvohuHZuyin1756ll6g0vyMTdFw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de; spf=pass smtp.mailfrom=linutronix.de; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=ZbtmHbtt; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=IFzsyrCN; arc=none smtp.client-ip=193.142.43.55 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linutronix.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="ZbtmHbtt"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="IFzsyrCN" From: John Ogness DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1724135407; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=72KWg1lC7QoA8wkEDKOEAHKAbxE9DDTme6Zqb5h0emg=; b=ZbtmHbttL9R9Z+jLl70YMzPQ2B5YUZUrujAiwZuCLQXpA4L4SvpcosE5JS2Gzakx6Rg87y IgAksSB/C9EIYSC+Dmg6DdW6zavCwNHSjRFbHl6lKUOykRIcc83p7VdKtDco3eTJQGwYxe OZxN5wBzC/2Q18TYocfFwjitCxvEgvNH3J1HNhpDiOYsRNKOMXzei7uHflQea4bXBYbQ1w uxizzpHhY2k3MNBcuCTw/xTDtgOtAiu+fI885v9t2+9xJbl3I19fPxwSBDPyJd6CgNp1QV 7YOCMpMyIcoM+JIkkVVyUy2e1MvQQ41rHx4JLgfgqpiTXcmiCWMAMTLaOUEVVQ== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1724135407; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=72KWg1lC7QoA8wkEDKOEAHKAbxE9DDTme6Zqb5h0emg=; b=IFzsyrCNYYAiMrH6O7LE9XEIioYZI/W9WiKGGr1Yzr6Ccm/NSgSi8HpEfmGGyjAaD3vL7+ oNKkdLfo/dFos4Dw== To: Petr Mladek Cc: Sergey Senozhatsky , Steven Rostedt , Thomas Gleixner , linux-kernel@vger.kernel.org, Greg Kroah-Hartman , Jiri Slaby , Russell King , Tony Lindgren , Andy Shevchenko , Geert Uytterhoeven , Arnd Bergmann , =?utf-8?q?Uwe_Kleine-K=C3=B6nig?= , =?utf-8?q?Th=C3=A9o_Lebrun?= , Linus Walleij , Lino Sanfilippo , =?utf-8?q?Ilpo_J=C3=A4rvinen?= , Konrad Dybcio , Sebastian Andrzej Siewior , linux-serial@vger.kernel.org Subject: [PATCH printk v8 11/35] serial: core: Introduce wrapper to set @uart_port->cons Date: Tue, 20 Aug 2024 08:35:37 +0206 Message-Id: <20240820063001.36405-12-john.ogness@linutronix.de> In-Reply-To: <20240820063001.36405-1-john.ogness@linutronix.de> References: <20240820063001.36405-1-john.ogness@linutronix.de> Precedence: bulk X-Mailing-List: linux-serial@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Introduce uart_port_set_cons() as a wrapper to set @cons of a uart_port. The wrapper sets @cons under the port lock in order to prevent @cons from disappearing while another context is holding the port lock. This is necessary for a follow-up commit relating to the port lock wrappers, which rely on @cons not changing between lock and unlock. Signed-off-by: John Ogness Tested-by: Théo Lebrun # EyeQ5, AMBA-PL011 Acked-by: Greg Kroah-Hartman Reviewed-by: Petr Mladek --- drivers/tty/serial/8250/8250_core.c | 6 +++--- drivers/tty/serial/amba-pl011.c | 2 +- drivers/tty/serial/serial_core.c | 16 ++++++++-------- include/linux/serial_core.h | 17 +++++++++++++++++ 4 files changed, 29 insertions(+), 12 deletions(-) diff --git a/drivers/tty/serial/8250/8250_core.c b/drivers/tty/serial/8250/8250_core.c index 29e4b83e0376..5f9f06911795 100644 --- a/drivers/tty/serial/8250/8250_core.c +++ b/drivers/tty/serial/8250/8250_core.c @@ -423,11 +423,11 @@ static int univ8250_console_setup(struct console *co, char *options) port = &serial8250_ports[co->index].port; /* link port to console */ - port->cons = co; + uart_port_set_cons(port, co); retval = serial8250_console_setup(port, options, false); if (retval != 0) - port->cons = NULL; + uart_port_set_cons(port, NULL); return retval; } @@ -485,7 +485,7 @@ static int univ8250_console_match(struct console *co, char *name, int idx, continue; co->index = i; - port->cons = co; + uart_port_set_cons(port, co); return serial8250_console_setup(port, options, true); } diff --git a/drivers/tty/serial/amba-pl011.c b/drivers/tty/serial/amba-pl011.c index 8b1644f5411e..7d0134ecd82f 100644 --- a/drivers/tty/serial/amba-pl011.c +++ b/drivers/tty/serial/amba-pl011.c @@ -2480,7 +2480,7 @@ static int pl011_console_match(struct console *co, char *name, int idx, continue; co->index = i; - port->cons = co; + uart_port_set_cons(port, co); return pl011_console_setup(co, options); } diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c index 9a18d0b95a41..61c7e1268957 100644 --- a/drivers/tty/serial/serial_core.c +++ b/drivers/tty/serial/serial_core.c @@ -3168,8 +3168,15 @@ static int serial_core_add_one_port(struct uart_driver *drv, struct uart_port *u state->uart_port = uport; uport->state = state; + /* + * If this port is in use as a console then the spinlock is already + * initialised. + */ + if (!uart_console_registered(uport)) + uart_port_spin_lock_init(uport); + state->pm_state = UART_PM_STATE_UNDEFINED; - uport->cons = drv->cons; + uart_port_set_cons(uport, drv->cons); uport->minor = drv->tty_driver->minor_start + uport->line; uport->name = kasprintf(GFP_KERNEL, "%s%d", drv->dev_name, drv->tty_driver->name_base + uport->line); @@ -3178,13 +3185,6 @@ static int serial_core_add_one_port(struct uart_driver *drv, struct uart_port *u goto out; } - /* - * If this port is in use as a console then the spinlock is already - * initialised. - */ - if (!uart_console_registered(uport)) - uart_port_spin_lock_init(uport); - if (uport->cons && uport->dev) of_console_check(uport->dev->of_node, uport->cons->name, uport->line); diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h index 8872cd21e70a..2cf03ff2056a 100644 --- a/include/linux/serial_core.h +++ b/include/linux/serial_core.h @@ -608,6 +608,23 @@ static inline void __uart_port_unlock_irqrestore(struct uart_port *up, unsigned spin_unlock_irqrestore(&up->lock, flags); } +/** + * uart_port_set_cons - Safely set the @cons field for a uart + * @up: The uart port to set + * @con: The new console to set to + * + * This function must be used to set @up->cons. It uses the port lock to + * synchronize with the port lock wrappers in order to ensure that the console + * cannot change or disappear while another context is holding the port lock. + */ +static inline void uart_port_set_cons(struct uart_port *up, struct console *con) +{ + unsigned long flags; + + __uart_port_lock_irqsave(up, &flags); + up->cons = con; + __uart_port_unlock_irqrestore(up, flags); +} /** * uart_port_lock - Lock the UART port * @up: Pointer to UART port structure From patchwork Tue Aug 20 06:29:40 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: John Ogness X-Patchwork-Id: 820903 Received: from galois.linutronix.de (Galois.linutronix.de [193.142.43.55]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 0E1741E212E; Tue, 20 Aug 2024 06:30:10 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=193.142.43.55 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1724135412; cv=none; b=mVoDb13UNtRmH6lSPN2H9FrMhcNXA6t7Gov7Emp0JFaGdgi/IEALQmu3MPn/r6S0Zs+DicXGSwcZVeXmYbglACi9dfOcA7nVl3axDtGY2vNc5RF8UtrH7HQieaYaxgpHbGioo/hXOmoXFOCtcTO/xWyYZwdHS84c8KTcR3IN32Q= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1724135412; c=relaxed/simple; bh=R4TOefOxndRBCPUXtpdDEsXMvKoXT/g+AiM/wcdCOiI=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=cngrEnGiQZfKKmRwqcwsS8nAuSglItaU6ZZNBdUrbaEgCCbV3ZjrRRAQvJma+ng5/mOR32KkznLG0Bcjoe++Htu51hvaGM+ncH88jdMEnjhFLSDIO7qfc4WwqMleKKW/BkO93FMZ40D+cJ8bG7ZbXBd2dfPW7L1nlLd01012HBc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de; spf=pass smtp.mailfrom=linutronix.de; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=JoHyeatM; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=ClkIjKV+; arc=none smtp.client-ip=193.142.43.55 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linutronix.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="JoHyeatM"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="ClkIjKV+" From: John Ogness DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1724135408; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=ElxI59csI9kczE5ClB/S01RcILMnwACUfY2TZOkMQ4U=; b=JoHyeatMCnmKRPRHgthJM7/1nUTwBhU+wT8BCo/mp44hEBO5+yNjBUsGZ1pOTHnZNfXT06 lUse3PXibj0w8U96MeLLZQmjkWYaLv1AHH4a/G9eByHiiA8APVPdK4uP6Skj/F2hWRP3JR CKFH849fTBa5WkCGlB+XzKiR342Zc2xkJ0YqA9MdN0s6/rMfN5k5LzOgQh08skSgzq49PL X/pCIPEu07f4mFiMmVrlYSm2bwu0Zjtlq5tImXv0CSEgQfYKvI6n6CvopaRhiK66BPhuP1 rPx5TKtkUMithTktcwLKOaTTQEQ1Dy1sU5vRS9xXkrc4SL9Ma4jwJWfSzeCClw== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1724135408; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=ElxI59csI9kczE5ClB/S01RcILMnwACUfY2TZOkMQ4U=; b=ClkIjKV+8w/CdQtbj4gYDFknd1XAWfeQu9aOMAs9rgjTzac0rSj01UQA4sPBrOxpSzoI5h JBDfiLk4OmYusqDg== To: Petr Mladek Cc: Sergey Senozhatsky , Steven Rostedt , Thomas Gleixner , linux-kernel@vger.kernel.org, Greg Kroah-Hartman , Jiri Slaby , linux-serial@vger.kernel.org Subject: [PATCH printk v8 14/35] serial: core: Acquire nbcon context in port->lock wrapper Date: Tue, 20 Aug 2024 08:35:40 +0206 Message-Id: <20240820063001.36405-15-john.ogness@linutronix.de> In-Reply-To: <20240820063001.36405-1-john.ogness@linutronix.de> References: <20240820063001.36405-1-john.ogness@linutronix.de> Precedence: bulk X-Mailing-List: linux-serial@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Currently the port->lock wrappers uart_port_lock(), uart_port_unlock() (and their variants) only lock/unlock the spin_lock. If the port is an nbcon console that has implemented the write_atomic() callback, the wrappers must also acquire/release the console context and mark the region as unsafe. This allows general port->lock synchronization to be synchronized against the nbcon write_atomic() callback. Note that __uart_port_using_nbcon() relies on the port->lock being held while a console is added and removed from the console list (i.e. all uart nbcon drivers *must* take the port->lock in their device_lock() callbacks). Signed-off-by: John Ogness Acked-by: Greg Kroah-Hartman Reviewed-by: Petr Mladek --- include/linux/serial_core.h | 82 ++++++++++++++++++++++++++++++++++++- 1 file changed, 80 insertions(+), 2 deletions(-) diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h index 2cf03ff2056a..4ab65874a850 100644 --- a/include/linux/serial_core.h +++ b/include/linux/serial_core.h @@ -11,6 +11,8 @@ #include #include #include +#include +#include #include #include #include @@ -625,6 +627,60 @@ static inline void uart_port_set_cons(struct uart_port *up, struct console *con) up->cons = con; __uart_port_unlock_irqrestore(up, flags); } + +/* Only for internal port lock wrapper usage. */ +static inline bool __uart_port_using_nbcon(struct uart_port *up) +{ + lockdep_assert_held_once(&up->lock); + + if (likely(!uart_console(up))) + return false; + + /* + * @up->cons is only modified under the port lock. Therefore it is + * certain that it cannot disappear here. + * + * @up->cons->node is added/removed from the console list under the + * port lock. Therefore it is certain that the registration status + * cannot change here, thus @up->cons->flags can be read directly. + */ + if (hlist_unhashed_lockless(&up->cons->node) || + !(up->cons->flags & CON_NBCON) || + !up->cons->write_atomic) { + return false; + } + + return true; +} + +/* Only for internal port lock wrapper usage. */ +static inline bool __uart_port_nbcon_try_acquire(struct uart_port *up) +{ + if (!__uart_port_using_nbcon(up)) + return true; + + return nbcon_device_try_acquire(up->cons); +} + +/* Only for internal port lock wrapper usage. */ +static inline void __uart_port_nbcon_acquire(struct uart_port *up) +{ + if (!__uart_port_using_nbcon(up)) + return; + + while (!nbcon_device_try_acquire(up->cons)) + cpu_relax(); +} + +/* Only for internal port lock wrapper usage. */ +static inline void __uart_port_nbcon_release(struct uart_port *up) +{ + if (!__uart_port_using_nbcon(up)) + return; + + nbcon_device_release(up->cons); +} + /** * uart_port_lock - Lock the UART port * @up: Pointer to UART port structure @@ -632,6 +688,7 @@ static inline void uart_port_set_cons(struct uart_port *up, struct console *con) static inline void uart_port_lock(struct uart_port *up) { spin_lock(&up->lock); + __uart_port_nbcon_acquire(up); } /** @@ -641,6 +698,7 @@ static inline void uart_port_lock(struct uart_port *up) static inline void uart_port_lock_irq(struct uart_port *up) { spin_lock_irq(&up->lock); + __uart_port_nbcon_acquire(up); } /** @@ -651,6 +709,7 @@ static inline void uart_port_lock_irq(struct uart_port *up) static inline void uart_port_lock_irqsave(struct uart_port *up, unsigned long *flags) { spin_lock_irqsave(&up->lock, *flags); + __uart_port_nbcon_acquire(up); } /** @@ -661,7 +720,15 @@ static inline void uart_port_lock_irqsave(struct uart_port *up, unsigned long *f */ static inline bool uart_port_trylock(struct uart_port *up) { - return spin_trylock(&up->lock); + if (!spin_trylock(&up->lock)) + return false; + + if (!__uart_port_nbcon_try_acquire(up)) { + spin_unlock(&up->lock); + return false; + } + + return true; } /** @@ -673,7 +740,15 @@ static inline bool uart_port_trylock(struct uart_port *up) */ static inline bool uart_port_trylock_irqsave(struct uart_port *up, unsigned long *flags) { - return spin_trylock_irqsave(&up->lock, *flags); + if (!spin_trylock_irqsave(&up->lock, *flags)) + return false; + + if (!__uart_port_nbcon_try_acquire(up)) { + spin_unlock_irqrestore(&up->lock, *flags); + return false; + } + + return true; } /** @@ -682,6 +757,7 @@ static inline bool uart_port_trylock_irqsave(struct uart_port *up, unsigned long */ static inline void uart_port_unlock(struct uart_port *up) { + __uart_port_nbcon_release(up); spin_unlock(&up->lock); } @@ -691,6 +767,7 @@ static inline void uart_port_unlock(struct uart_port *up) */ static inline void uart_port_unlock_irq(struct uart_port *up) { + __uart_port_nbcon_release(up); spin_unlock_irq(&up->lock); } @@ -701,6 +778,7 @@ static inline void uart_port_unlock_irq(struct uart_port *up) */ static inline void uart_port_unlock_irqrestore(struct uart_port *up, unsigned long flags) { + __uart_port_nbcon_release(up); spin_unlock_irqrestore(&up->lock, flags); }