From nobody Tue Jun 9 01:01:39 2026 Received: from angie.orcam.me.uk (angie.orcam.me.uk [78.133.224.34]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 645322F8E81; Sun, 24 May 2026 23:20:45 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=78.133.224.34 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779664846; cv=none; b=YUZ0t5jwmxMoC6aHwZx6WOmZ1aQ60XSZmFsSWqXyx2pDnaulaBv9Mxz74cOX/84cOk7E+dEAhHpg6w5j6uzRJ2W1CFSbgFksly5rj4BhDRVMfUeC35raGV9yMhiDWbjQHolxhRroBd0SnjfaQXohmbN5B1qIae7zaAG9EYHfKwg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779664846; c=relaxed/simple; bh=dSpqvWLcenTGsHm74xZ1Rh/tXi1MqGz3aSfLvUUxsjE=; h=Date:From:To:cc:Subject:In-Reply-To:Message-ID:References: MIME-Version:Content-Type; b=WcDFhd1d+6N9gkboKcKYNgb1SC4cgIJdbXwPAUjablBryckcYJxwXMzQ2A5nllJE1go9HiRWvhLZIsKa003L5Iqq15miJ7/+DHs4QiLV256RbDdqtJ7TCI8Z8fP1Y9XS0QMw8AF+ViOLi8b9KR0IlQopQehi2Gij0ACoCQAbzq4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=orcam.me.uk; spf=none smtp.mailfrom=orcam.me.uk; arc=none smtp.client-ip=78.133.224.34 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=orcam.me.uk Authentication-Results: smtp.subspace.kernel.org; spf=none smtp.mailfrom=orcam.me.uk Received: by angie.orcam.me.uk (Postfix, from userid 500) id 0EC649200B3; Mon, 25 May 2026 01:12:06 +0200 (CEST) Received: from localhost (localhost [127.0.0.1]) by angie.orcam.me.uk (Postfix) with ESMTP id 07D7992009E; Mon, 25 May 2026 00:12:06 +0100 (BST) Date: Mon, 25 May 2026 00:12:05 +0100 (BST) From: "Maciej W. Rozycki" To: Thomas Bogendoerfer , Greg Kroah-Hartman , Jiri Slaby cc: Elena Reshetova , David Windsor , Kees Cook , Hans Liljestrand , linux-mips@vger.kernel.org, linux-serial@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v2 1/6] serial: sb1250-duart: Fix console message clobbering at channel resets In-Reply-To: Message-ID: References: User-Agent: Alpine 2.21 (DEB 202 2017-01-01) 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" Ensure any characters outstanding have been sent before issuing channel=20 resets so as to prevent messages issued to the bootconsole from getting=20 clobbered. Contrary to device documentation at the time the transmitter empty bit=20 is set only the transmit FIFO has been drained and there is still data=20 outstanding in the transmitter shift register, so wait an extra amount=20 of time for that register to drain too. This also prevents subsequent=20 messages produced to the console from getting clobbered, owing to what seems a transmitter synchronisation issue. When called from sbd_serial_console_init() it is too early for fsleep()=20 to work and even before lpj has been calculated and therefore the delay=20 is actually not sufficient for the transmitter to drain and is merely a=20 placeholder now. This will be addressed in a follow-up change. Fixes: 84a9582fd203 ("serial: core: Start managing serial controllers to en= able runtime PM") Signed-off-by: Maciej W. Rozycki Cc: stable@vger.kernel.org # v6.5+ --- Changes from v1 (1/4), : - Sanitise the change heading. --- drivers/tty/serial/sb1250-duart.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) linux-serial-sb1250-duart-reset-drain.diff Index: linux-macro/drivers/tty/serial/sb1250-duart.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- linux-macro.orig/drivers/tty/serial/sb1250-duart.c +++ linux-macro/drivers/tty/serial/sb1250-duart.c @@ -516,6 +516,28 @@ static void sbd_init_port(struct sbd_por =20 if (sport->initialised) return; + /* + * Contrary to documentation, which says that the transmitter + * empty bit is set when "there are no characters to send and + * the transmitter is idle," the bit is already set by hardware + * once the transmit FIFO has been drained only and while the + * transmitter shift register still holds data being supplied + * to the line. Consequently issuing a transmitter reset at + * this point causes the final character outstanding to be lost. + * + * Moreover, resetting the transmitter while transmission is + * in progress appears to make the transmitter go out of sync + * and subsequent characters issued after the transmitter has + * been reprogrammed and re-enabled are sent corrupted or with + * their bit patterns shifted. + * + * So once the transmitter empty bit has been set wait an extra + * amount of time, sufficient for the transmitter shift register + * to drain at 115200bps, which is the baud rate setting used by + * a standard CFE firmware compilation. + */ + sbd_line_drain(sport); + udelay(100); =20 /* There is no DUART reset feature, so just set some sane defaults. */ write_sbdchn(sport, R_DUART_CMD, V_DUART_MISC_CMD_RESET_TX); From nobody Tue Jun 9 01:01:39 2026 Received: from angie.orcam.me.uk (angie.orcam.me.uk [78.133.224.34]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 375FE3812C2; Sun, 24 May 2026 23:12:12 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=78.133.224.34 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779664335; cv=none; b=Z0oGd6ZcAHGnJzxVwAxUDONkuT25/MNwQf3vHl7KRWBuVk70Uj+lL4F+wu3aVTd/42u/mAQcm5Dqs2yECInVMUtZ13qbqj+3HF+eiV65/PRqdPjrcSCjPmB0MFE6q1zriHMSVS/Ndh9mEPFlP8PviW08bbZGb90rrvWuniICJxM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779664335; c=relaxed/simple; bh=y5JBd1z+ULSIeYgXT46gRAHtBNNNvc2Lumv/sFpaZXU=; h=Date:From:To:cc:Subject:In-Reply-To:Message-ID:References: MIME-Version:Content-Type; b=AfnSWlXLUBgrWqS1JJopotuWKm+xcUqL+7XEd5yrM7Y1XvhA6HaqHmGtJhspCzufQqukSJDpcuYNQFsK1w0bcOF3311JkW+TDM7BqeVqEVWb6BBo7RLMNniTRdTKDc3Na+IX3PTmvpM0Kr5CfzDBN8hvu503n75MSx31Rs97/Ds= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=orcam.me.uk; spf=none smtp.mailfrom=orcam.me.uk; arc=none smtp.client-ip=78.133.224.34 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=orcam.me.uk Authentication-Results: smtp.subspace.kernel.org; spf=none smtp.mailfrom=orcam.me.uk Received: by angie.orcam.me.uk (Postfix, from userid 500) id 77E049200B4; Mon, 25 May 2026 01:12:11 +0200 (CEST) Received: from localhost (localhost [127.0.0.1]) by angie.orcam.me.uk (Postfix) with ESMTP id 75A0392009B; Mon, 25 May 2026 00:12:11 +0100 (BST) Date: Mon, 25 May 2026 00:12:11 +0100 (BST) From: "Maciej W. Rozycki" To: Thomas Bogendoerfer , Greg Kroah-Hartman , Jiri Slaby cc: Elena Reshetova , David Windsor , Kees Cook , Hans Liljestrand , linux-mips@vger.kernel.org, linux-serial@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v2 2/6] serial: sb1250-duart: Fix bootconsole handover lockup In-Reply-To: Message-ID: References: User-Agent: Alpine 2.21 (DEB 202 2017-01-01) 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" Calling sbd_init_port() in the course of setting up the serial device=20 causes line parameters to be messed up and the transmitter disabled. =20 We've been lucky in that no message is usually produced to the kernel=20 log between this call and the later call to uart_set_options() in the=20 course of console setup done by sbd_serial_console_init(), or the system=20 would hang as the console output handler in CFE tried to access a port=20 whose transmitter has been disabled and line parameters messed up. It'll change with the next change to the driver, so fix sbd_init_port()=20 such that line parameters are set for 115200n8 console operation as with=20 the CFE firmware and the transmitter re-enabled after reset. Fixes: 84a9582fd203 ("serial: core: Start managing serial controllers to en= able runtime PM") Signed-off-by: Maciej W. Rozycki Cc: stable@vger.kernel.org # v6.5+ --- Changes from v1 (2/4), : - Sanitise the change heading. --- drivers/tty/serial/sb1250-duart.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) linux-serial-sb1250-duart-prom-console.diff Index: linux-macro/drivers/tty/serial/sb1250-duart.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- linux-macro.orig/drivers/tty/serial/sb1250-duart.c +++ linux-macro/drivers/tty/serial/sb1250-duart.c @@ -542,14 +542,19 @@ static void sbd_init_port(struct sbd_por /* There is no DUART reset feature, so just set some sane defaults. */ write_sbdchn(sport, R_DUART_CMD, V_DUART_MISC_CMD_RESET_TX); write_sbdchn(sport, R_DUART_CMD, V_DUART_MISC_CMD_RESET_RX); - write_sbdchn(sport, R_DUART_MODE_REG_1, V_DUART_BITS_PER_CHAR_8); + write_sbdchn(sport, R_DUART_MODE_REG_1, + V_DUART_PARITY_MODE_NONE | V_DUART_BITS_PER_CHAR_8); write_sbdchn(sport, R_DUART_MODE_REG_2, 0); + write_sbdchn(sport, R_DUART_CLK_SEL, V_DUART_BAUD_RATE(115200)); write_sbdchn(sport, R_DUART_FULL_CTL, V_DUART_INT_TIME(0) | V_DUART_SIG_FULL(15)); write_sbdchn(sport, R_DUART_OPCR_X, 0); write_sbdchn(sport, R_DUART_AUXCTL_X, 0); write_sbdshr(sport, R_DUART_IMRREG((uport->line) % 2), 0); =20 + /* Re-enable transmission for the initial PROM-based console. */ + write_sbdchn(sport, R_DUART_CMD, M_DUART_TX_EN); + sport->initialised =3D 1; } From nobody Tue Jun 9 01:01:39 2026 Received: from angie.orcam.me.uk (angie.orcam.me.uk [78.133.224.34]) by smtp.subspace.kernel.org (Postfix) with ESMTP id EEF0A3B0ADD; Sun, 24 May 2026 23:12:20 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=78.133.224.34 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779664343; cv=none; b=Bkje3i69U0tN69glLOz2w0tooOOXPM5xC8zjCzhm3lG5ckmZLS1cDnJvSyPFLDImzxbI3mr7ClnHbFqUmj9OmFDhutQPk3kQ/waKTFMLjmH/pwij7CkWwGrgFUOTqIdaRnnvwiGF2O9uswUqQDdZvEAekvP+2gOCIijYeSPLmjo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779664343; c=relaxed/simple; bh=vGKZF0H0E5Lc5KPAipyL9drbWVXoIMBf8loyU4afelQ=; h=Date:From:To:cc:Subject:In-Reply-To:Message-ID:References: MIME-Version:Content-Type; b=HtrAVxnIlXBk63Uxgz2LjlZwfXRw0PsPsHIUyyw+lvB0RlwyFmdxfQfVMlDk66UMM2rz4jSYXtWW81gye4V/w5meK+q9tvydoTWDoYexxVdrckqWspUBruA37+VOK8yIBYtG7yEGSnkLqLwYGZnEMS2V2Fl+0agzlWr1FtsHSbg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=orcam.me.uk; spf=none smtp.mailfrom=orcam.me.uk; arc=none smtp.client-ip=78.133.224.34 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=orcam.me.uk Authentication-Results: smtp.subspace.kernel.org; spf=none smtp.mailfrom=orcam.me.uk Received: by angie.orcam.me.uk (Postfix, from userid 500) id 087E49200B4; Mon, 25 May 2026 01:12:20 +0200 (CEST) Received: from localhost (localhost [127.0.0.1]) by angie.orcam.me.uk (Postfix) with ESMTP id 03DC292009E; Mon, 25 May 2026 00:12:19 +0100 (BST) Date: Mon, 25 May 2026 00:12:19 +0100 (BST) From: "Maciej W. Rozycki" To: Thomas Bogendoerfer , Greg Kroah-Hartman , Jiri Slaby cc: Elena Reshetova , David Windsor , Kees Cook , Hans Liljestrand , linux-mips@vger.kernel.org, linux-serial@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v2 3/6] serial: sb1250-duart: Convert to use a platform device In-Reply-To: Message-ID: References: User-Agent: Alpine 2.21 (DEB 202 2017-01-01) 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" Prevent a crash from happening as the first serial port is initialised: pata-swarm: PATA interface at GenBus slot 4 workingset: timestamp_bits=3D62 max_order=3D18 bucket_order=3D0 Block layer SCSI generic (bsg) driver version 0.4 loaded (major 253) CPU 1 Unable to handle kernel paging request at virtual address 000000000= 0000208, epc =3D=3D ffffffff8067f8f8, ra =3D=3D ffffffff80666330 Oops[#1]: CPU: 1 UID: 0 PID: 1 Comm: swapper/0 Not tainted 6.19.0-dirty #27 NONE=20 $ 0 : 0000000000000000 0000000014001fe0 0000000000000020 ffffffff806661= 30 $ 4 : 0000000000000000 a800000100e6f118 ffffffff8112cbc0 00000000000000= 00 $ 8 : 0000000000000002 0000000000000000 0000000000000000 0000000001a800= 00 $12 : 0000000000000000 ffffffff809fd488 000000004ddf14dd ffffffff000000= 00 $16 : a800000100e6f000 0000000000000000 ffffffff8112c1d0 a800000100e6f0= 00 $20 : 0000000000000000 00000000000004d0 0000000000000004 ffffffff8112c1= d0 $24 : 0000000000000001 0000000000000003 = =20 $28 : a80000010007c000 a80000010007fcb0 00000000000000ef ffffffff806663= 30 Hi : fffffffffffffdb9 Lo : 0000000000000035 epc : ffffffff8067f8f8 __dev_fwnode+0x0/0x8 ra : ffffffff80666330 serial_base_ctrl_add+0xb8/0x180 Status: 14001fe3 KX SX UX KERNEL EXL IE=20 Cause : 80800008 (ExcCode 02) BadVA : 0000000000000208 PrId : 03040102 (SiByte SB1) Process swapper/0 (pid: 1, threadinfo=3D(____ptrval____), task=3D(____ptr= val____), tls=3D0000000000000000) Stack : 0000000000000000 ffffffff80cd5178 ffffffff80cd0000 ffffffff8112c1= c8 0000000000000260 ffffffff806655c4 a800000100275bc0 ffffffff8064ac= 88 004000408112c000 0000000000000002 0000000000000000 ffffffff801965= d0 a800000100786ba0 ffffffff80cd5178 a800000100786ba0 00000000000000= 04 a800000100275bc0 0000000000000000 0000000000000000 ffffffff80cd51= 78 0000000000000000 ffffffff8112c1c8 0000000000000260 00000000000004= d0 0000000000000004 ffffffff80bf0000 00000000000000ef ffffffff80d171= dc ffffffff80d17120 ffffffff80d25658 0000000000000000 ffffffff80d500= 00 ffffffff80d2f928 ffffffff80d50000 ffffffff80d25698 ffffffff80cfce= cc 00ffffff80b84428 0000000000000000 0000000000000006 00000000000000= 06 ... Call Trace: [] __dev_fwnode+0x0/0x8 [] serial_base_ctrl_add+0xb8/0x180 [] serial_core_register_port+0x174/0x8e0 [] sbd_init+0xbc/0xf4 [] do_one_initcall+0x64/0x150 [] kernel_init_freeable+0x25c/0x30c [] kernel_init+0x24/0x118 [] ret_from_kernel_thread+0x14/0x1c =20 Code: 67bd0010 03e00008 2402ffea <03e00008> dc820208 67bdffa0 ffbe005= 0 ffb70048 ffb60040=20 =20 ---[ end trace 0000000000000000 ]--- -- where a pointer is dereferenced that has been derived from a null pointer to the port's parent device. Since no device is available with legacy probing and it's not anymore a preferable way to discover devices anyway, switch the driver to using a platform device and use it as the port's parent device. Use platform_driver_probe() because SB1250 DUART devices are embedded=20 onchip the SoC and therefore not that straightforward to remove. An unfortunate consequence of the switch to a platform device is we now=20 hand the console over from the bootconsole much later in the bootstrap.=20 The CFE console handler appears good enough though to work so late and=20 in particular with interrupts enabled. Conversely only starting the console port so late lets the reset code fully utilise our delay handlers, so switch from udelay() to fsleep() for transmitter draining so as to avoid busy-waiting for an excessive amount of time. Since there is one way only remaining to reach sbd_init_port() now, drop=20 the port initialisation marker as no longer needed and go through the=20 channel resets unconditionally. Fixes: 84a9582fd203 ("serial: core: Start managing serial controllers to en= able runtime PM") Signed-off-by: Maciej W. Rozycki Cc: stable@vger.kernel.org # needs to use .remove_new for <=3D 6.10 --- Changes from v1 (3/4), : - Sanitise the change heading. --- arch/mips/sibyte/swarm/platform.c | 97 +++++++++++++++++++++++-- drivers/tty/serial/sb1250-duart.c | 147 +++++++++++++--------------------= ----- 2 files changed, 145 insertions(+), 99 deletions(-) linux-serial-sb1250-duart-platform.diff Index: linux-macro/arch/mips/sibyte/swarm/platform.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- linux-macro.orig/arch/mips/sibyte/swarm/platform.c +++ linux-macro/arch/mips/sibyte/swarm/platform.c @@ -8,7 +8,13 @@ =20 #include #include +#if defined(CONFIG_SIBYTE_BCM1x80) +#include +#include +#else #include +#include +#endif =20 #if defined(CONFIG_SIBYTE_SWARM) || defined(CONFIG_SIBYTE_LITTLESUR) =20 @@ -85,6 +91,82 @@ device_initcall(swarm_pata_init); =20 #endif /* defined(CONFIG_SIBYTE_SWARM) || defined(CONFIG_SIBYTE_LITTLESUR)= */ =20 +#if defined(CONFIG_SIBYTE_BCM1x80) +static struct resource sb1250_duart_resources[][2] =3D { + { + { + .name =3D "sb1250-duart0", + .flags =3D IORESOURCE_MEM, + .start =3D A_BCM1480_DUART0, + .end =3D (A_BCM1480_DUART0 + + 4 * BCM1480_DUART_CHANREG_SPACING - 1), + }, + { + .name =3D "sb1250-duart0", + .flags =3D IORESOURCE_IRQ, + .start =3D K_BCM1480_INT_UART_0, + .end =3D K_BCM1480_INT_UART_1, + }, + }, + { + { + .name =3D "sb1250-duart1", + .flags =3D IORESOURCE_MEM, + .start =3D A_BCM1480_DUART1, + .end =3D (A_BCM1480_DUART1 + + 4 * BCM1480_DUART_CHANREG_SPACING - 1), + }, + { + .name =3D "sb1250-duart1", + .flags =3D IORESOURCE_IRQ, + .start =3D K_BCM1480_INT_UART_2, + .end =3D K_BCM1480_INT_UART_3, + }, + }, +}; +#else /* !defined(CONFIG_SIBYTE_BCM1x80) */ +static struct resource sb1250_duart_resources[][2] =3D { + { + { + .name =3D "sb1250-duart0", + .flags =3D IORESOURCE_MEM, + .start =3D A_DUART, + .end =3D A_DUART + 4 * DUART_CHANREG_SPACING - 1, + }, + { + .name =3D "sb1250-duart0", + .flags =3D IORESOURCE_IRQ, + .start =3D K_INT_UART_0, + .end =3D K_INT_UART_1, + }, + }, +}; +#endif /* !defined(CONFIG_SIBYTE_BCM1x80) */ + +static struct platform_device sb1250_duart_device[] =3D { + { + .name =3D "sb1250-duart", + .id =3D 0, + .resource =3D sb1250_duart_resources[0], + .num_resources =3D ARRAY_SIZE(sb1250_duart_resources[0]), + }, +#if defined(CONFIG_SIBYTE_BCM1x80) + { + .name =3D "sb1250-duart", + .id =3D 1, + .resource =3D sb1250_duart_resources[1], + .num_resources =3D ARRAY_SIZE(sb1250_duart_resources[1]), + }, +#endif +}; + +static struct platform_device *sb1250_duart_devices[] __initdata =3D { + &sb1250_duart_device[0], +#if defined(CONFIG_SIBYTE_BCM1x80) + &sb1250_duart_device[1], +#endif +}; + #define sb1250_dev_struct(num) \ static struct resource sb1250_res##num =3D { \ .name =3D "SB1250 MAC " __stringify(num), \ @@ -113,28 +195,31 @@ static struct platform_device *sb1250_de =20 static int __init sb1250_device_init(void) { - int ret; + int ret1, ret2; + + ret1 =3D platform_add_devices(sb1250_duart_devices, + ARRAY_SIZE(sb1250_duart_devices)); =20 /* Set the number of available units based on the SOC type. */ switch (soc_type) { case K_SYS_SOC_TYPE_BCM1250: case K_SYS_SOC_TYPE_BCM1250_ALT: - ret =3D platform_add_devices(sb1250_devs, 3); + ret2 =3D platform_add_devices(sb1250_devs, 3); break; case K_SYS_SOC_TYPE_BCM1120: case K_SYS_SOC_TYPE_BCM1125: case K_SYS_SOC_TYPE_BCM1125H: case K_SYS_SOC_TYPE_BCM1250_ALT2: /* Hybrid */ - ret =3D platform_add_devices(sb1250_devs, 2); + ret2 =3D platform_add_devices(sb1250_devs, 2); break; case K_SYS_SOC_TYPE_BCM1x55: case K_SYS_SOC_TYPE_BCM1x80: - ret =3D platform_add_devices(sb1250_devs, 4); + ret2 =3D platform_add_devices(sb1250_devs, 4); break; default: - ret =3D -ENODEV; + ret2 =3D 0; break; } - return ret; + return ret1 ? ret1 : ret2; } device_initcall(sb1250_device_init); Index: linux-macro/drivers/tty/serial/sb1250-duart.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- linux-macro.orig/drivers/tty/serial/sb1250-duart.c +++ linux-macro/drivers/tty/serial/sb1250-duart.c @@ -3,7 +3,7 @@ * Support for the asynchronous serial interface (DUART) included * in the BCM1250 and derived System-On-a-Chip (SOC) devices. * - * Copyright (c) 2007 Maciej W. Rozycki + * Copyright (c) 2007, 2026 Maciej W. Rozycki * * Derived from drivers/char/sb1250_duart.c for which the following * copyright applies: @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include @@ -45,10 +46,6 @@ #include #include =20 -#define SBD_CHANREGS(line) A_BCM1480_DUART_CHANREG((line), 0) -#define SBD_CTRLREGS(line) A_BCM1480_DUART_CTRLREG((line), 0) -#define SBD_INT(line) (K_BCM1480_INT_UART_0 + (line)) - #define DUART_CHANREG_SPACING BCM1480_DUART_CHANREG_SPACING =20 #define R_DUART_IMRREG(line) R_BCM1480_DUART_IMRREG(line) @@ -59,10 +56,6 @@ #include #include =20 -#define SBD_CHANREGS(line) A_DUART_CHANREG((line), 0) -#define SBD_CTRLREGS(line) A_DUART_CTRLREG(0) -#define SBD_INT(line) (K_INT_UART_0 + (line)) - #else #error invalid SB1250 UART configuration =20 @@ -85,7 +78,6 @@ struct sbd_port { struct uart_port port; unsigned char __iomem *memctrl; int tx_stopped; - int initialised; }; =20 /* @@ -100,6 +92,7 @@ struct sbd_duart { #define to_sport(uport) container_of(uport, struct sbd_port, port) =20 static struct sbd_duart sbd_duarts[DUART_MAX_CHIP]; +static struct uart_driver sbd_reg; =20 =20 /* @@ -514,8 +507,6 @@ static void sbd_init_port(struct sbd_por { struct uart_port *uport =3D &sport->port; =20 - if (sport->initialised) - return; /* * Contrary to documentation, which says that the transmitter * empty bit is set when "there are no characters to send and @@ -537,7 +528,7 @@ static void sbd_init_port(struct sbd_por * a standard CFE firmware compilation. */ sbd_line_drain(sport); - udelay(100); + fsleep(100); =20 /* There is no DUART reset feature, so just set some sane defaults. */ write_sbdchn(sport, R_DUART_CMD, V_DUART_MISC_CMD_RESET_TX); @@ -554,8 +545,6 @@ static void sbd_init_port(struct sbd_por =20 /* Re-enable transmission for the initial PROM-based console. */ write_sbdchn(sport, R_DUART_CMD, M_DUART_TX_EN); - - sport->initialised =3D 1; } =20 static void sbd_set_termios(struct uart_port *uport, struct ktermios *term= ios, @@ -794,50 +783,54 @@ static const struct uart_ops sbd_ops =3D { }; =20 /* Initialize SB1250 DUART port structures. */ -static void __init sbd_probe_duarts(void) +static int __init sbd_probe(struct platform_device *pdev) { - static int probed; + struct resource *mem_resource, *irq_resource; int chip, side; - int max_lines, line; =20 - if (probed) - return; + mem_resource =3D platform_get_resource(pdev, IORESOURCE_MEM, 0); + irq_resource =3D platform_get_resource(pdev, IORESOURCE_IRQ, 0); + if (!mem_resource || !irq_resource) + return -ENODEV; =20 - /* Set the number of available units based on the SOC type. */ - switch (soc_type) { - case K_SYS_SOC_TYPE_BCM1x55: - case K_SYS_SOC_TYPE_BCM1x80: - max_lines =3D 4; - break; - default: - /* Assume at least two serial ports at the normal address. */ - max_lines =3D 2; - break; - } + chip =3D pdev->id; + sbd_duarts[chip].mapctrl =3D mem_resource->start + + DUART_CHANREG_SPACING * 3; + for (side =3D 0; side < DUART_MAX_SIDE; side++) { + struct sbd_port *sport =3D &sbd_duarts[chip].sport[side]; + struct uart_port *uport =3D &sport->port; =20 - probed =3D 1; + sport->duart =3D &sbd_duarts[chip]; =20 - for (chip =3D 0, line =3D 0; chip < DUART_MAX_CHIP && line < max_lines; - chip++) { - sbd_duarts[chip].mapctrl =3D SBD_CTRLREGS(line); + uport->dev =3D &pdev->dev; + uport->irq =3D irq_resource->start + side; + uport->uartclk =3D 100000000 / 20 * 16; + uport->fifosize =3D 16; + uport->iotype =3D UPIO_MEM; + uport->flags =3D UPF_BOOT_AUTOCONF; + uport->ops =3D &sbd_ops; + uport->line =3D chip * DUART_MAX_SIDE + side; + uport->mapbase =3D mem_resource->start + + DUART_CHANREG_SPACING * (side + 1); + uport->has_sysrq =3D IS_ENABLED(CONFIG_SERIAL_SB1250_DUART_CONSOLE); + if (uart_add_one_port(&sbd_reg, uport)) + uport->dev =3D NULL; + } =20 - for (side =3D 0; side < DUART_MAX_SIDE && line < max_lines; - side++, line++) { - struct sbd_port *sport =3D &sbd_duarts[chip].sport[side]; - struct uart_port *uport =3D &sport->port; + return 0; +} =20 - sport->duart =3D &sbd_duarts[chip]; +static void __exit sbd_remove(struct platform_device *pdev) +{ + int chip, side; =20 - uport->irq =3D SBD_INT(line); - uport->uartclk =3D 100000000 / 20 * 16; - uport->fifosize =3D 16; - uport->iotype =3D UPIO_MEM; - uport->flags =3D UPF_BOOT_AUTOCONF; - uport->ops =3D &sbd_ops; - uport->line =3D line; - uport->mapbase =3D SBD_CHANREGS(line); - uport->has_sysrq =3D IS_ENABLED(CONFIG_SERIAL_SB1250_DUART_CONSOLE); - } + chip =3D pdev->id; + for (side =3D DUART_MAX_SIDE - 1; side >=3D 0; side--) { + struct sbd_port *sport =3D &sbd_duarts[chip].sport[side]; + struct uart_port *uport =3D &sport->port; + + if (uport->dev) + uart_remove_one_port(&sbd_reg, uport); } } =20 @@ -895,23 +888,14 @@ static int __init sbd_console_setup(stru int bits =3D 8; int parity =3D 'n'; int flow =3D 'n'; - int ret; =20 if (!sport->duart) return -ENXIO; - - ret =3D sbd_map_port(uport); - if (ret) - return ret; - - sbd_init_port(sport); - if (options) uart_parse_options(options, &baud, &parity, &bits, &flow); return uart_set_options(uport, co, baud, parity, bits, flow); } =20 -static struct uart_driver sbd_reg; static struct console sbd_console =3D { .name =3D "duart", .write =3D sbd_console_write, @@ -922,16 +906,6 @@ static struct console sbd_console =3D { .data =3D &sbd_reg }; =20 -static int __init sbd_serial_console_init(void) -{ - sbd_probe_duarts(); - register_console(&sbd_console); - - return 0; -} - -console_initcall(sbd_serial_console_init); - #define SERIAL_SB1250_DUART_CONSOLE &sbd_console #else #define SERIAL_SB1250_DUART_CONSOLE NULL @@ -948,43 +922,30 @@ static struct uart_driver sbd_reg =3D { .cons =3D SERIAL_SB1250_DUART_CONSOLE, }; =20 +static struct platform_driver sbd_driver =3D { + .remove =3D __exit_p(sbd_remove), + .driver =3D { .name =3D "sb1250-duart" }, +}; + /* Set up the driver and register it. */ static int __init sbd_init(void) { - int i, ret; - - sbd_probe_duarts(); + int ret; =20 ret =3D uart_register_driver(&sbd_reg); if (ret) return ret; + ret =3D platform_driver_probe(&sbd_driver, sbd_probe); + if (ret) + uart_unregister_driver(&sbd_reg); =20 - for (i =3D 0; i < DUART_MAX_CHIP * DUART_MAX_SIDE; i++) { - struct sbd_duart *duart =3D &sbd_duarts[i / DUART_MAX_SIDE]; - struct sbd_port *sport =3D &duart->sport[i % DUART_MAX_SIDE]; - struct uart_port *uport =3D &sport->port; - - if (sport->duart) - uart_add_one_port(&sbd_reg, uport); - } - - return 0; + return ret; } =20 /* Unload the driver. Unregister stuff, get ready to go away. */ static void __exit sbd_exit(void) { - int i; - - for (i =3D DUART_MAX_CHIP * DUART_MAX_SIDE - 1; i >=3D 0; i--) { - struct sbd_duart *duart =3D &sbd_duarts[i / DUART_MAX_SIDE]; - struct sbd_port *sport =3D &duart->sport[i % DUART_MAX_SIDE]; - struct uart_port *uport =3D &sport->port; - - if (sport->duart) - uart_remove_one_port(&sbd_reg, uport); - } - + platform_driver_unregister(&sbd_driver); uart_unregister_driver(&sbd_reg); } From nobody Tue Jun 9 01:01:39 2026 Received: from angie.orcam.me.uk (angie.orcam.me.uk [78.133.224.34]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 95DFA3B3BF0; Sun, 24 May 2026 23:12:26 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=78.133.224.34 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779664348; cv=none; b=XmE4MKImacPQ3PZNpSdTVOl+arSIGsoMdoZdjGu1TOsUhCwWyOJm4FDgtXDl13r1cOMiwWufb1Mn/6cVv/k5/Dbyyw6HJ2fa45glI45AetDktdPv7KoEzWXOXE48cq474eNd3dm/irFSEQoqR7UAvJifuK58jUqz0Ol+KL5shJc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779664348; c=relaxed/simple; bh=zZ3NDP9gal7k+hEf6zlir6KCHnEXv34AglStD6PZ2qc=; h=Date:From:To:cc:Subject:In-Reply-To:Message-ID:References: MIME-Version:Content-Type; b=GjN11YGmrz5+N8vOIRpTsXy6hch/3syY0waHD2c0+nHpi1OazjclKTbPwUynYHSoIiLDk25l5zzwZB+rP/PS/9nsU0/IE+nS5BkukRsfXZZ1i/LmVmwBezgyrRVAnTR9Z+akVSe9vJLkScZlYu+YcbI3Ezk30vIZn9OSBH/qksg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=orcam.me.uk; spf=none smtp.mailfrom=orcam.me.uk; arc=none smtp.client-ip=78.133.224.34 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=orcam.me.uk Authentication-Results: smtp.subspace.kernel.org; spf=none smtp.mailfrom=orcam.me.uk Received: by angie.orcam.me.uk (Postfix, from userid 500) id 0C9379200B4; Mon, 25 May 2026 01:12:25 +0200 (CEST) Received: from localhost (localhost [127.0.0.1]) by angie.orcam.me.uk (Postfix) with ESMTP id 0572592009E; Mon, 25 May 2026 00:12:24 +0100 (BST) Date: Mon, 25 May 2026 00:12:24 +0100 (BST) From: "Maciej W. Rozycki" To: Thomas Bogendoerfer , Greg Kroah-Hartman , Jiri Slaby cc: Elena Reshetova , David Windsor , Kees Cook , Hans Liljestrand , linux-mips@vger.kernel.org, linux-serial@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v2 4/6] Revert "drivers: convert sbd_duart.map_guard from atomic_t to refcount_t" In-Reply-To: Message-ID: References: User-Agent: Alpine 2.21 (DEB 202 2017-01-01) 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" Revert commit 22a33651a56f ("drivers: convert sbd_duart.map_guard from atomic_t to refcount_t"), which broke perfectly valid code: ------------[ cut here ]------------ WARNING: CPU: 1 PID: 1 at lib/refcount.c:114 sbd_request_port+0x54/0x140 refcount_t: increment on 0; use-after-free. CPU: 1 PID: 1 Comm: swapper/0 Not tainted 4.11.0-rc2+ #34 Stack : 0000000014001fe0 0000000000000000 ffffffff80830000 00000000000000= 00 ffffffff8127bc7a ffffffff8016fe08 ffffffff808d0000 ffffffff808d00= 00 ffffffff807aa828 ffffffff80822337 ffffffff808ce188 a8000001860b00= 00 0000000000000001 0000000000000001 00000000000001c8 ffffffff808a30= 90 00000000000000bb ffffffff801b09d4 a80000018609bb68 ffffffff801231= cc ffffffff812a0000 ffffffff80171388 0000000000001000 ffffffff807aa8= 28 0000000000000001 0000000000000001 0000000000000000 00000000000000= 00 0000000000000000 a80000018609bab0 0000000000000000 ffffffff803c47= cc 0000000000000000 0000000000000000 0000000000000000 00000000000000= 00 ffffffff807cb648 ffffffff8010bff8 0000000014001fe1 ffffffff803c47= cc ... Call Trace: [] show_stack+0x28/0x88 [] dump_stack+0x8c/0xc0 [] __warn+0xe0/0x114 [] warn_slowpath_fmt+0x40/0x50 [] sbd_request_port+0x54/0x140 [] sbd_config_port+0x2c/0x68 ---[ end trace f666d696412caa3e ]--- (report at the offending commit) -- sbd_request_port() is called twice per DUART instance, to reserve a resource holding the control register block shared between the two channels, so there's no slightest chance for an overflow. Also this doesn't stop the driver from working and it's just the reservation that is missing as a result, i.e.: 10060100-100601ff : sb1250-duart 10060200-100602ff : sb1250-duart as from the offending change, vs: 10060100-100601ff : sb1250-duart 10060200-100602ff : sb1250-duart 10060300-100603ff : sb1250-duart beforehand, which is surely why the breakage has gone so long unnoticed. "If it ain't broke, don't fix it," so just revert the broken commit. Fixes: 22a33651a56f ("drivers: convert sbd_duart.map_guard from atomic_t to= refcount_t") Signed-off-by: Maciej W. Rozycki --- No change from v1 (4/4), . --- drivers/tty/serial/sb1250-duart.c | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) linux-serial-sb1250-duart-map-guard-atomic.diff Index: linux-macro/drivers/tty/serial/sb1250-duart.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- linux-macro.orig/drivers/tty/serial/sb1250-duart.c +++ linux-macro/drivers/tty/serial/sb1250-duart.c @@ -34,8 +34,8 @@ #include #include =20 -#include -#include +#include +#include =20 #include #include @@ -86,7 +86,7 @@ struct sbd_port { struct sbd_duart { struct sbd_port sport[2]; unsigned long mapctrl; - refcount_t map_guard; + atomic_t map_guard; }; =20 #define to_sport(uport) container_of(uport, struct sbd_port, port) @@ -662,13 +662,15 @@ static void sbd_release_port(struct uart { struct sbd_port *sport =3D to_sport(uport); struct sbd_duart *duart =3D sport->duart; + int map_guard; =20 iounmap(sport->memctrl); sport->memctrl =3D NULL; iounmap(uport->membase); uport->membase =3D NULL; =20 - if(refcount_dec_and_test(&duart->map_guard)) + map_guard =3D atomic_add_return(-1, &duart->map_guard); + if (!map_guard) release_mem_region(duart->mapctrl, DUART_CHANREG_SPACING); release_mem_region(uport->mapbase, DUART_CHANREG_SPACING); } @@ -704,6 +706,7 @@ static int sbd_request_port(struct uart_ { const char *err =3D KERN_ERR "sbd: Unable to reserve MMIO resource\n"; struct sbd_duart *duart =3D to_sport(uport)->duart; + int map_guard; int ret =3D 0; =20 if (!request_mem_region(uport->mapbase, DUART_CHANREG_SPACING, @@ -711,11 +714,11 @@ static int sbd_request_port(struct uart_ printk(err); return -EBUSY; } - refcount_inc(&duart->map_guard); - if (refcount_read(&duart->map_guard) =3D=3D 1) { + map_guard =3D atomic_add_return(1, &duart->map_guard); + if (map_guard =3D=3D 1) { if (!request_mem_region(duart->mapctrl, DUART_CHANREG_SPACING, "sb1250-duart")) { - refcount_dec(&duart->map_guard); + atomic_add(-1, &duart->map_guard); printk(err); ret =3D -EBUSY; } @@ -723,7 +726,8 @@ static int sbd_request_port(struct uart_ if (!ret) { ret =3D sbd_map_port(uport); if (ret) { - if (refcount_dec_and_test(&duart->map_guard)) + map_guard =3D atomic_add_return(-1, &duart->map_guard); + if (!map_guard) release_mem_region(duart->mapctrl, DUART_CHANREG_SPACING); } From nobody Tue Jun 9 01:01:39 2026 Received: from angie.orcam.me.uk (angie.orcam.me.uk [78.133.224.34]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 9E7E33B0ADD; Sun, 24 May 2026 23:12:30 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=78.133.224.34 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779664352; cv=none; b=SsRQN3r6yXTJxjYmVsSpVwHvWTtsm/gQc4VP4YsW8pR0WBHvSCLag1NOVrWsoR1c35XvGz2IvsuIqfLVbVPiIDXspKPtUWXyrohu3KrGhIYSeFGWu1OjzgI8C4fyPYGreqPaMUvEPS1Ffj9TUJB7ASDCkd3sayZ7Jht+BuFHTPM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779664352; c=relaxed/simple; bh=z54peA8XItYsMuM7laktWvaNwWCvsNnEOFJlL/FUf+Q=; h=Date:From:To:cc:Subject:In-Reply-To:Message-ID:References: MIME-Version:Content-Type; b=lcGsZDRgCjJgEKQ/KQmmuiopJarXyDGxet7NtcHkkhiaFSAvlOEQ84VuNrGaAq05F+Uhr8lWgrEnZlCHBhb+5APSjaHNN4gAEa+QDHfdsW7fThCCaBbKVp2jRQ97brCD5PmKxBBamtDl81Sud1qCv2vwV6k/0jDrJySuFJFufVg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=orcam.me.uk; spf=none smtp.mailfrom=orcam.me.uk; arc=none smtp.client-ip=78.133.224.34 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=orcam.me.uk Authentication-Results: smtp.subspace.kernel.org; spf=none smtp.mailfrom=orcam.me.uk Received: by angie.orcam.me.uk (Postfix, from userid 500) id A89BD92009E; Mon, 25 May 2026 01:12:29 +0200 (CEST) Received: from localhost (localhost [127.0.0.1]) by angie.orcam.me.uk (Postfix) with ESMTP id A213492009D; Mon, 25 May 2026 00:12:29 +0100 (BST) Date: Mon, 25 May 2026 00:12:29 +0100 (BST) From: "Maciej W. Rozycki" To: Thomas Bogendoerfer , Greg Kroah-Hartman , Jiri Slaby cc: Elena Reshetova , David Windsor , Kees Cook , Hans Liljestrand , linux-mips@vger.kernel.org, linux-serial@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v2 5/6] serial: sb1250-duart: Switch to spinlock protection for shared resource In-Reply-To: Message-ID: References: User-Agent: Alpine 2.21 (DEB 202 2017-01-01) 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 control register block is shared between DUART channels and so its=20 resource has to be requested by the first channel claimed and released=20 by the last one dropped. It is currently handled with an atomic counter, which however does not=20 protect against a situation where request_mem_region() has failed, but=20 another CPU has seen the map guard nonzero and refrained from calling=20 this function for another channel where it should have (and likely also=20 fail). This parallel execution scenario can in principle be arranged=20 via the TIOCSSERIAL ioctl. Switch to using an ordinary counter then and spinlock protection for the=20 counter updates along with the corresponding resource request/release=20 calls, so that the case described above is covered. Fixes: b45d52797432 ("sb1250-duart.c: SB1250 DUART serial support") Signed-off-by: Maciej W. Rozycki --- New change in v2. --- drivers/tty/serial/sb1250-duart.c | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) linux-serial-sb1250-duart-map-guard-spinlock.diff Index: linux-macro/drivers/tty/serial/sb1250-duart.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- linux-macro.orig/drivers/tty/serial/sb1250-duart.c +++ linux-macro/drivers/tty/serial/sb1250-duart.c @@ -86,7 +86,8 @@ struct sbd_port { struct sbd_duart { struct sbd_port sport[2]; unsigned long mapctrl; - atomic_t map_guard; + spinlock_t map_lock; + int map_guard; }; =20 #define to_sport(uport) container_of(uport, struct sbd_port, port) @@ -662,16 +663,18 @@ static void sbd_release_port(struct uart { struct sbd_port *sport =3D to_sport(uport); struct sbd_duart *duart =3D sport->duart; - int map_guard; + unsigned long flags; =20 iounmap(sport->memctrl); sport->memctrl =3D NULL; iounmap(uport->membase); uport->membase =3D NULL; =20 - map_guard =3D atomic_add_return(-1, &duart->map_guard); - if (!map_guard) + spin_lock_irqsave(&duart->map_lock, flags); + if (!--duart->map_guard) release_mem_region(duart->mapctrl, DUART_CHANREG_SPACING); + spin_unlock_irqrestore(&duart->map_lock, flags); + release_mem_region(uport->mapbase, DUART_CHANREG_SPACING); } =20 @@ -706,7 +709,7 @@ static int sbd_request_port(struct uart_ { const char *err =3D KERN_ERR "sbd: Unable to reserve MMIO resource\n"; struct sbd_duart *duart =3D to_sport(uport)->duart; - int map_guard; + unsigned long flags; int ret =3D 0; =20 if (!request_mem_region(uport->mapbase, DUART_CHANREG_SPACING, @@ -714,22 +717,26 @@ static int sbd_request_port(struct uart_ printk(err); return -EBUSY; } - map_guard =3D atomic_add_return(1, &duart->map_guard); - if (map_guard =3D=3D 1) { + + spin_lock_irqsave(&duart->map_lock, flags); + if (!duart->map_guard++) { if (!request_mem_region(duart->mapctrl, DUART_CHANREG_SPACING, "sb1250-duart")) { - atomic_add(-1, &duart->map_guard); + --duart->map_guard; printk(err); ret =3D -EBUSY; } } + spin_unlock_irqrestore(&duart->map_lock, flags); + if (!ret) { ret =3D sbd_map_port(uport); if (ret) { - map_guard =3D atomic_add_return(-1, &duart->map_guard); - if (!map_guard) + spin_lock_irqsave(&duart->map_lock, flags); + if (!--duart->map_guard) release_mem_region(duart->mapctrl, DUART_CHANREG_SPACING); + spin_unlock_irqrestore(&duart->map_lock, flags); } } if (ret) { @@ -800,6 +807,7 @@ static int __init sbd_probe(struct platf chip =3D pdev->id; sbd_duarts[chip].mapctrl =3D mem_resource->start + DUART_CHANREG_SPACING * 3; + spin_lock_init(&sbd_duarts[chip].map_lock); for (side =3D 0; side < DUART_MAX_SIDE; side++) { struct sbd_port *sport =3D &sbd_duarts[chip].sport[side]; struct uart_port *uport =3D &sport->port; From nobody Tue Jun 9 01:01:39 2026 Received: from angie.orcam.me.uk (angie.orcam.me.uk [78.133.224.34]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 170923B3BF2; Sun, 24 May 2026 23:12:36 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=78.133.224.34 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779664358; cv=none; b=VVMsS0DHLEnB5VslGVKLjK7H4xqt2/Ob/4dNF0uXoSyrZrbsMI4IypX7MVIzqAmpCHLC9qiL9cgsmFjuoSc2VFPNUK3YlEVyoMgPrjZDdC44V2bsjFC38TavsflcEqxpSeJCoeFmxHjH+RssDRF+w/LcRhjkLXILodYU/R2MO9s= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779664358; c=relaxed/simple; bh=5NMfh6aMaAzIdfTqrok+ogFVcaOO0Qo/oCPcajGXADI=; h=Date:From:To:cc:Subject:In-Reply-To:Message-ID:References: MIME-Version:Content-Type; b=uDi6onp3FubO6OSXrPQd4lNmqwNconuZ4t+MCG471cb1HBzyMNndsWP26YZ/MZCiFDgKqyqeCbKXCPXEqJBReUbgC8s+Xq78ML3sL1w4BFJgkpe+FqphGN4+uct9Hedy6s9Os56Kf2EpKIvfuEWiaBmiIT/371ASqdhOQf94ilE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=orcam.me.uk; spf=none smtp.mailfrom=orcam.me.uk; arc=none smtp.client-ip=78.133.224.34 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=orcam.me.uk Authentication-Results: smtp.subspace.kernel.org; spf=none smtp.mailfrom=orcam.me.uk Received: by angie.orcam.me.uk (Postfix, from userid 500) id 273329200BF; Mon, 25 May 2026 01:12:36 +0200 (CEST) Received: from localhost (localhost [127.0.0.1]) by angie.orcam.me.uk (Postfix) with ESMTP id 23A3B9200B4; Mon, 25 May 2026 00:12:36 +0100 (BST) Date: Mon, 25 May 2026 00:12:36 +0100 (BST) From: "Maciej W. Rozycki" To: Thomas Bogendoerfer , Greg Kroah-Hartman , Jiri Slaby cc: Elena Reshetova , David Windsor , Kees Cook , Hans Liljestrand , linux-mips@vger.kernel.org, linux-serial@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v2 6/6] MAINTAINERS: Add self for the sb1250-duart serial driver In-Reply-To: Message-ID: References: User-Agent: Alpine 2.21 (DEB 202 2017-01-01) 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" I wrote this driver and seem to have been the main remaining user now. Signed-off-by: Maciej W. Rozycki --- New change in v2. --- MAINTAINERS | 5 +++++ 1 file changed, 5 insertions(+) linux-serial-sb1250-duart-maintainers.diff Index: linux-macro/MAINTAINERS =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- linux-macro.orig/MAINTAINERS +++ linux-macro/MAINTAINERS @@ -23658,6 +23658,11 @@ R: Marc Murphy +S: Maintained +F: drivers/tty/serial/sb1250-duart.c + SC1200 WDT DRIVER M: Zwane Mwaikambo S: Maintained