All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Ilpo Järvinen" <ilpo.jarvinen@linux.intel.com>
To: "Jiri Slaby (SUSE)" <jirislaby@kernel.org>
Cc: "Greg Kroah-Hartman" <gregkh@linuxfoundation.org>,
	"Vadim Fedorenko" <vadim.fedorenko@linux.dev>,
	"Richard Cochran" <richardcochran@gmail.com>,
	"Andrew Lunn" <andrew+netdev@lunn.ch>,
	"David S. Miller" <davem@davemloft.net>,
	"Eric Dumazet" <edumazet@kernel.org>,
	"Jakub Kicinski" <kuba@kernel.org>,
	"Paolo Abeni" <pabeni@redhat.com>,
	"Joel Stanley" <joel@jms.id.au>,
	"Andrew Jeffery" <andrew@codeconstruct.com.au>,
	"Ryan Chen" <ryan_chen@aspeedtech.com>,
	"Billy Tsai" <billy_tsai@aspeedtech.com>,
	"Florian Fainelli" <florian.fainelli@broadcom.com>,
	"Broadcom internal kernel review list"
	<bcm-kernel-feedback-list@broadcom.com>,
	"Ray Jui" <rjui@broadcom.com>,
	"Scott Branden" <sbranden@broadcom.com>,
	"Al Cooper" <alcooperx@gmail.com>,
	"Andy Shevchenko" <andriy.shevchenko@linux.intel.com>,
	"Paul Cercueil" <paul@crapouillou.net>,
	"Matthias Brugger" <matthias.bgg@gmail.com>,
	"AngeloGioacchino Del Regno"
	<angelogioacchino.delregno@collabora.com>,
	"Chaitanya Vadrevu" <chaitanya.vadrevu@emerson.com>,
	"James E.J. Bottomley" <James.Bottomley@HansenPartnership.com>,
	"Helge Deller" <deller@gmx.de>,
	"Kumaravel Thiagarajan" <kumaravel.thiagarajan@microchip.com>,
	"Thierry Reding" <thierry.reding@kernel.org>,
	"Jonathan Hunter" <jonathanh@nvidia.com>,
	"Kunihiko Hayashi" <hayashi.kunihiko@socionext.com>,
	"Masami Hiramatsu" <mhiramat@kernel.org>,
	"Kees Cook" <kees@kernel.org>,
	"Gustavo A. R. Silva" <gustavoars@kernel.org>,
	"Uwe Kleine-König (The Capable Hub)"
	<u.kleine-koenig@baylibre.com>, Netdev <netdev@vger.kernel.org>,
	linux-serial <linux-serial@vger.kernel.org>,
	linux-arm-kernel@lists.infradead.org,
	linux-aspeed@lists.ozlabs.org,
	linux-rpi-kernel@lists.infradead.org, linux-mips@vger.kernel.org,
	linux-mediatek@lists.infradead.org, linux-parisc@vger.kernel.org,
	linux-tegra@vger.kernel.org, linux-hardening@vger.kernel.org
Subject: Re: [PATCH 3/3] serial: 8250: make port operations work on struct uart_8250_port
Date: Fri, 9 Oct 2026 14:25:36 +0300 (EEST)	[thread overview]
Message-ID: <9a08fb1a-1e2d-6477-06db-b201c8c425b4@linux.intel.com> (raw)
In-Reply-To: <dde18b78e0988a2c45e84c13938f1521e5c8b9f9.1791524724.git.jirislaby@kernel.org>

[-- Attachment #1: Type: text/plain, Size: 50464 bytes --]

On Fri, 9 Oct 2026, Jiri Slaby (SUSE) wrote:

> serial8250_register_8250_port() returns a line number and the other
> port operations (serial8250_unregister_port(), serial8250_suspend_port(),
> serial8250_resume_port()) accept it. Many drivers then convert the line
> back to the port using serial8250_get_port() anyway.
> 
> Switch the interface to struct uart_8250_port:
> * serial8250_register_8250_port() now returns the registered port, or
> an ERR_PTR() on failure.
> * serial8250_unregister_port(), serial8250_suspend_port() and
> serial8250_resume_port() accept the port.
> 
> Convert all users accordingly. Drivers store the port pointer instead
> of the line number. Several drivers kept a private struct only to hold
> the line (airoha, dfl, em, fsl, ioc3); these are dropped and the port
> is stored as drvdata directly.
> 
> This also fixes two latent issues:
> * For a CIR port, serial8250_register_8250_port() used to return 0.
> Callers stored this as the line, so a later unregister/suspend/resume
> operated on ttyS0. Now the CIR port itself is returned.
> * 8250_acorn checked ports[i] > 0 on removal, so a port registered as
> line 0 was never unregistered.
> 
> There are no more users of serial8250_get_port() outside of the 8250
> core, so drop its EXPORT.
> 
> Signed-off-by: Jiri Slaby (SUSE) <jirislaby@kernel.org>
> Assisted-by: LLM
> ---
> Cc: Vadim Fedorenko <vadim.fedorenko@linux.dev>
> Cc: Richard Cochran <richardcochran@gmail.com>
> Cc: Andrew Lunn <andrew+netdev@lunn.ch>
> Cc: "David S. Miller" <davem@davemloft.net>
> Cc: Eric Dumazet <edumazet@kernel.org>
> Cc: Jakub Kicinski <kuba@kernel.org>
> Cc: Paolo Abeni <pabeni@redhat.com>
> Cc: Joel Stanley <joel@jms.id.au>
> Cc: Andrew Jeffery <andrew@codeconstruct.com.au>
> Cc: Ryan Chen <ryan_chen@aspeedtech.com>
> Cc: Billy Tsai <billy_tsai@aspeedtech.com>
> Cc: Florian Fainelli <florian.fainelli@broadcom.com>
> Cc: Broadcom internal kernel review list <bcm-kernel-feedback-list@broadcom.com>
> Cc: Ray Jui <rjui@broadcom.com>
> Cc: Scott Branden <sbranden@broadcom.com>
> Cc: Al Cooper <alcooperx@gmail.com>
> Cc: "Ilpo Järvinen" <ilpo.jarvinen@linux.intel.com>
> Cc: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
> Cc: Paul Cercueil <paul@crapouillou.net>
> Cc: Matthias Brugger <matthias.bgg@gmail.com>
> Cc: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
> Cc: Chaitanya Vadrevu <chaitanya.vadrevu@emerson.com>
> Cc: "James E.J. Bottomley" <James.Bottomley@HansenPartnership.com>
> Cc: Helge Deller <deller@gmx.de>
> Cc: Kumaravel Thiagarajan <kumaravel.thiagarajan@microchip.com>
> Cc: Thierry Reding <thierry.reding@kernel.org>
> Cc: Jonathan Hunter <jonathanh@nvidia.com>
> Cc: Kunihiko Hayashi <hayashi.kunihiko@socionext.com>
> Cc: Masami Hiramatsu <mhiramat@kernel.org>
> Cc: Kees Cook <kees@kernel.org>
> Cc: "Gustavo A. R. Silva" <gustavoars@kernel.org>
> Cc: "Uwe Kleine-König (The Capable Hub)" <u.kleine-koenig@baylibre.com>
> Cc: netdev@vger.kernel.org
> Cc: linux-serial@vger.kernel.org
> Cc: linux-arm-kernel@lists.infradead.org
> Cc: linux-aspeed@lists.ozlabs.org
> Cc: linux-rpi-kernel@lists.infradead.org
> Cc: linux-mips@vger.kernel.org
> Cc: linux-mediatek@lists.infradead.org
> Cc: linux-parisc@vger.kernel.org
> Cc: linux-tegra@vger.kernel.org
> Cc: linux-hardening@vger.kernel.org
> ---
>  drivers/ptp/ptp_ocp.c                       | 36 +++++++++---------
>  drivers/tty/serial/8250/8250_acorn.c        |  5 ++-
>  drivers/tty/serial/8250/8250_airoha.c       | 22 +++--------
>  drivers/tty/serial/8250/8250_aspeed_vuart.c | 12 +++---
>  drivers/tty/serial/8250/8250_bcm2835aux.c   | 19 +++++-----
>  drivers/tty/serial/8250/8250_bcm7271.c      | 32 +++++++---------
>  drivers/tty/serial/8250/8250_core.c         | 37 +++++++------------
>  drivers/tty/serial/8250/8250_dfl.c          | 21 +++--------
>  drivers/tty/serial/8250/8250_dw.c           | 12 +++---
>  drivers/tty/serial/8250/8250_dwlib.h        |  2 +-
>  drivers/tty/serial/8250/8250_em.c           | 25 ++++---------
>  drivers/tty/serial/8250/8250_exar.c         | 21 +++++------
>  drivers/tty/serial/8250/8250_fsl.c          | 23 ++++--------
>  drivers/tty/serial/8250/8250_hp300.c        | 27 ++++++--------
>  drivers/tty/serial/8250/8250_ingenic.c      | 10 ++---
>  drivers/tty/serial/8250/8250_ioc3.c         | 25 ++++---------
>  drivers/tty/serial/8250/8250_keba.c         | 13 +++----
>  drivers/tty/serial/8250/8250_loongson.c     | 19 +++++-----
>  drivers/tty/serial/8250/8250_lpc18xx.c      | 10 ++---
>  drivers/tty/serial/8250/8250_lpss.c         | 21 ++++-------
>  drivers/tty/serial/8250/8250_men_mcb.c      | 13 +++----
>  drivers/tty/serial/8250/8250_mid.c          | 12 +++---
>  drivers/tty/serial/8250/8250_mtk.c          | 18 ++++-----
>  drivers/tty/serial/8250/8250_mxpcie.c       | 13 ++++---
>  drivers/tty/serial/8250/8250_ni.c           | 11 +++---
>  drivers/tty/serial/8250/8250_of.c           | 24 ++++++------
>  drivers/tty/serial/8250/8250_omap.c         | 41 +++++++++------------
>  drivers/tty/serial/8250/8250_parisc.c       | 13 +++----
>  drivers/tty/serial/8250/8250_pci.c          | 21 +++++------
>  drivers/tty/serial/8250/8250_pci1xxxx.c     | 40 ++++++++++----------
>  drivers/tty/serial/8250/8250_pericom.c      | 14 +++----
>  drivers/tty/serial/8250/8250_platform.c     | 22 +++++------
>  drivers/tty/serial/8250/8250_pnp.c          | 20 +++++-----
>  drivers/tty/serial/8250/8250_pxa.c          | 16 ++++----
>  drivers/tty/serial/8250/8250_tegra.c        | 19 +++++-----
>  drivers/tty/serial/8250/8250_uniphier.c     | 20 +++++-----
>  drivers/tty/serial/8250/serial_cs.c         | 14 +++----
>  include/linux/serial_8250.h                 |  8 ++--
>  38 files changed, 319 insertions(+), 412 deletions(-)
> 
> diff --git a/drivers/ptp/ptp_ocp.c b/drivers/ptp/ptp_ocp.c
> index 2802989e8494..609cee1d2c80 100644
> --- a/drivers/ptp/ptp_ocp.c
> +++ b/drivers/ptp/ptp_ocp.c
> @@ -344,7 +344,7 @@ struct ptp_ocp_signal {
>  };
>  
>  struct ptp_ocp_serial_port {
> -	int line;
> +	struct uart_8250_port *uport;
>  	int baud;
>  };
>  
> @@ -2629,7 +2629,7 @@ ptp_ocp_register_ext(struct ptp_ocp *bp, struct ocp_resource *r)
>  	return err;
>  }
>  
> -static int
> +static struct uart_8250_port *
>  ptp_ocp_serial_line(struct ptp_ocp *bp, struct ocp_resource *r)
>  {
>  	struct pci_dev *pdev = bp->pdev;
> @@ -2657,9 +2657,11 @@ ptp_ocp_register_serial(struct ptp_ocp *bp, struct ocp_resource *r)
>  	struct ptp_ocp_serial_port *p = (struct ptp_ocp_serial_port *)r->extra;
>  	struct ptp_ocp_serial_port port = {};
>  
> -	port.line = ptp_ocp_serial_line(bp, r);
> -	if (port.line < 0)
> -		return port.line;
> +	struct uart_8250_port *uport = ptp_ocp_serial_line(bp, r);
> +	if (IS_ERR(uport))
> +		return PTR_ERR(uport);
> +
> +	port.uport = uport;
>  
>  	if (p)
>  		port.baud = p->baud;
> @@ -3804,7 +3806,7 @@ ptp_ocp_tty_show(struct device *dev, struct device_attribute *attr, char *buf)
>  	 * as a device path (e.g., "/dev/ttyS4"), and adding a newline would
>  	 * break those applications. Do not add a newline to this output.
>  	 */
> -	return sysfs_emit(buf, "ttyS%d", bp->port[(uintptr_t)ea->var].line);
> +	return sysfs_emit(buf, "ttyS%d", bp->port[(uintptr_t)ea->var].uport->port.line);
>  }
>  
>  static umode_t
> @@ -3821,7 +3823,7 @@ ptp_ocp_timecard_tty_is_visible(struct kobject *kobj, struct attribute *attr, in
>  	dattr = container_of(attr, struct device_attribute, attr);
>  	ea = container_of(dattr, struct dev_ext_attribute, attr);
>  	port = &bp->port[(uintptr_t)ea->var];
> -	return port->line == -1 ? 0 : 0444;
> +	return port->uport ? 0444 : 0;
>  }
>  
>  #define EXT_TTY_ATTR_RO(_name, _val)			\
> @@ -5287,9 +5289,9 @@ ptp_ocp_summary_show(struct seq_file *s, void *data)
>  
>  	seq_printf(s, "%7s: /dev/ptp%d\n", "PTP", ptp_clock_index(bp->ptp));
>  	for (i = 0; i < __PORT_COUNT; i++) {
> -		if (bp->port[i].line != -1)
> +		if (bp->port[i].uport)
>  			seq_printf(s, "%7s: /dev/ttyS%d\n", ptp_ocp_tty_port_name(i),
> -				   bp->port[i].line);
> +				   bp->port[i].uport->port.line);
>  	}
>  
>  	memset(sma_val, 0xff, sizeof(sma_val));
> @@ -5613,7 +5615,7 @@ ptp_ocp_device_init(struct ptp_ocp *bp, struct pci_dev *pdev)
>  	spin_lock_init(&bp->lock);
>  
>  	for (i = 0; i < __PORT_COUNT; i++)
> -		bp->port[i].line = -1;
> +		bp->port[i].uport = NULL;
>  
>  	bp->pdev = pdev;
>  
> @@ -5702,10 +5704,10 @@ ptp_ocp_phc_info(struct ptp_ocp *bp)
>  }
>  
>  static void
> -ptp_ocp_serial_info(struct device *dev, const char *name, int port, int baud)
> +ptp_ocp_serial_info(struct device *dev, const char *name, struct uart_8250_port *port, int baud)
>  {
> -	if (port != -1)
> -		dev_info(dev, "%5s: /dev/ttyS%-2d @ %6d\n", name, port, baud);
> +	if (port)
> +		dev_info(dev, "%5s: /dev/ttyS%-2d @ %6d\n", name, port->port.line, baud);
>  }
>  
>  static void
> @@ -5723,14 +5725,14 @@ ptp_ocp_info(struct ptp_ocp *bp)
>  	ptp_ocp_phc_info(bp);
>  
>  	for (i = 0; i < __PORT_COUNT; i++) {
> -		if (i == PORT_NMEA && bp->nmea_out && bp->port[PORT_NMEA].line != -1) {
> +		if (i == PORT_NMEA && bp->nmea_out && bp->port[PORT_NMEA].uport) {
>  			bp->port[PORT_NMEA].baud = -1;
>  
>  			reg = ioread32(&bp->nmea_out->uart_baud);
>  			if (reg < ARRAY_SIZE(nmea_baud))
>  				bp->port[PORT_NMEA].baud = nmea_baud[reg];
>  		}
> -		ptp_ocp_serial_info(dev, ptp_ocp_tty_port_name(i), bp->port[i].line,
> +		ptp_ocp_serial_info(dev, ptp_ocp_tty_port_name(i), bp->port[i].uport,
>  				    bp->port[i].baud);
>  	}
>  }
> @@ -5778,8 +5780,8 @@ ptp_ocp_detach(struct ptp_ocp *bp)
>  	for (i = 0; i < 4; i++)
>  		ptp_ocp_unregister_ext(bp->signal_out[i]);
>  	for (i = 0; i < __PORT_COUNT; i++)
> -		if (bp->port[i].line != -1)
> -			serial8250_unregister_port(bp->port[i].line);
> +		if (bp->port[i].uport)
> +			serial8250_unregister_port(bp->port[i].uport);
>  	platform_device_unregister(bp->spi_flash);
>  	platform_device_unregister(bp->i2c_ctrl);
>  	if (bp->i2c_clk)
> diff --git a/drivers/tty/serial/8250/8250_acorn.c b/drivers/tty/serial/8250/8250_acorn.c
> index fb596262b9c7..d0696668493a 100644
> --- a/drivers/tty/serial/8250/8250_acorn.c
> +++ b/drivers/tty/serial/8250/8250_acorn.c
> @@ -8,6 +8,7 @@
>  #include <linux/types.h>
>  #include <linux/tty.h>
>  #include <linux/serial_core.h>
> +#include <linux/err.h>
>  #include <linux/errno.h>
>  #include <linux/ioport.h>
>  #include <linux/slab.h>
> @@ -31,7 +32,7 @@ struct serial_card_type {
>  
>  struct serial_card_info {
>  	unsigned int	num_ports;
> -	int		ports[MAX_PORTS];
> +	struct uart_8250_port *ports[MAX_PORTS];
>  	void __iomem *vaddr;
>  };
>  
> @@ -85,7 +86,7 @@ static void serial_card_remove(struct expansion_card *ec)
>  	ecard_set_drvdata(ec, NULL);
>  
>  	for (i = 0; i < info->num_ports; i++)
> -		if (info->ports[i] > 0)
> +		if (!IS_ERR_OR_NULL(info->ports[i]))
>  			serial8250_unregister_port(info->ports[i]);
>  
>  	kfree(info);
> diff --git a/drivers/tty/serial/8250/8250_airoha.c b/drivers/tty/serial/8250/8250_airoha.c
> index fe72a39561c2..44aeb427d5c8 100644
> --- a/drivers/tty/serial/8250/8250_airoha.c
> +++ b/drivers/tty/serial/8250/8250_airoha.c
> @@ -28,10 +28,6 @@
>  #define   UART_AIROHA_XYD_X	GENMASK(31, 16)
>  #define   UART_AIROHA_XYD_Y	GENMASK(15, 0)
>  
> -struct airoha_8250_priv {
> -	int line;
> -};
> -
>  #define UART_BRD_20M		0x0001
>  
>  #define XINDIV_CLOCK		(20 * HZ_PER_MHZ)
> @@ -119,7 +115,6 @@ static int airoha_8250_probe(struct platform_device *pdev)
>  {
>  	struct uart_8250_port uart = { };
>  	struct device *dev = &pdev->dev;
> -	struct airoha_8250_priv *priv;
>  	struct resource *res;
>  	int ret;
>  
> @@ -127,10 +122,6 @@ static int airoha_8250_probe(struct platform_device *pdev)
>  	if (!res)
>  		return dev_err_probe(dev, -EINVAL, "invalid address\n");
>  
> -	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
> -	if (!priv)
> -		return -ENOMEM;
> -
>  	uart.port.dev = dev;
>  	if (device_is_compatible(dev, "airoha,an7581-hsuart"))
>  		uart.port.type = UART_PORT_AIROHA_HS;
> @@ -147,21 +138,20 @@ static int airoha_8250_probe(struct platform_device *pdev)
>  	if (ret)
>  		return ret;
>  
> -	ret = serial8250_register_8250_port(&uart);
> -	if (ret < 0)
> -		return ret;
> +	struct uart_8250_port *uport = serial8250_register_8250_port(&uart);
> +	if (IS_ERR(uport))
> +		return PTR_ERR(uport);
>  
> -	priv->line = ret;
> -	platform_set_drvdata(pdev, priv);
> +	platform_set_drvdata(pdev, uport);
>  
>  	return 0;
>  }
>  
>  static void airoha_8250_remove(struct platform_device *ofdev)
>  {
> -	struct airoha_8250_priv *priv = platform_get_drvdata(ofdev);
> +	struct uart_8250_port *uport = platform_get_drvdata(ofdev);
>  
> -	serial8250_unregister_port(priv->line);
> +	serial8250_unregister_port(uport);
>  }
>  
>  static const struct of_device_id airoha_8250_dt_ids[] = {
> diff --git a/drivers/tty/serial/8250/8250_aspeed_vuart.c b/drivers/tty/serial/8250/8250_aspeed_vuart.c
> index 26fc0464f1cc..604e4946fd1d 100644
> --- a/drivers/tty/serial/8250/8250_aspeed_vuart.c
> +++ b/drivers/tty/serial/8250/8250_aspeed_vuart.c
> @@ -34,7 +34,6 @@
>  
>  struct aspeed_vuart {
>  	struct device		*dev;
> -	int			line;
>  	struct timer_list	unthrottle_timer;
>  	struct uart_8250_port	*port;
>  };
> @@ -484,12 +483,13 @@ static int aspeed_vuart_probe(struct platform_device *pdev)
>  	if (of_property_read_bool(np, "auto-flow-control"))
>  		port.capabilities |= UART_CAP_AFE;
>  
> -	rc = serial8250_register_8250_port(&port);
> -	if (rc < 0)
> +	struct uart_8250_port *uport = serial8250_register_8250_port(&port);
> +	if (IS_ERR(uport)) {
> +		rc = PTR_ERR(uport);
>  		goto err_sysfs_remove;
> +	}
>  
> -	vuart->line = rc;
> -	vuart->port = serial8250_get_port(vuart->line);
> +	vuart->port = uport;
>  
>  	rc = of_parse_phandle_with_fixed_args(
>  		np, "aspeed,sirq-polarity-sense", 2, 0,
> @@ -553,7 +553,7 @@ static void aspeed_vuart_remove(struct platform_device *pdev)
>  
>  	timer_delete_sync(&vuart->unthrottle_timer);
>  	aspeed_vuart_set_enabled(vuart, false);
> -	serial8250_unregister_port(vuart->line);
> +	serial8250_unregister_port(vuart->port);
>  	sysfs_remove_group(&vuart->dev->kobj, &aspeed_vuart_attr_group);
>  }
>  
> diff --git a/drivers/tty/serial/8250/8250_bcm2835aux.c b/drivers/tty/serial/8250/8250_bcm2835aux.c
> index 0609582a62f7..78b40bf1363b 100644
> --- a/drivers/tty/serial/8250/8250_bcm2835aux.c
> +++ b/drivers/tty/serial/8250/8250_bcm2835aux.c
> @@ -37,12 +37,12 @@
>  /**
>   * struct bcm2835aux_data - driver private data of BCM2835 auxiliary UART
>   * @clk: clock producer of the port's uartclk
> - * @line: index of the port's serial8250_ports[] entry
> + * @uport: the underlying uart_8250_port
>   * @cntl: cached copy of CNTL register
>   */
>  struct bcm2835aux_data {
>  	struct clk *clk;
> -	int line;
> +	struct uart_8250_port *uport;
>  	u32 cntl;
>  };
>  
> @@ -157,12 +157,12 @@ static int bcm2835aux_serial_probe(struct platform_device *pdev)
>  	up.port.uartclk *= 2;
>  
>  	/* register the port */
> -	ret = serial8250_register_8250_port(&up);
> -	if (ret < 0) {
> +	data->uport = serial8250_register_8250_port(&up);
> +	if (IS_ERR(data->uport)) {
> +		ret = PTR_ERR(data->uport);
>  		dev_err_probe(&pdev->dev, ret, "unable to register 8250 port\n");
>  		goto dis_clk;
>  	}
> -	data->line = ret;
>  
>  	return 0;
>  
> @@ -177,7 +177,7 @@ static void bcm2835aux_serial_remove(struct platform_device *pdev)
>  {
>  	struct bcm2835aux_data *data = platform_get_drvdata(pdev);
>  
> -	serial8250_unregister_port(data->line);
> +	serial8250_unregister_port(data->uport);
>  	clk_disable_unprepare(data->clk);
>  	device_remove_software_node(&pdev->dev);
>  }
> @@ -217,12 +217,11 @@ MODULE_DEVICE_TABLE(acpi, bcm2835aux_serial_acpi_match);
>  static bool bcm2835aux_can_disable_clock(struct device *dev)
>  {
>  	struct bcm2835aux_data *data = dev_get_drvdata(dev);
> -	struct uart_8250_port *up = serial8250_get_port(data->line);
>  
>  	if (device_may_wakeup(dev))
>  		return false;
>  
> -	if (uart_console(&up->port) && !console_suspend_enabled)
> +	if (uart_console(&data->uport->port) && !console_suspend_enabled)
>  		return false;
>  
>  	return true;
> @@ -232,7 +231,7 @@ static int bcm2835aux_suspend(struct device *dev)
>  {
>  	struct bcm2835aux_data *data = dev_get_drvdata(dev);
>  
> -	serial8250_suspend_port(data->line);
> +	serial8250_suspend_port(data->uport);
>  
>  	if (!bcm2835aux_can_disable_clock(dev))
>  		return 0;
> @@ -252,7 +251,7 @@ static int bcm2835aux_resume(struct device *dev)
>  			return ret;
>  	}
>  
> -	serial8250_resume_port(data->line);
> +	serial8250_resume_port(data->uport);
>  
>  	return 0;
>  }
> diff --git a/drivers/tty/serial/8250/8250_bcm7271.c b/drivers/tty/serial/8250/8250_bcm7271.c
> index 5f1140f05150..ff75b0df41f4 100644
> --- a/drivers/tty/serial/8250/8250_bcm7271.c
> +++ b/drivers/tty/serial/8250/8250_bcm7271.c
> @@ -204,13 +204,12 @@ static const u32 brcmstb_rate_table_7278[] = {
>  };
>  
>  struct brcmuart_priv {
> -	int		line;
>  	struct clk	*baud_mux_clk;
>  	unsigned long	default_mux_rate;
>  	u32		real_rates[ARRAY_SIZE(brcmstb_rate_table)];
>  	const u32	*rate_table;
>  	ktime_t		char_wait;
> -	struct uart_port *up;
> +	struct uart_8250_port *uport;
>  	struct hrtimer	hrt;
>  	bool		shutdown;
>  	bool		dma_enabled;
> @@ -839,8 +838,8 @@ static int brcmuart_handle_irq(struct uart_port *p)
>  static enum hrtimer_restart brcmuart_hrtimer_func(struct hrtimer *t)
>  {
>  	struct brcmuart_priv *priv = container_of(t, struct brcmuart_priv, hrt);
> -	struct uart_port *p = priv->up;
> -	struct uart_8250_port *up = up_to_u8250p(p);
> +	struct uart_8250_port *up = priv->uport;
> +	struct uart_port *p = &up->port;
>  	unsigned int status;
>  	unsigned long flags;
>  
> @@ -953,7 +952,6 @@ static int brcmuart_probe(struct platform_device *pdev)
>  {
>  	struct resource *regs;
>  	const struct of_device_id *of_id = NULL;
> -	struct uart_8250_port *new_port;
>  	struct device *dev = &pdev->dev;
>  	struct brcmuart_priv *priv;
>  	struct clk *baud_mux_clk;
> @@ -1083,14 +1081,12 @@ static int brcmuart_probe(struct platform_device *pdev)
>  		}
>  	}
>  
> -	ret = serial8250_register_8250_port(&up);
> -	if (ret < 0) {
> +	priv->uport = serial8250_register_8250_port(&up);
> +	if (IS_ERR(priv->uport)) {
> +		ret = PTR_ERR(priv->uport);
>  		dev_err_probe(dev, ret, "unable to register 8250 port\n");
>  		goto err;
>  	}
> -	priv->line = ret;
> -	new_port = serial8250_get_port(ret);
> -	priv->up = &new_port->port;
>  	if (priv->dma_enabled) {
>  		dma_irq = platform_get_irq_byname(pdev,  "dma");
>  		if (dma_irq < 0) {
> @@ -1098,7 +1094,7 @@ static int brcmuart_probe(struct platform_device *pdev)
>  			goto err1;
>  		}
>  		ret = devm_request_irq(dev, dma_irq, brcmuart_isr,
> -				IRQF_SHARED, "uart DMA irq", &new_port->port);
> +				IRQF_SHARED, "uart DMA irq", &priv->uport->port);
>  		if (ret)
>  			goto err1;
>  	}
> @@ -1107,7 +1103,7 @@ static int brcmuart_probe(struct platform_device *pdev)
>  	return 0;
>  
>  err1:
> -	serial8250_unregister_port(priv->line);
> +	serial8250_unregister_port(priv->uport);
>  err:
>  	brcmuart_free_bufs(dev, priv);
>  release_dma:
> @@ -1121,7 +1117,7 @@ static void brcmuart_remove(struct platform_device *pdev)
>  	struct brcmuart_priv *priv = platform_get_drvdata(pdev);
>  
>  	debugfs_remove_recursive(priv->debugfs_dir);
> -	serial8250_unregister_port(priv->line);
> +	serial8250_unregister_port(priv->uport);
>  	hrtimer_cancel(&priv->hrt);
>  	brcmuart_free_bufs(&pdev->dev, priv);
>  	if (priv->dma_enabled)
> @@ -1131,7 +1127,7 @@ static void brcmuart_remove(struct platform_device *pdev)
>  static int __maybe_unused brcmuart_suspend(struct device *dev)
>  {
>  	struct brcmuart_priv *priv = dev_get_drvdata(dev);
> -	struct uart_8250_port *up = serial8250_get_port(priv->line);
> +	struct uart_8250_port *up = priv->uport;
>  	struct uart_port *port = &up->port;
>  	unsigned long flags;
>  
> @@ -1144,7 +1140,7 @@ static int __maybe_unused brcmuart_suspend(struct device *dev)
>  	port->mctrl &= ~TIOCM_RTS;
>  	uart_port_unlock_irqrestore(port, flags);
>  
> -	serial8250_suspend_port(priv->line);
> +	serial8250_suspend_port(up);
>  	clk_disable_unprepare(priv->baud_mux_clk);
>  
>  	return 0;
> @@ -1153,7 +1149,7 @@ static int __maybe_unused brcmuart_suspend(struct device *dev)
>  static int __maybe_unused brcmuart_resume(struct device *dev)
>  {
>  	struct brcmuart_priv *priv = dev_get_drvdata(dev);
> -	struct uart_8250_port *up = serial8250_get_port(priv->line);
> +	struct uart_8250_port *up = priv->uport;
>  	struct uart_port *port = &up->port;
>  	unsigned long flags;
>  	int ret;
> @@ -1175,9 +1171,9 @@ static int __maybe_unused brcmuart_resume(struct device *dev)
>  			return(-EBUSY);
>  		}
>  		brcmuart_init_dma_hardware(priv);
> -		start_rx_dma(serial8250_get_port(priv->line));
> +		start_rx_dma(up);
>  	}
> -	serial8250_resume_port(priv->line);
> +	serial8250_resume_port(up);
>  
>  	if (priv->saved_mctrl & TIOCM_RTS) {
>  		/* Restore RTS */
> diff --git a/drivers/tty/serial/8250/8250_core.c b/drivers/tty/serial/8250/8250_core.c
> index 11424fef7c08..6ca6b3bed80f 100644
> --- a/drivers/tty/serial/8250/8250_core.c
> +++ b/drivers/tty/serial/8250/8250_core.c
> @@ -333,7 +333,6 @@ struct uart_8250_port *serial8250_get_port(int line)
>  {
>  	return &serial8250_ports[line];
>  }
> -EXPORT_SYMBOL_GPL(serial8250_get_port);
>  
>  static inline void serial8250_apply_quirks(struct uart_8250_port *up)
>  {
> @@ -600,13 +599,12 @@ int __init early_serial_setup(struct uart_port *port)
>  
>  /**
>   *	serial8250_suspend_port - suspend one serial port
> - *	@line:  serial line number
> + *	@up: serial port
>   *
>   *	Suspend one serial port.
>   */
> -void serial8250_suspend_port(int line)
> +void serial8250_suspend_port(struct uart_8250_port *up)
>  {
> -	struct uart_8250_port *up = &serial8250_ports[line];
>  	struct uart_port *port = &up->port;
>  
>  	if (uart_console(port)) {
> @@ -630,13 +628,12 @@ EXPORT_SYMBOL(serial8250_suspend_port);
>  
>  /**
>   *	serial8250_resume_port - resume one serial port
> - *	@line:  serial line number
> + *	@up: serial port
>   *
>   *	Resume one serial port.
>   */
> -void serial8250_resume_port(int line)
> +void serial8250_resume_port(struct uart_8250_port *up)
>  {
> -	struct uart_8250_port *up = &serial8250_ports[line];
>  	struct uart_port *port = &up->port;
>  
>  	up->canary = 0;
> @@ -754,16 +751,16 @@ static void serial_8250_overrun_backoff_work(struct work_struct *work)
>   *	The port is then probed and if necessary the IRQ is autodetected
>   *	If this fails an error is returned.
>   *
> - *	On success the port is ready to use and the line number is returned.
> + *	On success, the port is returned as ready to use.
>   */
> -int serial8250_register_8250_port(const struct uart_8250_port *up)
> +struct uart_8250_port *serial8250_register_8250_port(const struct uart_8250_port *up)
>  {
>  	struct uart_8250_port *uart;
>  	bool cons_flow;
>  	int ret;
>  
>  	if (up->port.uartclk == 0)
> -		return -EINVAL;
> +		return ERR_PTR(-EINVAL);
>  
>  	guard(mutex)(&serial_mutex);
>  
> @@ -775,13 +772,13 @@ int serial8250_register_8250_port(const struct uart_8250_port *up)
>  		 */
>  		uart = serial8250_setup_port(nr_uarts);
>  		if (!uart)
> -			return -ENOSPC;
> +			return ERR_PTR(-ENOSPC);
>  		nr_uarts++;
>  	}
>  
>  	/* Check if it is CIR already. We check this below again, see there why. */
>  	if (uart->port.type == PORT_8250_CIR)
> -		return -ENODEV;
> +		return ERR_PTR(-ENODEV);
>  
>  	/* Preserve specified console flow control. */
>  	cons_flow = uart_cons_flow_enabled(&uart->port);
> @@ -901,16 +898,12 @@ int serial8250_register_8250_port(const struct uart_8250_port *up)
>  					&uart->port);
>  		if (ret)
>  			goto err;
> -
> -		ret = uart->port.line;
>  	} else {
>  		dev_info(uart->port.dev,
>  			"skipping CIR port at 0x%lx / 0x%llx, IRQ %d\n",
>  			uart->port.iobase,
>  			(unsigned long long)uart->port.mapbase,
>  			uart->port.irq);
> -
> -		ret = 0;
>  	}
>  
>  	if (!uart->lsr_save_mask)
> @@ -926,25 +919,23 @@ int serial8250_register_8250_port(const struct uart_8250_port *up)
>  		uart->overrun_backoff_time_ms = 0;
>  	}
>  
> -	return ret;
> +	return uart;
>  
>  err:
>  	uart->port.dev = NULL;
> -	return ret;
> +	return ERR_PTR(ret);
>  }
>  EXPORT_SYMBOL(serial8250_register_8250_port);
>  
>  /**
>   *	serial8250_unregister_port - remove a 16x50 serial port at runtime
> - *	@line: serial line number
> + *	@uart: port
>   *
>   *	Remove one serial port.  This may not be called from interrupt
>   *	context.  We hand the port back to the our control.
>   */
> -void serial8250_unregister_port(int line)
> +void serial8250_unregister_port(struct uart_8250_port *uart)
>  {
> -	struct uart_8250_port *uart = &serial8250_ports[line];
> -
>  	guard(mutex)(&serial_mutex);
>  
>  	if (uart->em485) {
> @@ -957,7 +948,7 @@ void serial8250_unregister_port(int line)
>  		uart->port.flags &= ~UPF_BOOT_AUTOCONF;
>  		uart->port.type = PORT_UNKNOWN;
>  		uart->port.dev = &serial8250_isa_devs->dev;
> -		uart->port.port_id = line;
> +		uart->port.port_id = uart->port.line;
>  		uart->capabilities = 0;
>  		serial8250_init_port(uart);
>  		serial8250_apply_quirks(uart);
> diff --git a/drivers/tty/serial/8250/8250_dfl.c b/drivers/tty/serial/8250/8250_dfl.c
> index 475ca340948c..13d361ddfc4b 100644
> --- a/drivers/tty/serial/8250/8250_dfl.c
> +++ b/drivers/tty/serial/8250/8250_dfl.c
> @@ -27,10 +27,6 @@
>  #define DFHv1_PARAM_REG_LAYOUT_WIDTH	GENMASK_ULL(63, 32)
>  #define DFHv1_PARAM_REG_LAYOUT_SHIFT	GENMASK_ULL(31, 0)
>  
> -struct dfl_uart {
> -	int line;
> -};
> -
>  static int dfh_get_u64_param_val(struct dfl_device *dfl_dev, int param_id, u64 *pval)
>  {
>  	size_t psize;
> @@ -109,7 +105,6 @@ static int dfl_uart_probe(struct dfl_device *dfl_dev)
>  {
>  	struct device *dev = &dfl_dev->dev;
>  	struct uart_8250_port uart = { };
> -	struct dfl_uart *dfluart;
>  	int ret;
>  
>  	uart.port.flags = UPF_IOREMAP;
> @@ -123,24 +118,20 @@ static int dfl_uart_probe(struct dfl_device *dfl_dev)
>  	if (dfl_dev->num_irqs == 1)
>  		uart.port.irq = dfl_dev->irqs[0];
>  
> -	dfluart = devm_kzalloc(dev, sizeof(*dfluart), GFP_KERNEL);
> -	if (!dfluart)
> -		return -ENOMEM;
> -
> -	dfluart->line = serial8250_register_8250_port(&uart);
> -	if (dfluart->line < 0)
> -		return dev_err_probe(dev, dfluart->line, "unable to register 8250 port.\n");
> +	struct uart_8250_port *uport = serial8250_register_8250_port(&uart);
> +	if (IS_ERR(uport))
> +		return dev_err_probe(dev, PTR_ERR(uport), "unable to register 8250 port.\n");
>  
> -	dev_set_drvdata(dev, dfluart);
> +	dev_set_drvdata(dev, uport);
>  
>  	return 0;
>  }
>  
>  static void dfl_uart_remove(struct dfl_device *dfl_dev)
>  {
> -	struct dfl_uart *dfluart = dev_get_drvdata(&dfl_dev->dev);
> +	struct uart_8250_port *uport = dev_get_drvdata(&dfl_dev->dev);
>  
> -	serial8250_unregister_port(dfluart->line);
> +	serial8250_unregister_port(uport);
>  }
>  
>  #define FME_FEATURE_ID_UART 0x24
> diff --git a/drivers/tty/serial/8250/8250_dw.c b/drivers/tty/serial/8250/8250_dw.c
> index 0ab558230370..c259a940654f 100644
> --- a/drivers/tty/serial/8250/8250_dw.c
> +++ b/drivers/tty/serial/8250/8250_dw.c
> @@ -774,9 +774,9 @@ static int dw8250_probe(struct platform_device *pdev)
>  		up->dma = &data->data.dma;
>  	}
>  
> -	data->data.line = serial8250_register_8250_port(up);
> -	if (data->data.line < 0)
> -		return data->data.line;
> +	data->data.uport = serial8250_register_8250_port(up);
> +	if (IS_ERR(data->data.uport))
> +		return PTR_ERR(data->data.uport);

Add err.h.

>  
>  	platform_set_drvdata(pdev, data);
>  
> @@ -792,7 +792,7 @@ static void dw8250_remove(struct platform_device *pdev)
>  
>  	pm_runtime_get_sync(dev);
>  
> -	serial8250_unregister_port(data->data.line);
> +	serial8250_unregister_port(data->data.uport);
>  
>  	pm_runtime_disable(dev);
>  	pm_runtime_put_noidle(dev);
> @@ -802,7 +802,7 @@ static int dw8250_suspend(struct device *dev)
>  {
>  	struct dw8250_data *data = dev_get_drvdata(dev);
>  
> -	serial8250_suspend_port(data->data.line);
> +	serial8250_suspend_port(data->data.uport);
>  
>  	return 0;
>  }
> @@ -811,7 +811,7 @@ static int dw8250_resume(struct device *dev)
>  {
>  	struct dw8250_data *data = dev_get_drvdata(dev);
>  
> -	serial8250_resume_port(data->data.line);
> +	serial8250_resume_port(data->data.uport);
>  
>  	return 0;
>  }
> diff --git a/drivers/tty/serial/8250/8250_dwlib.h b/drivers/tty/serial/8250/8250_dwlib.h
> index ee7a07fac0f6..39fcb1b323ad 100644
> --- a/drivers/tty/serial/8250/8250_dwlib.h
> +++ b/drivers/tty/serial/8250/8250_dwlib.h
> @@ -80,7 +80,7 @@
>  
>  struct dw8250_port_data {
>  	/* Port properties */
> -	int			line;
> +	struct uart_8250_port *uport;
>  
>  	/* DMA operations */
>  	struct uart_8250_dma	dma;
> diff --git a/drivers/tty/serial/8250/8250_em.c b/drivers/tty/serial/8250/8250_em.c
> index 32d077da076a..68c70f857e8d 100644
> --- a/drivers/tty/serial/8250/8250_em.c
> +++ b/drivers/tty/serial/8250/8250_em.c
> @@ -28,10 +28,6 @@
>  
>  #define UART_HCR0_EM_SW_RESET	BIT(7) /* SW Reset */
>  
> -struct serial8250_em_priv {
> -	int line;
> -};
> -
>  static void serial8250_em_serial_out_helper(struct uart_port *p, int offset,
>  					    int value)
>  {
> @@ -151,12 +147,11 @@ static void serial8250_em_serial_dl_write(struct uart_8250_port *up, u32 value)
>  
>  static int serial8250_em_probe(struct platform_device *pdev)
>  {
> -	struct serial8250_em_priv *priv;
>  	struct device *dev = &pdev->dev;
>  	struct uart_8250_port up;
>  	struct resource *regs;
>  	struct clk *sclk;
> -	int irq, ret;
> +	int irq;
>  
>  	irq = platform_get_irq(pdev, 0);
>  	if (irq < 0)
> @@ -166,10 +161,6 @@ static int serial8250_em_probe(struct platform_device *pdev)
>  	if (!regs)
>  		return dev_err_probe(dev, -EINVAL, "missing registers\n");
>  
> -	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
> -	if (!priv)
> -		return -ENOMEM;
> -
>  	sclk = devm_clk_get_enabled(dev, "sclk");
>  	if (IS_ERR(sclk))
>  		return dev_err_probe(dev, PTR_ERR(sclk), "unable to get clock\n");
> @@ -180,7 +171,6 @@ static int serial8250_em_probe(struct platform_device *pdev)
>  	up.port.type = PORT_16750;
>  	up.port.flags = UPF_FIXED_PORT | UPF_IOREMAP | UPF_FIXED_TYPE;
>  	up.port.dev = dev;
> -	up.port.private_data = priv;
>  
>  	up.port.uartclk = clk_get_rate(sclk);
>  
> @@ -190,20 +180,19 @@ static int serial8250_em_probe(struct platform_device *pdev)
>  	up.dl_read = serial8250_em_serial_dl_read;
>  	up.dl_write = serial8250_em_serial_dl_write;
>  
> -	ret = serial8250_register_8250_port(&up);
> -	if (ret < 0)
> -		return dev_err_probe(dev, ret, "unable to register 8250 port\n");
> +	struct uart_8250_port *uport = serial8250_register_8250_port(&up);
> +	if (IS_ERR(uport))
> +		return dev_err_probe(dev, PTR_ERR(uport), "unable to register 8250 port\n");
>  
> -	priv->line = ret;
> -	platform_set_drvdata(pdev, priv);
> +	platform_set_drvdata(pdev, uport);
>  	return 0;
>  }
>  
>  static void serial8250_em_remove(struct platform_device *pdev)
>  {
> -	struct serial8250_em_priv *priv = platform_get_drvdata(pdev);
> +	struct uart_8250_port *up = platform_get_drvdata(pdev);
>  
> -	serial8250_unregister_port(priv->line);
> +	serial8250_unregister_port(up);
>  }
>  
>  static const struct of_device_id serial8250_em_dt_ids[] = {
> diff --git a/drivers/tty/serial/8250/8250_exar.c b/drivers/tty/serial/8250/8250_exar.c
> index 836792e861bf..453e843b78ca 100644
> --- a/drivers/tty/serial/8250/8250_exar.c
> +++ b/drivers/tty/serial/8250/8250_exar.c
> @@ -256,7 +256,7 @@ struct exar8250 {
>  	struct exar8250_board	*board;
>  	struct eeprom_93cx6	eeprom;
>  	void __iomem		*virt;
> -	int			line[];
> +	struct uart_8250_port	*uport[];
>  };
>  
>  static inline void exar_write_reg(struct exar8250 *priv,
> @@ -1377,9 +1377,8 @@ static void pci_xr17v35x_exit(struct pci_dev *pcidev)
>  {
>  	const struct exar8250_platform *platform = exar_get_platform();
>  	struct exar8250 *priv = pci_get_drvdata(pcidev);
> -	struct uart_8250_port *port = serial8250_get_port(priv->line[0]);
>  
> -	platform->unregister_gpio(port);
> +	platform->unregister_gpio(priv->uport[0]);
>  }
>  
>  static inline void exar_misc_clear(struct exar8250 *priv)
> @@ -1460,7 +1459,7 @@ exar_pci_probe(struct pci_dev *pcidev, const struct pci_device_id *ent)
>  	if (nr_ports == 0)
>  		return dev_err_probe(&pcidev->dev, -ENODEV, "failed to get number of ports\n");
>  
> -	priv = devm_kzalloc(&pcidev->dev, struct_size(priv, line, nr_ports), GFP_KERNEL);
> +	priv = devm_kzalloc(&pcidev->dev, struct_size(priv, uport, nr_ports), GFP_KERNEL);
>  	if (!priv)
>  		return -ENOMEM;
>  
> @@ -1500,9 +1499,9 @@ exar_pci_probe(struct pci_dev *pcidev, const struct pci_device_id *ent)
>  		dev_dbg(&pcidev->dev, "Setup PCI port: port %lx, irq %d, type %d\n",
>  			uart.port.iobase, uart.port.irq, uart.port.iotype);
>  
> -		priv->line[i] = serial8250_register_8250_port(&uart);
> -		if (priv->line[i] < 0) {
> -			dev_err_probe(&pcidev->dev, priv->line[i],
> +		priv->uport[i] = serial8250_register_8250_port(&uart);
> +		if (IS_ERR(priv->uport[i])) {
> +			dev_err_probe(&pcidev->dev, PTR_ERR(priv->uport[i]),
>  				"Couldn't register serial port %lx, type %d, irq %d\n",
>  				uart.port.iobase, uart.port.iotype, uart.port.irq);
>  			break;
> @@ -1519,7 +1518,7 @@ static void exar_pci_remove(struct pci_dev *pcidev)
>  	unsigned int i;
>  
>  	for (i = 0; i < priv->nr; i++)
> -		serial8250_unregister_port(priv->line[i]);
> +		serial8250_unregister_port(priv->uport[i]);
>  
>  	/* Ensure that every init quirk is properly torn down */
>  	if (priv->board->exit)
> @@ -1532,8 +1531,7 @@ static int exar_suspend(struct device *dev)
>  	unsigned int i;
>  
>  	for (i = 0; i < priv->nr; i++)
> -		if (priv->line[i] >= 0)
> -			serial8250_suspend_port(priv->line[i]);
> +		serial8250_suspend_port(priv->uport[i]);
>  
>  	return 0;
>  }
> @@ -1546,8 +1544,7 @@ static int exar_resume(struct device *dev)
>  	exar_misc_clear(priv);
>  
>  	for (i = 0; i < priv->nr; i++)
> -		if (priv->line[i] >= 0)
> -			serial8250_resume_port(priv->line[i]);
> +		serial8250_resume_port(priv->uport[i]);
>  
>  	return 0;
>  }
> diff --git a/drivers/tty/serial/8250/8250_fsl.c b/drivers/tty/serial/8250/8250_fsl.c
> index 649ae5c8304d..d4ba391e321b 100644
> --- a/drivers/tty/serial/8250/8250_fsl.c
> +++ b/drivers/tty/serial/8250/8250_fsl.c
> @@ -99,14 +99,9 @@ int fsl8250_handle_irq(struct uart_port *port)
>  EXPORT_SYMBOL_GPL(fsl8250_handle_irq);
>  
>  #ifdef CONFIG_ACPI
> -struct fsl8250_data {
> -	int	line;
> -};
> -
>  static int fsl8250_acpi_probe(struct platform_device *pdev)
>  {
> -	struct fsl8250_data *data;
> -	struct uart_8250_port port8250;
> +	struct uart_8250_port *uport, port8250;
>  	struct device *dev = &pdev->dev;
>  	struct resource *regs;
>  
> @@ -148,23 +143,19 @@ static int fsl8250_acpi_probe(struct platform_device *pdev)
>  	if (!port8250.port.membase)
>  		return -ENOMEM;
>  
> -	data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
> -	if (!data)
> -		return -ENOMEM;
> -
> -	data->line = serial8250_register_8250_port(&port8250);
> -	if (data->line < 0)
> -		return data->line;
> +	uport = serial8250_register_8250_port(&port8250);
> +	if (IS_ERR(uport))
> +		return PTR_ERR(uport);
>  
> -	platform_set_drvdata(pdev, data);
> +	platform_set_drvdata(pdev, uport);
>  	return 0;
>  }
>  
>  static void fsl8250_acpi_remove(struct platform_device *pdev)
>  {
> -	struct fsl8250_data *data = platform_get_drvdata(pdev);
> +	struct uart_8250_port *uport = platform_get_drvdata(pdev);
>  
> -	serial8250_unregister_port(data->line);
> +	serial8250_unregister_port(uport);
>  }
>  
>  static const struct acpi_device_id fsl_8250_acpi_id[] = {
> diff --git a/drivers/tty/serial/8250/8250_hp300.c b/drivers/tty/serial/8250/8250_hp300.c
> index 59ec0c7377a1..c0227ec873c8 100644
> --- a/drivers/tty/serial/8250/8250_hp300.c
> +++ b/drivers/tty/serial/8250/8250_hp300.c
> @@ -27,7 +27,7 @@
>  #ifdef CONFIG_HPAPCI
>  struct hp300_port {
>  	struct hp300_port *next;	/* next port */
> -	int line;			/* line (tty) number */
> +	struct uart_8250_port *uport;
>  };
>  
>  static struct hp300_port *hp300_ports;
> @@ -157,8 +157,7 @@ int __init hp300_setup_serial_console(void)
>  static int hpdca_init_one(struct dio_dev *d,
>  				const struct dio_device_id *ent)
>  {
> -	struct uart_8250_port uart;
> -	int line;
> +	struct uart_8250_port *uport, uart;
>  
>  #ifdef CONFIG_SERIAL_8250_CONSOLE
>  	if (hp300_uart_scode == d->scode) {
> @@ -177,9 +176,8 @@ static int hpdca_init_one(struct dio_dev *d,
>  	uart.port.membase = (char *)(uart.port.mapbase + DIO_VIRADDRBASE);
>  	uart.port.regshift = 1;
>  	uart.port.dev = &d->dev;
> -	line = serial8250_register_8250_port(&uart);
> -
> -	if (line < 0) {
> +	uport = serial8250_register_8250_port(&uart);
> +	if (IS_ERR(uport)) {
>  		dev_notice(&d->dev,
>  			  "8250_hp300: register_serial() DCA scode %d irq %d failed\n",
>  			  d->scode, uart.port.irq);
> @@ -188,7 +186,7 @@ static int hpdca_init_one(struct dio_dev *d,
>  
>  	/* Enable board-interrupts */
>  	out_8(d->resource.start + DIO_VIRADDRBASE + DCA_IC, DCA_IC_IE);
> -	dio_set_drvdata(d, (void *)line);
> +	dio_set_drvdata(d, uport);
>  
>  	/* Reset the DCA */
>  	out_8(d->resource.start + DIO_VIRADDRBASE + DCA_ID, 0xff);
> @@ -204,7 +202,6 @@ static int __init hp300_8250_init(void)
>  {
>  	static int called;
>  #ifdef CONFIG_HPAPCI
> -	int line;
>  	unsigned long base;
>  	struct uart_8250_port uart;
>  	struct hp300_port *port;
> @@ -226,6 +223,7 @@ static int __init hp300_8250_init(void)
>  			return -ENODEV;
>  		return 0;
>  	}
> +
>  	/* These models have the Frodo chip.
>  	 * Port 0 is reserved for the Apollo Domain keyboard.
>  	 * Port 1 is either the console or the DCA.
> @@ -259,9 +257,8 @@ static int __init hp300_8250_init(void)
>  		uart.port.membase = (char *)(base + DIO_VIRADDRBASE);
>  		uart.port.regshift = 2;
>  
> -		line = serial8250_register_8250_port(&uart);
> -
> -		if (line < 0) {
> +		port->uport = serial8250_register_8250_port(&uart);
> +		if (IS_ERR(port->uport)) {
>  			dev_notice(uart.port.dev,
>  				   "8250_hp300: register_serial() APCI %d irq %d failed\n",
>  				   i, uart.port.irq);
> @@ -269,7 +266,6 @@ static int __init hp300_8250_init(void)
>  			continue;
>  		}
>  
> -		port->line = line;
>  		port->next = hp300_ports;
>  		hp300_ports = port;
>  
> @@ -287,14 +283,13 @@ static int __init hp300_8250_init(void)
>  #ifdef CONFIG_HPDCA
>  static void hpdca_remove_one(struct dio_dev *d)
>  {
> -	int line;
> +	struct uart_8250_port *uport = dio_get_drvdata(d);
>  
> -	line = (int) dio_get_drvdata(d);
>  	if (d->resource.start) {
>  		/* Disable board-interrupts */
>  		out_8(d->resource.start + DIO_VIRADDRBASE + DCA_IC, 0);
>  	}
> -	serial8250_unregister_port(line);
> +	serial8250_unregister_port(uport);
>  }
>  #endif
>  
> @@ -304,7 +299,7 @@ static void __exit hp300_8250_exit(void)
>  	struct hp300_port *port, *to_free;
>  
>  	for (port = hp300_ports; port; ) {
> -		serial8250_unregister_port(port->line);
> +		serial8250_unregister_port(port->uport);
>  		to_free = port;
>  		port = port->next;
>  		kfree(to_free);
> diff --git a/drivers/tty/serial/8250/8250_ingenic.c b/drivers/tty/serial/8250/8250_ingenic.c
> index 94542fc143c2..8fedddeb38d9 100644
> --- a/drivers/tty/serial/8250/8250_ingenic.c
> +++ b/drivers/tty/serial/8250/8250_ingenic.c
> @@ -29,7 +29,7 @@ struct ingenic_uart_config {
>  struct ingenic_uart_data {
>  	struct clk	*clk_module;
>  	struct clk	*clk_baud;
> -	int		line;
> +	struct uart_8250_port *uport;
>  };
>  
>  static const struct of_device_id of_match[];
> @@ -297,9 +297,9 @@ static int ingenic_uart_probe(struct platform_device *pdev)
>  	}
>  	uart.port.uartclk = clk_get_rate(data->clk_baud);
>  
> -	data->line = serial8250_register_8250_port(&uart);
> -	if (data->line < 0) {
> -		err = data->line;
> +	data->uport = serial8250_register_8250_port(&uart);
> +	if (IS_ERR(data->uport)) {
> +		err = PTR_ERR(data->uport);
>  		goto out_disable_baudclk;
>  	}
>  
> @@ -318,7 +318,7 @@ static void ingenic_uart_remove(struct platform_device *pdev)
>  {
>  	struct ingenic_uart_data *data = platform_get_drvdata(pdev);
>  
> -	serial8250_unregister_port(data->line);
> +	serial8250_unregister_port(data->uport);
>  	clk_disable_unprepare(data->clk_module);
>  	clk_disable_unprepare(data->clk_baud);
>  }
> diff --git a/drivers/tty/serial/8250/8250_ioc3.c b/drivers/tty/serial/8250/8250_ioc3.c
> index 28e28076782b..0ddc5e24567b 100644
> --- a/drivers/tty/serial/8250/8250_ioc3.c
> +++ b/drivers/tty/serial/8250/8250_ioc3.c
> @@ -17,10 +17,6 @@
>  
>  #define IOC3_UARTCLK (22000000 / 3)
>  
> -struct ioc3_8250_data {
> -	int line;
> -};
> -
>  static u32 ioc3_serial_in(struct uart_port *p, unsigned int offset)
>  {
>  	return readb(p->membase + (offset ^ 3));
> @@ -33,20 +29,15 @@ static void ioc3_serial_out(struct uart_port *p, unsigned int offset, u32 value)
>  
>  static int serial8250_ioc3_probe(struct platform_device *pdev)
>  {
> -	struct ioc3_8250_data *data;
> -	struct uart_8250_port up;
> +	struct uart_8250_port *uport, up;
>  	struct resource *r;
>  	void __iomem *membase;
> -	int irq, line;
> +	int irq;
>  
>  	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
>  	if (!r)
>  		return -ENODEV;
>  
> -	data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
> -	if (!data)
> -		return -ENOMEM;
> -
>  	membase = devm_ioremap(&pdev->dev, r->start, resource_size(r));
>  	if (!membase)
>  		return -ENOMEM;
> @@ -67,19 +58,19 @@ static int serial8250_ioc3_probe(struct platform_device *pdev)
>  	up.port.mapbase = r->start;
>  	up.port.serial_in = ioc3_serial_in;
>  	up.port.serial_out = ioc3_serial_out;
> -	line = serial8250_register_8250_port(&up);
> -	if (line < 0)
> -		return line;
> +	uport = serial8250_register_8250_port(&up);
> +	if (IS_ERR(uport))
> +		return PTR_ERR(uport);
>  
> -	platform_set_drvdata(pdev, data);
> +	platform_set_drvdata(pdev, uport);
>  	return 0;
>  }
>  
>  static void serial8250_ioc3_remove(struct platform_device *pdev)
>  {
> -	struct ioc3_8250_data *data = platform_get_drvdata(pdev);
> +	struct uart_8250_port *uport = platform_get_drvdata(pdev);
>  
> -	serial8250_unregister_port(data->line);
> +	serial8250_unregister_port(uport);
>  }
>  
>  static struct platform_driver serial8250_ioc3_driver = {
> diff --git a/drivers/tty/serial/8250/8250_keba.c b/drivers/tty/serial/8250/8250_keba.c
> index 5b791b6eefd0..c53ca05a57d7 100644
> --- a/drivers/tty/serial/8250/8250_keba.c
> +++ b/drivers/tty/serial/8250/8250_keba.c
> @@ -62,7 +62,7 @@ enum kuart_mode {
>  struct kuart {
>  	struct keba_uart_auxdev *auxdev;
>  	void __iomem *base;
> -	unsigned int line;
> +	struct uart_8250_port *uport;
>  
>  	unsigned int flags;
>  	u8 capability;
> @@ -174,7 +174,6 @@ static int kuart_probe(struct auxiliary_device *auxdev,
>  	struct uart_8250_port uart = {};
>  	struct resource res;
>  	struct kuart *kuart;
> -	int retval;
>  
>  	kuart = devm_kzalloc(dev, sizeof(*kuart), GFP_KERNEL);
>  	if (!kuart)
> @@ -250,12 +249,10 @@ static int kuart_probe(struct auxiliary_device *auxdev,
>  		}
>  	}
>  
> -	retval = serial8250_register_8250_port(&uart);
> -	if (retval < 0)
> -		return dev_err_probe(&auxdev->dev, retval,
> +	kuart->uport = serial8250_register_8250_port(&uart);
> +	if (IS_ERR(kuart->uport))
> +		return dev_err_probe(&auxdev->dev, PTR_ERR(kuart->uport),
>  				     "UART registration failed!\n");
> -	kuart->line = retval;
> -
>  	return 0;
>  }
>  
> @@ -266,7 +263,7 @@ static void kuart_remove(struct auxiliary_device *auxdev)
>  	if (kuart->flags & KUART_USE_CAPABILITY)
>  		kuart_set_phy_mode(kuart, KUART_MODE_NONE);
>  
> -	serial8250_unregister_port(kuart->line);
> +	serial8250_unregister_port(kuart->uport);
>  }
>  
>  static const struct auxiliary_device_id kuart_devtype_aux[] = {
> diff --git a/drivers/tty/serial/8250/8250_loongson.c b/drivers/tty/serial/8250/8250_loongson.c
> index 19acb2c6b611..f65e0813d84a 100644
> --- a/drivers/tty/serial/8250/8250_loongson.c
> +++ b/drivers/tty/serial/8250/8250_loongson.c
> @@ -43,7 +43,7 @@ static const struct loongson_uart_ddata ls2k1500_uart_data = {
>  };
>  
>  struct loongson_uart_priv {
> -	int line;
> +	struct uart_8250_port *uport;
>  	struct clk *clk;
>  	struct resource *res;
>  	struct reset_control *rst;
> @@ -160,13 +160,12 @@ static int loongson_uart_probe(struct platform_device *pdev)
>  	if (ret)
>  		return ret;
>  
> -	ret = serial8250_register_8250_port(&uart);
> -	if (ret < 0) {
> +	priv->uport = serial8250_register_8250_port(&uart);
> +	if (IS_ERR(priv->uport)) {
>  		reset_control_assert(priv->rst);
> -		return ret;
> +		return PTR_ERR(priv->uport);
>  	}
>  
> -	priv->line = ret;
>  	platform_set_drvdata(pdev, priv);
>  
>  	return 0;
> @@ -176,16 +175,16 @@ static void loongson_uart_remove(struct platform_device *pdev)
>  {
>  	struct loongson_uart_priv *priv = platform_get_drvdata(pdev);
>  
> -	serial8250_unregister_port(priv->line);
> +	serial8250_unregister_port(priv->uport);
>  	reset_control_assert(priv->rst);
>  }
>  
>  static int loongson_uart_suspend(struct device *dev)
>  {
>  	struct loongson_uart_priv *priv = dev_get_drvdata(dev);
> -	struct uart_8250_port *up = serial8250_get_port(priv->line);
> +	struct uart_8250_port *up = priv->uport;
>  
> -	serial8250_suspend_port(priv->line);
> +	serial8250_suspend_port(up);
>  
>  	if (!uart_console(&up->port) || console_suspend_enabled)
>  		clk_disable_unprepare(priv->clk);
> @@ -196,7 +195,7 @@ static int loongson_uart_suspend(struct device *dev)
>  static int loongson_uart_resume(struct device *dev)
>  {
>  	struct loongson_uart_priv *priv = dev_get_drvdata(dev);
> -	struct uart_8250_port *up = serial8250_get_port(priv->line);
> +	struct uart_8250_port *up = priv->uport;
>  	int ret;
>  
>  	if (!uart_console(&up->port) || console_suspend_enabled) {
> @@ -205,7 +204,7 @@ static int loongson_uart_resume(struct device *dev)
>  			return ret;
>  	}
>  
> -	serial8250_resume_port(priv->line);
> +	serial8250_resume_port(up);
>  
>  	return 0;
>  }
> diff --git a/drivers/tty/serial/8250/8250_lpc18xx.c b/drivers/tty/serial/8250/8250_lpc18xx.c
> index 6c0489c9c253..9002951db02b 100644
> --- a/drivers/tty/serial/8250/8250_lpc18xx.c
> +++ b/drivers/tty/serial/8250/8250_lpc18xx.c
> @@ -29,7 +29,7 @@ struct lpc18xx_uart_data {
>  	struct uart_8250_dma dma;
>  	struct clk *clk_uart;
>  	struct clk *clk_reg;
> -	int line;
> +	struct uart_8250_port *uport;
>  };
>  
>  static int lpc18xx_rs485_config(struct uart_port *port, struct ktermios *termios,
> @@ -160,13 +160,13 @@ static int lpc18xx_serial_probe(struct platform_device *pdev)
>  	uart.dma->rxconf.src_maxburst = 1;
>  	uart.dma->txconf.dst_maxburst = 1;
>  
> -	ret = serial8250_register_8250_port(&uart);
> -	if (ret < 0) {
> +	data->uport = serial8250_register_8250_port(&uart);
> +	if (IS_ERR(data->uport)) {
> +		ret = PTR_ERR(data->uport);
>  		dev_err(&pdev->dev, "unable to register 8250 port\n");
>  		goto dis_uart_clk;
>  	}
>  
> -	data->line = ret;
>  	platform_set_drvdata(pdev, data);
>  
>  	return 0;
> @@ -182,7 +182,7 @@ static void lpc18xx_serial_remove(struct platform_device *pdev)
>  {
>  	struct lpc18xx_uart_data *data = platform_get_drvdata(pdev);
>  
> -	serial8250_unregister_port(data->line);
> +	serial8250_unregister_port(data->uport);
>  	clk_disable_unprepare(data->clk_uart);
>  	clk_disable_unprepare(data->clk_reg);
>  }
> diff --git a/drivers/tty/serial/8250/8250_lpss.c b/drivers/tty/serial/8250/8250_lpss.c
> index c5257847a94c..115b97556360 100644
> --- a/drivers/tty/serial/8250/8250_lpss.c
> +++ b/drivers/tty/serial/8250/8250_lpss.c
> @@ -183,12 +183,8 @@ static int ehl_serial_setup(struct lpss8250 *lpss, struct uart_port *port)
>  
>  static void ehl_serial_exit(struct lpss8250 *lpss)
>  {
> -	if (lpss->data.line < 0)
> -		return;
> -
> -	struct uart_8250_port *up = serial8250_get_port(lpss->data.line);
> -
> -	up->dma = NULL;
> +	if (lpss->data.uport)
> +		lpss->data.uport->dma = NULL;
>  }
>  
>  #ifdef CONFIG_SERIAL_8250_DMA
> @@ -332,8 +328,6 @@ static int lpss8250_probe(struct pci_dev *pdev, const struct pci_device_id *id)
>  		return ret;
>  
>  	lpss->board = (struct lpss8250_board *)id->driver_data;
> -	/* for tests in lpss->board->exit() */
> -	lpss->data.line = -1;
>  
>  	memset(&uart, 0, sizeof(struct uart_8250_port));
>  
> @@ -361,11 +355,12 @@ static int lpss8250_probe(struct pci_dev *pdev, const struct pci_device_id *id)
>  	if (ret)
>  		goto err_exit;
>  
> -	ret = serial8250_register_8250_port(&uart);
> -	if (ret < 0)
> +	struct uart_8250_port *uport = serial8250_register_8250_port(&uart);
> +	if (IS_ERR(uport)) {
> +		ret = PTR_ERR(uport);

Add err.h

Some other cases had the include added so you might want to check all the 
files you're adding IS_ERR/PTR_ERR() to if they already have err.h or not.

--
 i.

  reply	other threads:[~2026-10-09 11:25 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <cover.1791524724.git.jirislaby@kernel.org>
2026-10-09  5:46 ` [PATCH 1/3] serial: 8250_lpss: do not touch uninitialized line in ehl_serial_exit() Jiri Slaby (SUSE)
2026-10-09 11:11   ` Ilpo Järvinen
2026-10-10  5:46   ` sashiko-bot
2026-10-11  9:29     ` Jiri Slaby
2026-10-09  5:46 ` [PATCH 2/3] serial: 8250_omap: set priv->line before enabling the IRQ Jiri Slaby (SUSE)
2026-10-10  5:46   ` sashiko-bot
2026-10-09  5:46 ` [PATCH 3/3] serial: 8250: make port operations work on struct uart_8250_port Jiri Slaby (SUSE)
2026-10-09 11:25   ` Ilpo Järvinen [this message]
2026-10-10  5:46   ` sashiko-bot

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=9a08fb1a-1e2d-6477-06db-b201c8c425b4@linux.intel.com \
    --to=ilpo.jarvinen@linux.intel.com \
    --cc=James.Bottomley@HansenPartnership.com \
    --cc=alcooperx@gmail.com \
    --cc=andrew+netdev@lunn.ch \
    --cc=andrew@codeconstruct.com.au \
    --cc=andriy.shevchenko@linux.intel.com \
    --cc=angelogioacchino.delregno@collabora.com \
    --cc=bcm-kernel-feedback-list@broadcom.com \
    --cc=billy_tsai@aspeedtech.com \
    --cc=chaitanya.vadrevu@emerson.com \
    --cc=davem@davemloft.net \
    --cc=deller@gmx.de \
    --cc=edumazet@kernel.org \
    --cc=florian.fainelli@broadcom.com \
    --cc=gregkh@linuxfoundation.org \
    --cc=gustavoars@kernel.org \
    --cc=hayashi.kunihiko@socionext.com \
    --cc=jirislaby@kernel.org \
    --cc=joel@jms.id.au \
    --cc=jonathanh@nvidia.com \
    --cc=kees@kernel.org \
    --cc=kuba@kernel.org \
    --cc=kumaravel.thiagarajan@microchip.com \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-aspeed@lists.ozlabs.org \
    --cc=linux-hardening@vger.kernel.org \
    --cc=linux-mediatek@lists.infradead.org \
    --cc=linux-mips@vger.kernel.org \
    --cc=linux-parisc@vger.kernel.org \
    --cc=linux-rpi-kernel@lists.infradead.org \
    --cc=linux-serial@vger.kernel.org \
    --cc=linux-tegra@vger.kernel.org \
    --cc=matthias.bgg@gmail.com \
    --cc=mhiramat@kernel.org \
    --cc=netdev@vger.kernel.org \
    --cc=pabeni@redhat.com \
    --cc=paul@crapouillou.net \
    --cc=richardcochran@gmail.com \
    --cc=rjui@broadcom.com \
    --cc=ryan_chen@aspeedtech.com \
    --cc=sbranden@broadcom.com \
    --cc=thierry.reding@kernel.org \
    --cc=u.kleine-koenig@baylibre.com \
    --cc=vadim.fedorenko@linux.dev \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.