{"id":2175506,"url":"http://patchwork.ozlabs.org/api/1.0/patches/2175506/?format=json","project":{"id":67,"url":"http://patchwork.ozlabs.org/api/1.0/projects/67/?format=json","name":"OpenSBI development","link_name":"opensbi","list_id":"opensbi.lists.infradead.org","list_email":"opensbi@lists.infradead.org","web_url":"https://github.com/riscv/opensbi","scm_url":"","webscm_url":""},"msgid":"<20251218104243.562667-7-ganboing@gmail.com>","date":"2025-12-18T10:42:42","name":"[v6,6/7] lib: utils/serial: Support multiple UART8250 devices","commit_ref":null,"pull_url":null,"state":"accepted","archived":false,"hash":"8459d7b176571cd8772213ca5cdd810826849a64","submitter":{"id":86401,"url":"http://patchwork.ozlabs.org/api/1.0/people/86401/?format=json","name":"Bo Gan","email":"ganboing@gmail.com"},"delegate":null,"mbox":"http://patchwork.ozlabs.org/project/opensbi/patch/20251218104243.562667-7-ganboing@gmail.com/mbox/","series":[{"id":485819,"url":"http://patchwork.ozlabs.org/api/1.0/series/485819/?format=json","date":"2025-12-18T10:42:37","name":"Initial ESWIN/EIC7700 and Hifive P550 support","version":6,"mbox":"http://patchwork.ozlabs.org/series/485819/mbox/"}],"check":"pending","checks":"http://patchwork.ozlabs.org/api/patches/2175506/checks/","tags":{},"headers":{"Return-Path":"\n <opensbi-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org>","X-Original-To":"incoming@patchwork.ozlabs.org","Delivered-To":"patchwork-incoming@legolas.ozlabs.org","Authentication-Results":["legolas.ozlabs.org;\n\tdkim=pass (2048-bit key;\n secure) header.d=lists.infradead.org header.i=@lists.infradead.org\n header.a=rsa-sha256 header.s=bombadil.20210309 header.b=qfQmV7GY;\n\tdkim=fail reason=\"signature verification failed\" (2048-bit key;\n unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256\n header.s=20230601 header.b=eGHlZAub;\n\tdkim-atps=neutral","legolas.ozlabs.org;\n spf=none (no SPF record) smtp.mailfrom=lists.infradead.org\n (client-ip=2607:7c80:54:3::133; helo=bombadil.infradead.org;\n envelope-from=opensbi-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org;\n receiver=patchwork.ozlabs.org)"],"Received":["from bombadil.infradead.org (bombadil.infradead.org\n [IPv6:2607:7c80:54:3::133])\n\t(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n\t key-exchange x25519 server-signature ECDSA (secp384r1) server-digest SHA384)\n\t(No client certificate requested)\n\tby legolas.ozlabs.org (Postfix) with ESMTPS id 4dX6kM46kzz1y2f\n\tfor <incoming@patchwork.ozlabs.org>; Thu, 18 Dec 2025 21:44:59 +1100 (AEDT)","from localhost ([::1] helo=bombadil.infradead.org)\n\tby bombadil.infradead.org with esmtp (Exim 4.98.2 #2 (Red Hat Linux))\n\tid 1vWBV5-00000008Flq-2J1F;\n\tThu, 18 Dec 2025 10:44:51 +0000","from mail-pf1-x42d.google.com ([2607:f8b0:4864:20::42d])\n\tby bombadil.infradead.org with esmtps (Exim 4.98.2 #2 (Red Hat Linux))\n\tid 1vWBV3-00000008Fj0-0fMZ\n\tfor opensbi@lists.infradead.org;\n\tThu, 18 Dec 2025 10:44:50 +0000","by mail-pf1-x42d.google.com with SMTP id\n d2e1a72fcca58-7b9c17dd591so438800b3a.3\n        for <opensbi@lists.infradead.org>;\n Thu, 18 Dec 2025 02:44:48 -0800 (PST)","from m91p.airy.home ([172.92.174.155])\n        by smtp.gmail.com with ESMTPSA id\n d2e1a72fcca58-7fe11d3e004sm2264795b3a.15.2025.12.18.02.44.46\n        (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);\n        Thu, 18 Dec 2025 02:44:47 -0800 (PST)"],"DKIM-Signature":["v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed;\n\td=lists.infradead.org; s=bombadil.20210309; h=Sender:\n\tContent-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post:\n\tList-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To:\n\tMessage-Id:Date:Subject:Cc:To:From:Reply-To:Content-ID:Content-Description:\n\tResent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:\n\tList-Owner; bh=3/nTap3S0i0tmw/6s7+TemOH3cvTs4zX5goKMHOFXpc=; b=qfQmV7GYf0yeqw\n\t6YqzcCGfD/YodRrpSSfmn9A+sb+T+7B/U9ur2vzLQcUeUQNxx4zaN/Ch9h7lCQjMX2628DDnRbfZ7\n\tE4XMgBCRoFUkcqsbBUawJFPJzto+Ke64kpjV8HEUUhYPnA7M8P0y1cp7nV0MZbnTrfdLtpq0BnR9k\n\tOi7nWzNrxYzpszz36k6nbKgr29Lyv1zBIm14+D/oIwRHoNAhSi5jp+onP1AEAjmK3dQxmHyE/34eX\n\tAdSFqYUmzBL9xftbx7jvhWewE5i6APGehdpApub03gfIEgzVnT0oH/ij2Kt8cuyH1zpQXhgCQb+oM\n\tofhA4/NjSFWSBihQUy2w==;","v=1; a=rsa-sha256; c=relaxed/relaxed;\n        d=gmail.com; s=20230601; t=1766054688; x=1766659488;\n darn=lists.infradead.org;\n        h=content-transfer-encoding:mime-version:references:in-reply-to\n         :message-id:date:subject:cc:to:from:from:to:cc:subject:date\n         :message-id:reply-to;\n        bh=LIT4B15Uv7s4AxSGReqiIk/KbR2zK/NhVJ+urA9SX8I=;\n        b=eGHlZAubSYpJF2A0MuT00OYdi2IYx4xXh5c0sG1Drl2sKO1dOzidNDgWFtoDoOzR8r\n         vTmhu5/TiJ7Rp/6lT0zHrc4s0buHpv59C+GWFCq4BfzXPKtTE6GmhWAzyUPgFlwtrDOI\n         EkmF7818Z9Ni1U9IyfRx0jt8wM7ZqdggTla5rkjMaq0wkt3NUh7ZMifWz+qpQQDVIBZC\n         2jukmYn8E5GHr5j2IcYBZ4u4qpbqIm1B3MX2cMQ9fnT81rTEnILO4u+YXhHpGLY14C+n\n         ZIufUyKYdwfhT4s3j2bcqOMcqdjteLELt3Eyw+lClKP5z1FMRhSqqaIMvreNbJpLFjoE\n         MvvQ=="],"X-Google-DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n        d=1e100.net; s=20230601; t=1766054688; x=1766659488;\n        h=content-transfer-encoding:mime-version:references:in-reply-to\n         :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from\n         :to:cc:subject:date:message-id:reply-to;\n        bh=LIT4B15Uv7s4AxSGReqiIk/KbR2zK/NhVJ+urA9SX8I=;\n        b=dXhl/y4L5oSGXigpDPRVNV/XJIGCbBcv92ryNL44FjXna6ZLFozZkc1KpKr3lZK949\n         4+iJSMnXhdRzJKfE79ekAANlW3259I9NvalK91nkfjiBWskOOeNcizgLRC/HE/+OMJVy\n         aV3wnj3GMD15NtRZfgW0zXS0+7kBGpe9YL7+bg+inLGY/82+aRwOUKEVcMFRAz9YopUL\n         QUwrjbtxr6b+/m40zoYSiGMCa/C0uqwI97WwxbYzQbjyqEFuZUdkj4OxZ98uYzxoB6Eo\n         /9EuwfhjljTUVdmtJyJXPxT7k6HI98vDx0tv1WPWDlBLdcFHeKxU/w7lVzN9BqJh2oTa\n         DrPQ==","X-Gm-Message-State":"AOJu0YwGRDIErQee48a29AftoA85Kr9ZS08be2X0wZBes9X/Om5qAhgE\n\tpxokk3bK1Q4p4/OK+IM76wkU0BDKEhowznsDRn6cQ8JXxxF6si3/OJj/pDaYAQ==","X-Gm-Gg":"AY/fxX5t/pOl6LbrAVPAYZJsv/V9f9L8ZSh8aDlyO5wYKpOF9w3+oCC6eaz+iKT+k2M\n\tKycWmkBMaFGMbPiM++u10Inbm0VtPZcLeofspD6sgymaQSLLpMs9BuRFAKtR/SMkxxGx02KZBF0\n\tThu6q9IwkfPpvy4g2xa7tliNQo3qDMX5QF/Ne4RxIcvORKTwfvGaPfiS9SXd4DIXpRTGxzhv9PN\n\tRaY4BCGs1s/THsTKu03IfEEQ8th5iwGNBoYh4vfQwJWbG6aoJhCjNTWbe3wz/pik6LbVXhX0S0V\n\tzehlS6iV4Iep1ICcQoziddKkrT3pxfG66rGzI8mFNnWcfIl5hFjDlkK/S/1Glbn/Jp2hDIlp1Ex\n\tqvfBLTAQF+k2AD0p8F5KOHQnDPBJc3VwUrYRYCu9Wgm9Li4sAcF2IM+6hnvzBtlRfSHlwxFk6XX\n\txzEfKJ0bgiYfx5GIkAOeOYypE=","X-Google-Smtp-Source":"\n AGHT+IELSopj+pORQaVC9LHLoCy2Etb+kFTugvMx0m+ha5uxU0ieyuK1ogxET3ohYoURMzzUcre4Ug==","X-Received":"by 2002:a05:6a00:1c8e:b0:7ef:3f4e:9172 with SMTP id\n d2e1a72fcca58-7f66754899emr21621150b3a.8.1766054687668;\n        Thu, 18 Dec 2025 02:44:47 -0800 (PST)","From":"Bo Gan <ganboing@gmail.com>","To":"opensbi@lists.infradead.org","Cc":"linmin@eswincomputing.com,\n\tpinkesh.vaghela@einfochips.com,\n\tgaohan@iscas.ac.cn,\n\tsamuel@sholland.org,\n\twangxiang@iscas.ac.cn","Subject":"[PATCH v6 6/7] lib: utils/serial: Support multiple UART8250 devices","Date":"Thu, 18 Dec 2025 02:42:42 -0800","Message-Id":"<20251218104243.562667-7-ganboing@gmail.com>","X-Mailer":"git-send-email 2.34.1","In-Reply-To":"<20251218104243.562667-1-ganboing@gmail.com>","References":"<20251218104243.562667-1-ganboing@gmail.com>","MIME-Version":"1.0","X-CRM114-Version":"20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 ","X-CRM114-CacheID":"sfid-20251218_024449_195154_87E259C6 ","X-CRM114-Status":"GOOD (  15.77  )","X-Spam-Score":"-2.1 (--)","X-Spam-Report":"Spam detection software,\n running on the system \"bombadil.infradead.org\",\n has NOT identified this incoming email as spam.  The original\n message has been attached to this so you can view it or label\n similar future email.  If you have any questions, see\n the administrator of that system for details.\n Content preview:  Previously we assume only 1 UART8250 instance can be used.\n    Now we support multiple instances by introducing counterpart functions to\n    putc/getc/init which take an extra *dev parameter, and name them as [...]    \n Content analysis details:   (-2.1 points, 5.0 required)\n  pts rule name              description\n ---- ----------------------\n --------------------------------------------------\n -0.0 RCVD_IN_DNSWL_NONE     RBL: Sender listed at https://www.dnswl.org/, no\n                             trust\n                             [2607:f8b0:4864:20:0:0:0:42d listed in]\n                             [list.dnswl.org]\n -0.0 SPF_PASS               SPF: sender matches SPF record\n  0.0 SPF_HELO_NONE          SPF: HELO does not publish an SPF Record\n -0.1 DKIM_VALID_EF          Message has a valid DKIM or DK signature from\n                             envelope-from domain\n -0.1 DKIM_VALID_AU          Message has a valid DKIM or DK signature from\n author's\n                             domain\n -0.1 DKIM_VALID             Message has at least one valid DKIM or DK\n signature\n  0.1 DKIM_SIGNED            Message has a DKIM or DK signature,\n not necessarily valid\n -1.9 BAYES_00               BODY: Bayes spam probability is 0 to 1%\n                             [score: 0.0000]\n  0.0 FREEMAIL_FROM          Sender email is commonly abused enduser mail\n provider\n                             [ganboing(at)gmail.com]","X-BeenThere":"opensbi@lists.infradead.org","X-Mailman-Version":"2.1.34","Precedence":"list","List-Id":"<opensbi.lists.infradead.org>","List-Unsubscribe":"<http://lists.infradead.org/mailman/options/opensbi>,\n <mailto:opensbi-request@lists.infradead.org?subject=unsubscribe>","List-Archive":"<http://lists.infradead.org/pipermail/opensbi/>","List-Post":"<mailto:opensbi@lists.infradead.org>","List-Help":"<mailto:opensbi-request@lists.infradead.org?subject=help>","List-Subscribe":"<http://lists.infradead.org/mailman/listinfo/opensbi>,\n <mailto:opensbi-request@lists.infradead.org?subject=subscribe>","Content-Type":"text/plain; charset=\"us-ascii\"","Content-Transfer-Encoding":"7bit","Sender":"\"opensbi\" <opensbi-bounces@lists.infradead.org>","Errors-To":"opensbi-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org"},"content":"Previously we assume only 1 UART8250 instance can be used. Now we support\nmultiple instances by introducing counterpart functions to putc/getc/init\nwhich take an extra *dev parameter, and name them as uart8250_device_xyz()\nThe original functions without the *dev parameter will operate on the\ndefault instance exactly the same as before, so no changes on the caller\nis required.\n\nNote: uart8250_device_init only does device initialization without the\nconsole registration logic.\n\nSigned-off-by: Bo Gan <ganboing@gmail.com>\n---\n include/sbi_utils/serial/uart8250.h |  16 +++++\n lib/utils/serial/uart8250.c         | 104 ++++++++++++++++------------\n 2 files changed, 75 insertions(+), 45 deletions(-)","diff":"diff --git a/include/sbi_utils/serial/uart8250.h b/include/sbi_utils/serial/uart8250.h\nindex 70cd2912..78c0e614 100644\n--- a/include/sbi_utils/serial/uart8250.h\n+++ b/include/sbi_utils/serial/uart8250.h\n@@ -14,6 +14,22 @@\n \n #define UART_CAP_UUE\tBIT(0)\t/* Check UUE capability for XScale PXA UARTs */\n \n+struct uart8250_device {\n+\tvolatile char *base;\n+\tu32 in_freq;\n+\tu32 baudrate;\n+\tu32 reg_width;\n+\tu32 reg_shift;\n+};\n+\n+int uart8250_device_getc(struct uart8250_device *dev);\n+\n+void uart8250_device_putc(struct uart8250_device *dev, char ch);\n+\n+void uart8250_device_init(struct uart8250_device *dev, unsigned long base,\n+\t\t\t  u32 in_freq, u32 baudrate, u32 reg_shift,\n+\t\t\t  u32 reg_width, u32 reg_offset, u32 caps);\n+\n int uart8250_init(unsigned long base, u32 in_freq, u32 baudrate, u32 reg_shift,\n \t\t  u32 reg_width, u32 reg_offset, u32 caps);\n \ndiff --git a/lib/utils/serial/uart8250.c b/lib/utils/serial/uart8250.c\nindex bb209c9a..d65f127d 100644\n--- a/lib/utils/serial/uart8250.c\n+++ b/lib/utils/serial/uart8250.c\n@@ -47,97 +47,111 @@\n \n /* clang-format on */\n \n-static volatile char *uart8250_base;\n-static u32 uart8250_in_freq;\n-static u32 uart8250_baudrate;\n-static u32 uart8250_reg_width;\n-static u32 uart8250_reg_shift;\n+static struct uart8250_device uart8250_dev;\n \n-static u32 get_reg(u32 num)\n+static u32 get_reg(struct uart8250_device *dev, u32 num)\n {\n-\tu32 offset = num << uart8250_reg_shift;\n+\tu32 offset = num << dev->reg_shift;\n \n-\tif (uart8250_reg_width == 1)\n-\t\treturn readb(uart8250_base + offset);\n-\telse if (uart8250_reg_width == 2)\n-\t\treturn readw(uart8250_base + offset);\n+\tif (dev->reg_width == 1)\n+\t\treturn readb(dev->base + offset);\n+\telse if (dev->reg_width == 2)\n+\t\treturn readw(dev->base + offset);\n \telse\n-\t\treturn readl(uart8250_base + offset);\n+\t\treturn readl(dev->base + offset);\n }\n \n-static void set_reg(u32 num, u32 val)\n+static void set_reg(struct uart8250_device *dev, u32 num, u32 val)\n {\n-\tu32 offset = num << uart8250_reg_shift;\n+\tu32 offset = num << dev->reg_shift;\n \n-\tif (uart8250_reg_width == 1)\n-\t\twriteb(val, uart8250_base + offset);\n-\telse if (uart8250_reg_width == 2)\n-\t\twritew(val, uart8250_base + offset);\n+\tif (dev->reg_width == 1)\n+\t\twriteb(val, dev->base + offset);\n+\telse if (dev->reg_width == 2)\n+\t\twritew(val, dev->base + offset);\n \telse\n-\t\twritel(val, uart8250_base + offset);\n+\t\twritel(val, dev->base + offset);\n }\n \n-static void uart8250_putc(char ch)\n+void uart8250_device_putc(struct uart8250_device *dev, char ch)\n {\n-\twhile ((get_reg(UART_LSR_OFFSET) & UART_LSR_THRE) == 0)\n+\twhile ((get_reg(dev, UART_LSR_OFFSET) & UART_LSR_THRE) == 0)\n \t\t;\n \n-\tset_reg(UART_THR_OFFSET, ch);\n+\tset_reg(dev, UART_THR_OFFSET, ch);\n }\n \n-static int uart8250_getc(void)\n+static void uart8250_putc(char ch)\n {\n-\tif (get_reg(UART_LSR_OFFSET) & UART_LSR_DR)\n-\t\treturn get_reg(UART_RBR_OFFSET);\n+\treturn uart8250_device_putc(&uart8250_dev, ch);\n+}\n+\n+int uart8250_device_getc(struct uart8250_device *dev)\n+{\n+\tif (get_reg(dev, UART_LSR_OFFSET) & UART_LSR_DR)\n+\t\treturn get_reg(dev, UART_RBR_OFFSET);\n \treturn -1;\n }\n \n+static int uart8250_getc(void)\n+{\n+\treturn uart8250_device_getc(&uart8250_dev);\n+}\n+\n static struct sbi_console_device uart8250_console = {\n \t.name = \"uart8250\",\n \t.console_putc = uart8250_putc,\n \t.console_getc = uart8250_getc\n };\n \n-int uart8250_init(unsigned long base, u32 in_freq, u32 baudrate, u32 reg_shift,\n-\t\t  u32 reg_width, u32 reg_offset, u32 caps)\n+void uart8250_device_init(struct uart8250_device *dev, unsigned long base,\n+\t\t\t  u32 in_freq, u32 baudrate, u32 reg_shift,\n+\t\t\t  u32 reg_width, u32 reg_offset, u32 caps)\n {\n \tu16 bdiv = 0;\n \n-\tuart8250_base      = (volatile char *)base + reg_offset;\n-\tuart8250_reg_shift = reg_shift;\n-\tuart8250_reg_width = reg_width;\n-\tuart8250_in_freq   = in_freq;\n-\tuart8250_baudrate  = baudrate;\n+\tdev->base      = (volatile char *)base + reg_offset;\n+\tdev->reg_shift = reg_shift;\n+\tdev->reg_width = reg_width;\n+\tdev->in_freq   = in_freq;\n+\tdev->baudrate  = baudrate;\n \n-\tif (uart8250_baudrate) {\n-\t\tbdiv = (uart8250_in_freq + 8 * uart8250_baudrate) /\n-\t\t       (16 * uart8250_baudrate);\n+\tif (dev->baudrate) {\n+\t\tbdiv = (dev->in_freq + 8 * dev->baudrate) /\n+\t\t       (16 * dev->baudrate);\n \t}\n \n \t/* Disable all interrupts */\n-\tset_reg(UART_IER_OFFSET, (caps & UART_CAP_UUE) ?\n+\tset_reg(dev, UART_IER_OFFSET, (caps & UART_CAP_UUE) ?\n \t\t\t\t UART_IER_UUE : 0x00);\n \t/* Enable DLAB */\n-\tset_reg(UART_LCR_OFFSET, 0x80);\n+\tset_reg(dev, UART_LCR_OFFSET, 0x80);\n \n \tif (bdiv) {\n \t\t/* Set divisor low byte */\n-\t\tset_reg(UART_DLL_OFFSET, bdiv & 0xff);\n+\t\tset_reg(dev, UART_DLL_OFFSET, bdiv & 0xff);\n \t\t/* Set divisor high byte */\n-\t\tset_reg(UART_DLM_OFFSET, (bdiv >> 8) & 0xff);\n+\t\tset_reg(dev, UART_DLM_OFFSET, (bdiv >> 8) & 0xff);\n \t}\n \n \t/* 8 bits, no parity, one stop bit */\n-\tset_reg(UART_LCR_OFFSET, 0x03);\n+\tset_reg(dev, UART_LCR_OFFSET, 0x03);\n \t/* Enable FIFO */\n-\tset_reg(UART_FCR_OFFSET, 0x01);\n+\tset_reg(dev, UART_FCR_OFFSET, 0x01);\n \t/* No modem control DTR RTS */\n-\tset_reg(UART_MCR_OFFSET, 0x00);\n+\tset_reg(dev, UART_MCR_OFFSET, 0x00);\n \t/* Clear line status and read receive buffer */\n-\tif (get_reg(UART_LSR_OFFSET) & UART_LSR_DR)\n-\t\tget_reg(UART_RBR_OFFSET);\n+\tif (get_reg(dev, UART_LSR_OFFSET) & UART_LSR_DR)\n+\t\tget_reg(dev, UART_RBR_OFFSET);\n \t/* Set scratchpad */\n-\tset_reg(UART_SCR_OFFSET, 0x00);\n+\tset_reg(dev, UART_SCR_OFFSET, 0x00);\n+}\n+\n+int uart8250_init(unsigned long base, u32 in_freq, u32 baudrate, u32 reg_shift,\n+\t\t  u32 reg_width, u32 reg_offset, u32 caps)\n+{\n+\tuart8250_device_init(&uart8250_dev, base, in_freq, baudrate,\n+\t\t\t     reg_shift, reg_width, reg_offset, caps);\n \n \tsbi_console_set_device(&uart8250_console);\n \n","prefixes":["v6","6/7"]}