From nobody Thu Apr 9 11:17:39 2026 Received: from mail-ed1-f46.google.com (mail-ed1-f46.google.com [209.85.208.46]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 2E78E37C0FE for ; Mon, 9 Mar 2026 11:19:07 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.208.46 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773055149; cv=none; b=e/jRNjegiWvlUSqdAt2pnaQiqbArze2EHDIR97hI3NjXbY0fpQQAe/+k44oXNG1+iyzp17iXxJ1fSQfj50hpiU/Vx3shsGokUGjo0Vrp5bRN0UminokYfbkvzDWCAYI3dT9CmJCGWylP7JsmMYxwpZOzJaApJAg9jdCMwAoSca4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773055149; c=relaxed/simple; bh=/QT+ZsyT1g5zM93+IVQrwcQq8LP1sj3UTRUjMHmJ/iA=; h=From:To:Cc:Subject:Date:Message-ID:MIME-Version; b=ggKUEnraZKXi4pelwd0RhentZFnTFqLIU2YRYpwK+5veX9cAHT1gmHPhc+ZV14leJldEqVeKMbYNYGF0UKW+7i8LpurADT9fd0PT4/gsPFqZ4l2TCdvB+Q7+Ih2kGpStqS2LdbjJrQ1n/SkQ85PRzZH5nQQiA09FgD7rI9r5aoA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=BXIVRZs8; arc=none smtp.client-ip=209.85.208.46 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="BXIVRZs8" Received: by mail-ed1-f46.google.com with SMTP id 4fb4d7f45d1cf-6611e4aefdcso8090292a12.3 for ; Mon, 09 Mar 2026 04:19:06 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1773055145; x=1773659945; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:sender:from:to:cc:subject:date:message-id:reply-to; bh=UTOjzeQyqSqftgSUxo2hsCAem+/pzZYpTqKtA7wVqy8=; b=BXIVRZs87U3+BS0l/MN4+Yrpuj2g8Xk1TT+s4eo58dLSUwRvd4Dpgoh7cm+wDhg232 X0WZ27njFdEAIDSU7IoYoKKCiMk36Yua3fEflhGhXeNMkgP5uhnIYXQRi09k4SrRXfzK 26P439BqUIswpOj4pv7fW9JR+hXmCEhUGxHKKmFV6Iuhae4MMb1NtaocGJSpITlEMMPN Vxp5hL55BPRqAn2l5zVyYWJVw86DfN7MGnEIWS+0I+WmGdjxYDlO/fyoT46XHPQk3/jS Tmab3h9G/HuPhpqaLAniRVqLMxATE/yvgAgX0DBVDjIy2MFTsyoQDD1wgrgVNNKBV332 dnXQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1773055145; x=1773659945; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:sender:x-gm-gg:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=UTOjzeQyqSqftgSUxo2hsCAem+/pzZYpTqKtA7wVqy8=; b=P2aR6395UO044IEGxJ/tC/OtCmzEcJk+8KfwWmjfUokkCLspmKONOKmYZPG06sW3jP 9evkhh9M7KF6vGJxwr2aQyw4yWBHzfnJi/wYtvxJQGF4LkQYn7hyXyWxJapG9oVq2S1g d/xclAaRW6i+py9+6yCfsX6SsuVl0vBfdSvFtpIEqgRzke1Q61bTPzq5mHuGJw1I8x0Q oPZJIahE/emsWZOOu9pBbsy8DXh24JjNDRshR054/3XfDssP+Gdd7UhmbXWVKjGIpb5X FDlA4xXv2fVE2u7AH0/i8wfES0JtARUrbGuSCx2vwvVSFn3tC4V0lPPVnMinEUxMfzlC H7jg== X-Forwarded-Encrypted: i=1; AJvYcCXoWKj30Z1ZLxtQb4i8tYu5BBee80nq6lOayYvbprJxnsCknBHu4L/1RrLKeB1/1UH7fibPbCYiazgwfM8=@vger.kernel.org X-Gm-Message-State: AOJu0Yx4Q4aPKceILtjWeeby/K5A853R0vtaVvwk6VZnPpWH3PEaIkcH aqKtYfNLHNf/MqKXbOzEX12ySSqQ60Ae8ZzNHyAK5ljvThv9YWl3EXGf X-Gm-Gg: ATEYQzyyjhkUZoG0TPg3rqpGGjU4UhxTTCyLVu9gic0hcPTWQni8su1nC1SIKnyM1d2 /k5Fg6w4facItaqGIyfCc1sAK6qHrsIw+3Fcz0gKqBh6zz4o5nT7Xe5PorM36pgSbj7HSnFanD2 BJzrebKul4cv7K11FlB9trcTcbDYADKnoT6ODmJ6zs7NYU55GagW/gYna28vgaaH5XamNl6ciym lezocUCpjXGiFtaibLvqzLm5+VrYVyKk9Bn+WqjxAk7luH46Xi2W6piDYH+qPHfzhJWI6xfGgR2 fCVjEXSdfv1NkgzkKi8z5HZvvhcly+x4qL/pBRRsNKxdzN0xsDqcGCh78sqxAhneuwtQH2TqlUZ IMGjKRLESjYUb+WyrTp/6e1HxnGKkaG5eicDaX4MGPMexaBI9iwNX9DSEey9Xt1lgnc77jJdcmJ 1pkWPMrYaz1wHl29fxPxh9I3QeeCuQKDjov/ANPQnE8/YHdN0n4j5OxlHknZK/7cpyFOo7eQ== X-Received: by 2002:a17:907:2d9e:b0:b97:7a:768e with SMTP id a640c23a62f3a-b97007a8663mr102441566b.12.1773055145011; Mon, 09 Mar 2026 04:19:05 -0700 (PDT) Received: from nixos-office (98.206.213.193.static.cust.telenor.net. [193.213.206.98]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-b9431c02a56sm349671766b.39.2026.03.09.04.19.03 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 09 Mar 2026 04:19:04 -0700 (PDT) Sender: Julian Braha From: Julian Braha To: gregkh@linuxfoundation.org, jcmvbkbc@gmail.com Cc: rdunlap@infradead.org, ilpo.jarvinen@linux.intel.com, conor+dt@kernel.org, robh+dt@kernel.org, jirislaby@kernel.org, linux-serial@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, Julian Braha Subject: [PATCH] serial: remove drivers for espressif esp32 Date: Mon, 9 Mar 2026 11:18:48 +0000 Message-ID: <20260309111848.1516412-1-julianbraha@gmail.com> X-Mailer: git-send-email 2.51.2 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" Following the conversation here: https://lore.kernel.org/all/20260308131412.1102749-1-julianbraha@gmail.com/ There was an agreement to delete these drivers for now. Signed-off-by: Julian Braha --- drivers/tty/serial/Kconfig | 26 -- drivers/tty/serial/Makefile | 2 - drivers/tty/serial/esp32_acm.c | 459 ------------------- drivers/tty/serial/esp32_uart.c | 779 -------------------------------- 4 files changed, 1266 deletions(-) delete mode 100644 drivers/tty/serial/esp32_acm.c delete mode 100644 drivers/tty/serial/esp32_uart.c diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig index f86775cfdcc9..686e7fb073b8 100644 --- a/drivers/tty/serial/Kconfig +++ b/drivers/tty/serial/Kconfig @@ -1593,32 +1593,6 @@ config SERIAL_NUVOTON_MA35D1_CONSOLE but you can alter that using a kernel command line option such as "console=3DttyNVTx". =20 -config SERIAL_ESP32 - tristate "Espressif ESP32 UART support" - depends on XTENSA_PLATFORM_ESP32 || (COMPILE_TEST && OF) - select SERIAL_CORE - select SERIAL_CORE_CONSOLE - select SERIAL_EARLYCON - help - Driver for the UART controllers of the Espressif ESP32xx SoCs. - When earlycon option is enabled the following kernel command line - snippets may be used: - earlycon=3Desp32s3uart,mmio32,0x60000000,115200n8,40000000 - earlycon=3Desp32uart,mmio32,0x3ff40000,115200n8 - -config SERIAL_ESP32_ACM - tristate "Espressif ESP32 USB ACM gadget support" - depends on XTENSA_PLATFORM_ESP32 || (COMPILE_TEST && OF) - select SERIAL_CORE - select SERIAL_CORE_CONSOLE - select SERIAL_EARLYCON - help - Driver for the CDC ACM gadget controller of the Espressif ESP32S3 - SoCs that share separate USB controller with the JTAG adapter. - When earlycon option is enabled the following kernel command line - snippet may be used: - earlycon=3Desp32s3acm,mmio32,0x60038000 - endmenu =20 config SERIAL_MCTRL_GPIO diff --git a/drivers/tty/serial/Makefile b/drivers/tty/serial/Makefile index a2ccbc508ec5..bba7b21a4a1d 100644 --- a/drivers/tty/serial/Makefile +++ b/drivers/tty/serial/Makefile @@ -37,8 +37,6 @@ obj-$(CONFIG_SERIAL_CLPS711X) +=3D clps711x.o obj-$(CONFIG_SERIAL_CPM) +=3D cpm_uart.o obj-$(CONFIG_SERIAL_CONEXANT_DIGICOLOR) +=3D digicolor-usart.o obj-$(CONFIG_SERIAL_DZ) +=3D dz.o -obj-$(CONFIG_SERIAL_ESP32) +=3D esp32_uart.o -obj-$(CONFIG_SERIAL_ESP32_ACM) +=3D esp32_acm.o obj-$(CONFIG_SERIAL_FSL_LINFLEXUART) +=3D fsl_linflexuart.o obj-$(CONFIG_SERIAL_FSL_LPUART) +=3D fsl_lpuart.o obj-$(CONFIG_SERIAL_ICOM) +=3D icom.o diff --git a/drivers/tty/serial/esp32_acm.c b/drivers/tty/serial/esp32_acm.c deleted file mode 100644 index bb7cc65427f0..000000000000 --- a/drivers/tty/serial/esp32_acm.c +++ /dev/null @@ -1,459 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define DRIVER_NAME "esp32s3-acm" -#define DEV_NAME "ttyGS" -#define UART_NR 4 - -#define ESP32S3_ACM_TX_FIFO_SIZE 64 - -#define USB_SERIAL_JTAG_EP1_REG 0x00 -#define USB_SERIAL_JTAG_EP1_CONF_REG 0x04 -#define USB_SERIAL_JTAG_WR_DONE BIT(0) -#define USB_SERIAL_JTAG_SERIAL_IN_EP_DATA_FREE BIT(1) -#define USB_SERIAL_JTAG_INT_ST_REG 0x0c -#define USB_SERIAL_JTAG_SERIAL_OUT_RECV_PKT_INT_ST BIT(2) -#define USB_SERIAL_JTAG_SERIAL_IN_EMPTY_INT_ST BIT(3) -#define USB_SERIAL_JTAG_INT_ENA_REG 0x10 -#define USB_SERIAL_JTAG_SERIAL_OUT_RECV_PKT_INT_ENA BIT(2) -#define USB_SERIAL_JTAG_SERIAL_IN_EMPTY_INT_ENA BIT(3) -#define USB_SERIAL_JTAG_INT_CLR_REG 0x14 -#define USB_SERIAL_JTAG_IN_EP1_ST_REG 0x2c -#define USB_SERIAL_JTAG_IN_EP1_WR_ADDR GENMASK(8, 2) -#define USB_SERIAL_JTAG_OUT_EP1_ST_REG 0x3c -#define USB_SERIAL_JTAG_OUT_EP1_REC_DATA_CNT GENMASK(22, 16) - -static const struct of_device_id esp32s3_acm_dt_ids[] =3D { - { - .compatible =3D "esp,esp32s3-acm", - }, { /* sentinel */ } -}; -MODULE_DEVICE_TABLE(of, esp32s3_acm_dt_ids); - -static struct uart_port *esp32s3_acm_ports[UART_NR]; - -static void esp32s3_acm_write(struct uart_port *port, unsigned long reg, u= 32 v) -{ - writel(v, port->membase + reg); -} - -static u32 esp32s3_acm_read(struct uart_port *port, unsigned long reg) -{ - return readl(port->membase + reg); -} - -static u32 esp32s3_acm_tx_fifo_free(struct uart_port *port) -{ - u32 status =3D esp32s3_acm_read(port, USB_SERIAL_JTAG_EP1_CONF_REG); - - return status & USB_SERIAL_JTAG_SERIAL_IN_EP_DATA_FREE; -} - -static u32 esp32s3_acm_tx_fifo_cnt(struct uart_port *port) -{ - u32 status =3D esp32s3_acm_read(port, USB_SERIAL_JTAG_IN_EP1_ST_REG); - - return FIELD_GET(USB_SERIAL_JTAG_IN_EP1_WR_ADDR, status); -} - -static u32 esp32s3_acm_rx_fifo_cnt(struct uart_port *port) -{ - u32 status =3D esp32s3_acm_read(port, USB_SERIAL_JTAG_OUT_EP1_ST_REG); - - return FIELD_GET(USB_SERIAL_JTAG_OUT_EP1_REC_DATA_CNT, status); -} - -/* return TIOCSER_TEMT when transmitter is not busy */ -static unsigned int esp32s3_acm_tx_empty(struct uart_port *port) -{ - return esp32s3_acm_tx_fifo_cnt(port) =3D=3D 0 ? TIOCSER_TEMT : 0; -} - -static void esp32s3_acm_set_mctrl(struct uart_port *port, unsigned int mct= rl) -{ -} - -static unsigned int esp32s3_acm_get_mctrl(struct uart_port *port) -{ - return TIOCM_CAR; -} - -static void esp32s3_acm_stop_tx(struct uart_port *port) -{ - u32 int_ena; - - int_ena =3D esp32s3_acm_read(port, USB_SERIAL_JTAG_INT_ENA_REG); - int_ena &=3D ~USB_SERIAL_JTAG_SERIAL_IN_EMPTY_INT_ENA; - esp32s3_acm_write(port, USB_SERIAL_JTAG_INT_ENA_REG, int_ena); -} - -static void esp32s3_acm_rxint(struct uart_port *port) -{ - struct tty_port *tty_port =3D &port->state->port; - u32 rx_fifo_cnt =3D esp32s3_acm_rx_fifo_cnt(port); - unsigned long flags; - u32 i; - - if (!rx_fifo_cnt) - return; - - spin_lock_irqsave(&port->lock, flags); - - for (i =3D 0; i < rx_fifo_cnt; ++i) { - u32 rx =3D esp32s3_acm_read(port, USB_SERIAL_JTAG_EP1_REG); - - ++port->icount.rx; - tty_insert_flip_char(tty_port, rx, TTY_NORMAL); - } - spin_unlock_irqrestore(&port->lock, flags); - - tty_flip_buffer_push(tty_port); -} - -static void esp32s3_acm_push(struct uart_port *port) -{ - if (esp32s3_acm_tx_fifo_free(port)) - esp32s3_acm_write(port, USB_SERIAL_JTAG_EP1_CONF_REG, - USB_SERIAL_JTAG_WR_DONE); -} - -static void esp32s3_acm_put_char(struct uart_port *port, u8 c) -{ - esp32s3_acm_write(port, USB_SERIAL_JTAG_EP1_REG, c); -} - -static void esp32s3_acm_put_char_sync(struct uart_port *port, u8 c) -{ - unsigned long timeout =3D jiffies + HZ; - - while (!esp32s3_acm_tx_fifo_free(port)) { - if (time_after(jiffies, timeout)) { - dev_warn(port->dev, "timeout waiting for TX FIFO\n"); - return; - } - cpu_relax(); - } - esp32s3_acm_put_char(port, c); - esp32s3_acm_push(port); -} - -static void esp32s3_acm_transmit_buffer(struct uart_port *port) -{ - u32 tx_fifo_used; - unsigned int pending; - u8 ch; - - if (!esp32s3_acm_tx_fifo_free(port)) - return; - - tx_fifo_used =3D esp32s3_acm_tx_fifo_cnt(port); - pending =3D uart_port_tx_limited(port, ch, - ESP32S3_ACM_TX_FIFO_SIZE - tx_fifo_used, - true, esp32s3_acm_put_char(port, ch), - ({})); - if (pending) { - u32 int_ena; - - int_ena =3D esp32s3_acm_read(port, USB_SERIAL_JTAG_INT_ENA_REG); - int_ena |=3D USB_SERIAL_JTAG_SERIAL_IN_EMPTY_INT_ENA; - esp32s3_acm_write(port, USB_SERIAL_JTAG_INT_ENA_REG, int_ena); - } - esp32s3_acm_push(port); -} - -static void esp32s3_acm_txint(struct uart_port *port) -{ - esp32s3_acm_transmit_buffer(port); -} - -static irqreturn_t esp32s3_acm_int(int irq, void *dev_id) -{ - struct uart_port *port =3D dev_id; - u32 status; - - status =3D esp32s3_acm_read(port, USB_SERIAL_JTAG_INT_ST_REG); - esp32s3_acm_write(port, USB_SERIAL_JTAG_INT_CLR_REG, status); - - if (status & USB_SERIAL_JTAG_SERIAL_OUT_RECV_PKT_INT_ST) - esp32s3_acm_rxint(port); - if (status & USB_SERIAL_JTAG_SERIAL_IN_EMPTY_INT_ST) - esp32s3_acm_txint(port); - - return IRQ_RETVAL(status); -} - -static void esp32s3_acm_start_tx(struct uart_port *port) -{ - esp32s3_acm_transmit_buffer(port); -} - -static void esp32s3_acm_stop_rx(struct uart_port *port) -{ - u32 int_ena; - - int_ena =3D esp32s3_acm_read(port, USB_SERIAL_JTAG_INT_ENA_REG); - int_ena &=3D ~USB_SERIAL_JTAG_SERIAL_OUT_RECV_PKT_INT_ENA; - esp32s3_acm_write(port, USB_SERIAL_JTAG_INT_ENA_REG, int_ena); -} - -static int esp32s3_acm_startup(struct uart_port *port) -{ - int ret; - - ret =3D request_irq(port->irq, esp32s3_acm_int, 0, DRIVER_NAME, port); - if (ret) - return ret; - esp32s3_acm_write(port, USB_SERIAL_JTAG_INT_ENA_REG, - USB_SERIAL_JTAG_SERIAL_OUT_RECV_PKT_INT_ENA); - - return 0; -} - -static void esp32s3_acm_shutdown(struct uart_port *port) -{ - esp32s3_acm_write(port, USB_SERIAL_JTAG_INT_ENA_REG, 0); - free_irq(port->irq, port); -} - -static void esp32s3_acm_set_termios(struct uart_port *port, - struct ktermios *termios, - const struct ktermios *old) -{ -} - -static const char *esp32s3_acm_type(struct uart_port *port) -{ - return "ESP32S3 ACM"; -} - -/* configure/auto-configure the port */ -static void esp32s3_acm_config_port(struct uart_port *port, int flags) -{ - if (flags & UART_CONFIG_TYPE) - port->type =3D PORT_GENERIC; -} - -#ifdef CONFIG_CONSOLE_POLL -static void esp32s3_acm_poll_put_char(struct uart_port *port, unsigned cha= r c) -{ - esp32s3_acm_put_char_sync(port, c); -} - -static int esp32s3_acm_poll_get_char(struct uart_port *port) -{ - if (esp32s3_acm_rx_fifo_cnt(port)) - return esp32s3_acm_read(port, USB_SERIAL_JTAG_EP1_REG); - else - return NO_POLL_CHAR; -} -#endif - -static const struct uart_ops esp32s3_acm_pops =3D { - .tx_empty =3D esp32s3_acm_tx_empty, - .set_mctrl =3D esp32s3_acm_set_mctrl, - .get_mctrl =3D esp32s3_acm_get_mctrl, - .stop_tx =3D esp32s3_acm_stop_tx, - .start_tx =3D esp32s3_acm_start_tx, - .stop_rx =3D esp32s3_acm_stop_rx, - .startup =3D esp32s3_acm_startup, - .shutdown =3D esp32s3_acm_shutdown, - .set_termios =3D esp32s3_acm_set_termios, - .type =3D esp32s3_acm_type, - .config_port =3D esp32s3_acm_config_port, -#ifdef CONFIG_CONSOLE_POLL - .poll_put_char =3D esp32s3_acm_poll_put_char, - .poll_get_char =3D esp32s3_acm_poll_get_char, -#endif -}; - -static void esp32s3_acm_string_write(struct uart_port *port, const char *s, - unsigned int count) -{ - uart_console_write(port, s, count, esp32s3_acm_put_char_sync); -} - -static void -esp32s3_acm_console_write(struct console *co, const char *s, unsigned int = count) -{ - struct uart_port *port =3D esp32s3_acm_ports[co->index]; - unsigned long flags; - bool locked =3D true; - - if (port->sysrq) - locked =3D false; - else if (oops_in_progress) - locked =3D spin_trylock_irqsave(&port->lock, flags); - else - spin_lock_irqsave(&port->lock, flags); - - esp32s3_acm_string_write(port, s, count); - - if (locked) - spin_unlock_irqrestore(&port->lock, flags); -} - -static struct uart_driver esp32s3_acm_reg; -static struct console esp32s3_acm_console =3D { - .name =3D DEV_NAME, - .write =3D esp32s3_acm_console_write, - .device =3D uart_console_device, - .flags =3D CON_PRINTBUFFER, - .index =3D -1, - .data =3D &esp32s3_acm_reg, -}; - -static void esp32s3_acm_earlycon_write(struct console *con, const char *s, - unsigned int n) -{ - struct earlycon_device *dev =3D con->data; - - uart_console_write(&dev->port, s, n, esp32s3_acm_put_char_sync); -} - -#ifdef CONFIG_CONSOLE_POLL -static int esp32s3_acm_earlycon_read(struct console *con, char *s, unsigne= d int n) -{ - struct earlycon_device *dev =3D con->data; - unsigned int num_read =3D 0; - - while (num_read < n) { - int c =3D esp32s3_acm_poll_get_char(&dev->port); - - if (c =3D=3D NO_POLL_CHAR) - break; - s[num_read++] =3D c; - } - return num_read; -} -#endif - -static int __init esp32s3_acm_early_console_setup(struct earlycon_device *= device, - const char *options) -{ - if (!device->port.membase) - return -ENODEV; - - device->con->write =3D esp32s3_acm_earlycon_write; -#ifdef CONFIG_CONSOLE_POLL - device->con->read =3D esp32s3_acm_earlycon_read; -#endif - return 0; -} - -OF_EARLYCON_DECLARE(esp32s3acm, "esp,esp32s3-acm", - esp32s3_acm_early_console_setup); - -static struct uart_driver esp32s3_acm_reg =3D { - .owner =3D THIS_MODULE, - .driver_name =3D DRIVER_NAME, - .dev_name =3D DEV_NAME, - .nr =3D ARRAY_SIZE(esp32s3_acm_ports), - .cons =3D &esp32s3_acm_console, -}; - -static int esp32s3_acm_probe(struct platform_device *pdev) -{ - struct device_node *np =3D pdev->dev.of_node; - struct uart_port *port; - struct resource *res; - int ret; - - port =3D devm_kzalloc(&pdev->dev, sizeof(*port), GFP_KERNEL); - if (!port) - return -ENOMEM; - - ret =3D of_alias_get_id(np, "serial"); - if (ret < 0) { - dev_err(&pdev->dev, "failed to get alias id, errno %d\n", ret); - return ret; - } - if (ret >=3D UART_NR) { - dev_err(&pdev->dev, "driver limited to %d serial ports\n", - UART_NR); - return -ENOMEM; - } - - port->line =3D ret; - - res =3D platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) - return -ENODEV; - - port->mapbase =3D res->start; - port->membase =3D devm_ioremap_resource(&pdev->dev, res); - if (IS_ERR(port->membase)) - return PTR_ERR(port->membase); - - port->dev =3D &pdev->dev; - port->type =3D PORT_GENERIC; - port->iotype =3D UPIO_MEM; - port->irq =3D platform_get_irq(pdev, 0); - port->ops =3D &esp32s3_acm_pops; - port->flags =3D UPF_BOOT_AUTOCONF; - port->has_sysrq =3D 1; - port->fifosize =3D ESP32S3_ACM_TX_FIFO_SIZE; - - esp32s3_acm_ports[port->line] =3D port; - - platform_set_drvdata(pdev, port); - - return uart_add_one_port(&esp32s3_acm_reg, port); -} - -static void esp32s3_acm_remove(struct platform_device *pdev) -{ - struct uart_port *port =3D platform_get_drvdata(pdev); - - uart_remove_one_port(&esp32s3_acm_reg, port); -} - - -static struct platform_driver esp32s3_acm_driver =3D { - .probe =3D esp32s3_acm_probe, - .remove =3D esp32s3_acm_remove, - .driver =3D { - .name =3D DRIVER_NAME, - .of_match_table =3D esp32s3_acm_dt_ids, - }, -}; - -static int __init esp32s3_acm_init(void) -{ - int ret; - - ret =3D uart_register_driver(&esp32s3_acm_reg); - if (ret) - return ret; - - ret =3D platform_driver_register(&esp32s3_acm_driver); - if (ret) - uart_unregister_driver(&esp32s3_acm_reg); - - return ret; -} - -static void __exit esp32s3_acm_exit(void) -{ - platform_driver_unregister(&esp32s3_acm_driver); - uart_unregister_driver(&esp32s3_acm_reg); -} - -module_init(esp32s3_acm_init); -module_exit(esp32s3_acm_exit); - -MODULE_AUTHOR("Max Filippov "); -MODULE_DESCRIPTION("Espressif ESP32 USB ACM gadget support"); -MODULE_LICENSE("GPL"); diff --git a/drivers/tty/serial/esp32_uart.c b/drivers/tty/serial/esp32_uar= t.c deleted file mode 100644 index 667c2198a03a..000000000000 --- a/drivers/tty/serial/esp32_uart.c +++ /dev/null @@ -1,779 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define DRIVER_NAME "esp32-uart" -#define DEV_NAME "ttyS" -#define UART_NR 3 - -#define ESP32_UART_TX_FIFO_SIZE 127 -#define ESP32_UART_RX_FIFO_SIZE 127 - -#define UART_FIFO_REG 0x00 -#define UART_INT_RAW_REG 0x04 -#define UART_INT_ST_REG 0x08 -#define UART_INT_ENA_REG 0x0c -#define UART_INT_CLR_REG 0x10 -#define UART_RXFIFO_FULL_INT BIT(0) -#define UART_TXFIFO_EMPTY_INT BIT(1) -#define UART_BRK_DET_INT BIT(7) -#define UART_CLKDIV_REG 0x14 -#define ESP32_UART_CLKDIV GENMASK(19, 0) -#define ESP32S3_UART_CLKDIV GENMASK(11, 0) -#define UART_CLKDIV_SHIFT 0 -#define UART_CLKDIV_FRAG GENMASK(23, 20) -#define UART_STATUS_REG 0x1c -#define ESP32_UART_RXFIFO_CNT GENMASK(7, 0) -#define ESP32S3_UART_RXFIFO_CNT GENMASK(9, 0) -#define UART_RXFIFO_CNT_SHIFT 0 -#define UART_DSRN BIT(13) -#define UART_CTSN BIT(14) -#define ESP32_UART_TXFIFO_CNT GENMASK(23, 16) -#define ESP32S3_UART_TXFIFO_CNT GENMASK(25, 16) -#define UART_TXFIFO_CNT_SHIFT 16 -#define UART_CONF0_REG 0x20 -#define UART_PARITY BIT(0) -#define UART_PARITY_EN BIT(1) -#define UART_BIT_NUM GENMASK(3, 2) -#define UART_BIT_NUM_5 0 -#define UART_BIT_NUM_6 1 -#define UART_BIT_NUM_7 2 -#define UART_BIT_NUM_8 3 -#define UART_STOP_BIT_NUM GENMASK(5, 4) -#define UART_STOP_BIT_NUM_1 1 -#define UART_STOP_BIT_NUM_2 3 -#define UART_SW_RTS BIT(6) -#define UART_SW_DTR BIT(7) -#define UART_LOOPBACK BIT(14) -#define UART_TX_FLOW_EN BIT(15) -#define UART_RTS_INV BIT(23) -#define UART_DTR_INV BIT(24) -#define UART_CONF1_REG 0x24 -#define UART_RXFIFO_FULL_THRHD_SHIFT 0 -#define ESP32_UART_TXFIFO_EMPTY_THRHD_SHIFT 8 -#define ESP32S3_UART_TXFIFO_EMPTY_THRHD_SHIFT 10 -#define ESP32_UART_RX_FLOW_EN BIT(23) -#define ESP32S3_UART_RX_FLOW_EN BIT(22) -#define ESP32S3_UART_CLK_CONF_REG 0x78 -#define ESP32S3_UART_SCLK_DIV_B GENMASK(5, 0) -#define ESP32S3_UART_SCLK_DIV_A GENMASK(11, 6) -#define ESP32S3_UART_SCLK_DIV_NUM GENMASK(19, 12) -#define ESP32S3_UART_SCLK_SEL GENMASK(21, 20) -#define APB_CLK 1 -#define RC_FAST_CLK 2 -#define XTAL_CLK 3 -#define ESP32S3_UART_SCLK_EN BIT(22) -#define ESP32S3_UART_RST_CORE BIT(23) -#define ESP32S3_UART_TX_SCLK_EN BIT(24) -#define ESP32S3_UART_RX_SCLK_EN BIT(25) -#define ESP32S3_UART_TX_RST_CORE BIT(26) -#define ESP32S3_UART_RX_RST_CORE BIT(27) - -#define ESP32S3_UART_CLK_CONF_DEFAULT \ - (ESP32S3_UART_RX_SCLK_EN | \ - ESP32S3_UART_TX_SCLK_EN | \ - ESP32S3_UART_SCLK_EN | \ - FIELD_PREP(ESP32S3_UART_SCLK_SEL, XTAL_CLK)) - -struct esp32_port { - struct uart_port port; - struct clk *clk; -}; - -struct esp32_uart_variant { - u32 clkdiv_mask; - u32 rxfifo_cnt_mask; - u32 txfifo_cnt_mask; - u32 txfifo_empty_thrhd_shift; - u32 rx_flow_en; - const char *type; - bool has_clkconf; -}; - -static const struct esp32_uart_variant esp32_variant =3D { - .clkdiv_mask =3D ESP32_UART_CLKDIV, - .rxfifo_cnt_mask =3D ESP32_UART_RXFIFO_CNT, - .txfifo_cnt_mask =3D ESP32_UART_TXFIFO_CNT, - .txfifo_empty_thrhd_shift =3D ESP32_UART_TXFIFO_EMPTY_THRHD_SHIFT, - .rx_flow_en =3D ESP32_UART_RX_FLOW_EN, - .type =3D "ESP32 UART", -}; - -static const struct esp32_uart_variant esp32s3_variant =3D { - .clkdiv_mask =3D ESP32S3_UART_CLKDIV, - .rxfifo_cnt_mask =3D ESP32S3_UART_RXFIFO_CNT, - .txfifo_cnt_mask =3D ESP32S3_UART_TXFIFO_CNT, - .txfifo_empty_thrhd_shift =3D ESP32S3_UART_TXFIFO_EMPTY_THRHD_SHIFT, - .rx_flow_en =3D ESP32S3_UART_RX_FLOW_EN, - .type =3D "ESP32S3 UART", - .has_clkconf =3D true, -}; - -static const struct of_device_id esp32_uart_dt_ids[] =3D { - { - .compatible =3D "esp,esp32-uart", - .data =3D &esp32_variant, - }, { - .compatible =3D "esp,esp32s3-uart", - .data =3D &esp32s3_variant, - }, { /* sentinel */ } -}; -MODULE_DEVICE_TABLE(of, esp32_uart_dt_ids); - -static struct esp32_port *esp32_uart_ports[UART_NR]; - -static const struct esp32_uart_variant *port_variant(struct uart_port *por= t) -{ - return port->private_data; -} - -static void esp32_uart_write(struct uart_port *port, unsigned long reg, u3= 2 v) -{ - writel(v, port->membase + reg); -} - -static u32 esp32_uart_read(struct uart_port *port, unsigned long reg) -{ - return readl(port->membase + reg); -} - -static u32 esp32_uart_tx_fifo_cnt(struct uart_port *port) -{ - u32 status =3D esp32_uart_read(port, UART_STATUS_REG); - - return (status & port_variant(port)->txfifo_cnt_mask) >> UART_TXFIFO_CNT_= SHIFT; -} - -static u32 esp32_uart_rx_fifo_cnt(struct uart_port *port) -{ - u32 status =3D esp32_uart_read(port, UART_STATUS_REG); - - return (status & port_variant(port)->rxfifo_cnt_mask) >> UART_RXFIFO_CNT_= SHIFT; -} - -/* return TIOCSER_TEMT when transmitter is not busy */ -static unsigned int esp32_uart_tx_empty(struct uart_port *port) -{ - return esp32_uart_tx_fifo_cnt(port) ? 0 : TIOCSER_TEMT; -} - -static void esp32_uart_set_mctrl(struct uart_port *port, unsigned int mctr= l) -{ - u32 conf0 =3D esp32_uart_read(port, UART_CONF0_REG); - - conf0 &=3D ~(UART_LOOPBACK | - UART_SW_RTS | UART_RTS_INV | - UART_SW_DTR | UART_DTR_INV); - - if (mctrl & TIOCM_RTS) - conf0 |=3D UART_SW_RTS; - if (mctrl & TIOCM_DTR) - conf0 |=3D UART_SW_DTR; - if (mctrl & TIOCM_LOOP) - conf0 |=3D UART_LOOPBACK; - - esp32_uart_write(port, UART_CONF0_REG, conf0); -} - -static unsigned int esp32_uart_get_mctrl(struct uart_port *port) -{ - u32 status =3D esp32_uart_read(port, UART_STATUS_REG); - unsigned int ret =3D TIOCM_CAR; - - if (status & UART_DSRN) - ret |=3D TIOCM_DSR; - if (status & UART_CTSN) - ret |=3D TIOCM_CTS; - - return ret; -} - -static void esp32_uart_stop_tx(struct uart_port *port) -{ - u32 int_ena; - - int_ena =3D esp32_uart_read(port, UART_INT_ENA_REG); - int_ena &=3D ~UART_TXFIFO_EMPTY_INT; - esp32_uart_write(port, UART_INT_ENA_REG, int_ena); -} - -static void esp32_uart_rxint(struct uart_port *port) -{ - struct tty_port *tty_port =3D &port->state->port; - u32 rx_fifo_cnt =3D esp32_uart_rx_fifo_cnt(port); - unsigned long flags; - u32 i; - - if (!rx_fifo_cnt) - return; - - spin_lock_irqsave(&port->lock, flags); - - for (i =3D 0; i < rx_fifo_cnt; ++i) { - u32 rx =3D esp32_uart_read(port, UART_FIFO_REG); - - if (!rx && - (esp32_uart_read(port, UART_INT_ST_REG) & UART_BRK_DET_INT)) { - esp32_uart_write(port, UART_INT_CLR_REG, UART_BRK_DET_INT); - ++port->icount.brk; - uart_handle_break(port); - } else { - if (uart_handle_sysrq_char(port, (unsigned char)rx)) - continue; - tty_insert_flip_char(tty_port, rx, TTY_NORMAL); - ++port->icount.rx; - } - } - spin_unlock_irqrestore(&port->lock, flags); - - tty_flip_buffer_push(tty_port); -} - -static void esp32_uart_put_char(struct uart_port *port, u8 c) -{ - esp32_uart_write(port, UART_FIFO_REG, c); -} - -static void esp32_uart_put_char_sync(struct uart_port *port, u8 c) -{ - unsigned long timeout =3D jiffies + HZ; - - while (esp32_uart_tx_fifo_cnt(port) >=3D ESP32_UART_TX_FIFO_SIZE) { - if (time_after(jiffies, timeout)) { - dev_warn(port->dev, "timeout waiting for TX FIFO\n"); - return; - } - cpu_relax(); - } - esp32_uart_put_char(port, c); -} - -static void esp32_uart_transmit_buffer(struct uart_port *port) -{ - u32 tx_fifo_used =3D esp32_uart_tx_fifo_cnt(port); - unsigned int pending; - u8 ch; - - if (tx_fifo_used >=3D ESP32_UART_TX_FIFO_SIZE) - return; - - pending =3D uart_port_tx_limited(port, ch, - ESP32_UART_TX_FIFO_SIZE - tx_fifo_used, - true, esp32_uart_put_char(port, ch), - ({})); - if (pending) { - u32 int_ena; - - int_ena =3D esp32_uart_read(port, UART_INT_ENA_REG); - int_ena |=3D UART_TXFIFO_EMPTY_INT; - esp32_uart_write(port, UART_INT_ENA_REG, int_ena); - } -} - -static void esp32_uart_txint(struct uart_port *port) -{ - esp32_uart_transmit_buffer(port); -} - -static irqreturn_t esp32_uart_int(int irq, void *dev_id) -{ - struct uart_port *port =3D dev_id; - u32 status; - - status =3D esp32_uart_read(port, UART_INT_ST_REG); - - if (status & (UART_RXFIFO_FULL_INT | UART_BRK_DET_INT)) - esp32_uart_rxint(port); - if (status & UART_TXFIFO_EMPTY_INT) - esp32_uart_txint(port); - - esp32_uart_write(port, UART_INT_CLR_REG, status); - - return IRQ_RETVAL(status); -} - -static void esp32_uart_start_tx(struct uart_port *port) -{ - esp32_uart_transmit_buffer(port); -} - -static void esp32_uart_stop_rx(struct uart_port *port) -{ - u32 int_ena; - - int_ena =3D esp32_uart_read(port, UART_INT_ENA_REG); - int_ena &=3D ~UART_RXFIFO_FULL_INT; - esp32_uart_write(port, UART_INT_ENA_REG, int_ena); -} - -static int esp32_uart_startup(struct uart_port *port) -{ - int ret =3D 0; - unsigned long flags; - struct esp32_port *sport =3D container_of(port, struct esp32_port, port); - - ret =3D clk_prepare_enable(sport->clk); - if (ret) - return ret; - - ret =3D request_irq(port->irq, esp32_uart_int, 0, DRIVER_NAME, port); - if (ret) { - clk_disable_unprepare(sport->clk); - return ret; - } - - spin_lock_irqsave(&port->lock, flags); - if (port_variant(port)->has_clkconf) - esp32_uart_write(port, ESP32S3_UART_CLK_CONF_REG, - ESP32S3_UART_CLK_CONF_DEFAULT); - esp32_uart_write(port, UART_CONF1_REG, - (1 << UART_RXFIFO_FULL_THRHD_SHIFT) | - (1 << port_variant(port)->txfifo_empty_thrhd_shift)); - esp32_uart_write(port, UART_INT_CLR_REG, UART_RXFIFO_FULL_INT | UART_BRK_= DET_INT); - esp32_uart_write(port, UART_INT_ENA_REG, UART_RXFIFO_FULL_INT | UART_BRK_= DET_INT); - spin_unlock_irqrestore(&port->lock, flags); - - return ret; -} - -static void esp32_uart_shutdown(struct uart_port *port) -{ - struct esp32_port *sport =3D container_of(port, struct esp32_port, port); - - esp32_uart_write(port, UART_INT_ENA_REG, 0); - free_irq(port->irq, port); - clk_disable_unprepare(sport->clk); -} - -static bool esp32_uart_set_baud(struct uart_port *port, u32 baud) -{ - u32 sclk =3D port->uartclk; - u32 div =3D sclk / baud; - - if (port_variant(port)->has_clkconf) { - u32 sclk_div =3D div / port_variant(port)->clkdiv_mask; - - if (div > port_variant(port)->clkdiv_mask) { - sclk /=3D (sclk_div + 1); - div =3D sclk / baud; - } - esp32_uart_write(port, ESP32S3_UART_CLK_CONF_REG, - FIELD_PREP(ESP32S3_UART_SCLK_DIV_NUM, sclk_div) | - ESP32S3_UART_CLK_CONF_DEFAULT); - } - - if (div <=3D port_variant(port)->clkdiv_mask) { - u32 frag =3D (sclk * 16) / baud - div * 16; - - esp32_uart_write(port, UART_CLKDIV_REG, - div | FIELD_PREP(UART_CLKDIV_FRAG, frag)); - return true; - } - - return false; -} - -static void esp32_uart_set_termios(struct uart_port *port, - struct ktermios *termios, - const struct ktermios *old) -{ - unsigned long flags; - u32 conf0, conf1; - u32 baud; - const u32 rx_flow_en =3D port_variant(port)->rx_flow_en; - u32 max_div =3D port_variant(port)->clkdiv_mask; - - termios->c_cflag &=3D ~CMSPAR; - - if (port_variant(port)->has_clkconf) - max_div *=3D FIELD_MAX(ESP32S3_UART_SCLK_DIV_NUM); - - baud =3D uart_get_baud_rate(port, termios, old, - port->uartclk / max_div, - port->uartclk / 16); - - spin_lock_irqsave(&port->lock, flags); - - conf0 =3D esp32_uart_read(port, UART_CONF0_REG); - conf0 &=3D ~(UART_PARITY_EN | UART_PARITY | UART_BIT_NUM | UART_STOP_BIT_= NUM); - - conf1 =3D esp32_uart_read(port, UART_CONF1_REG); - conf1 &=3D ~rx_flow_en; - - if (termios->c_cflag & PARENB) { - conf0 |=3D UART_PARITY_EN; - if (termios->c_cflag & PARODD) - conf0 |=3D UART_PARITY; - } - - switch (termios->c_cflag & CSIZE) { - case CS5: - conf0 |=3D FIELD_PREP(UART_BIT_NUM, UART_BIT_NUM_5); - break; - case CS6: - conf0 |=3D FIELD_PREP(UART_BIT_NUM, UART_BIT_NUM_6); - break; - case CS7: - conf0 |=3D FIELD_PREP(UART_BIT_NUM, UART_BIT_NUM_7); - break; - case CS8: - conf0 |=3D FIELD_PREP(UART_BIT_NUM, UART_BIT_NUM_8); - break; - } - - if (termios->c_cflag & CSTOPB) - conf0 |=3D FIELD_PREP(UART_STOP_BIT_NUM, UART_STOP_BIT_NUM_2); - else - conf0 |=3D FIELD_PREP(UART_STOP_BIT_NUM, UART_STOP_BIT_NUM_1); - - if (termios->c_cflag & CRTSCTS) - conf1 |=3D rx_flow_en; - - esp32_uart_write(port, UART_CONF0_REG, conf0); - esp32_uart_write(port, UART_CONF1_REG, conf1); - - if (baud) { - esp32_uart_set_baud(port, baud); - uart_update_timeout(port, termios->c_cflag, baud); - } else { - if (esp32_uart_set_baud(port, 115200)) { - baud =3D 115200; - tty_termios_encode_baud_rate(termios, baud, baud); - uart_update_timeout(port, termios->c_cflag, baud); - } else { - dev_warn(port->dev, - "unable to set speed to %d baud or the default 115200\n", - baud); - } - } - spin_unlock_irqrestore(&port->lock, flags); -} - -static const char *esp32_uart_type(struct uart_port *port) -{ - return port_variant(port)->type; -} - -/* configure/auto-configure the port */ -static void esp32_uart_config_port(struct uart_port *port, int flags) -{ - if (flags & UART_CONFIG_TYPE) - port->type =3D PORT_GENERIC; -} - -#ifdef CONFIG_CONSOLE_POLL -static int esp32_uart_poll_init(struct uart_port *port) -{ - struct esp32_port *sport =3D container_of(port, struct esp32_port, port); - - return clk_prepare_enable(sport->clk); -} - -static void esp32_uart_poll_put_char(struct uart_port *port, unsigned char= c) -{ - esp32_uart_put_char_sync(port, c); -} - -static int esp32_uart_poll_get_char(struct uart_port *port) -{ - if (esp32_uart_rx_fifo_cnt(port)) - return esp32_uart_read(port, UART_FIFO_REG); - else - return NO_POLL_CHAR; - -} -#endif - -static const struct uart_ops esp32_uart_pops =3D { - .tx_empty =3D esp32_uart_tx_empty, - .set_mctrl =3D esp32_uart_set_mctrl, - .get_mctrl =3D esp32_uart_get_mctrl, - .stop_tx =3D esp32_uart_stop_tx, - .start_tx =3D esp32_uart_start_tx, - .stop_rx =3D esp32_uart_stop_rx, - .startup =3D esp32_uart_startup, - .shutdown =3D esp32_uart_shutdown, - .set_termios =3D esp32_uart_set_termios, - .type =3D esp32_uart_type, - .config_port =3D esp32_uart_config_port, -#ifdef CONFIG_CONSOLE_POLL - .poll_init =3D esp32_uart_poll_init, - .poll_put_char =3D esp32_uart_poll_put_char, - .poll_get_char =3D esp32_uart_poll_get_char, -#endif -}; - -static void esp32_uart_console_putchar(struct uart_port *port, u8 c) -{ - esp32_uart_put_char_sync(port, c); -} - -static void esp32_uart_string_write(struct uart_port *port, const char *s, - unsigned int count) -{ - uart_console_write(port, s, count, esp32_uart_console_putchar); -} - -static void -esp32_uart_console_write(struct console *co, const char *s, unsigned int c= ount) -{ - struct esp32_port *sport =3D esp32_uart_ports[co->index]; - struct uart_port *port =3D &sport->port; - unsigned long flags; - bool locked =3D true; - - if (port->sysrq) - locked =3D false; - else if (oops_in_progress) - locked =3D spin_trylock_irqsave(&port->lock, flags); - else - spin_lock_irqsave(&port->lock, flags); - - esp32_uart_string_write(port, s, count); - - if (locked) - spin_unlock_irqrestore(&port->lock, flags); -} - -static int __init esp32_uart_console_setup(struct console *co, char *optio= ns) -{ - struct esp32_port *sport; - int baud =3D 115200; - int bits =3D 8; - int parity =3D 'n'; - int flow =3D 'n'; - int ret; - - /* - * check whether an invalid uart number has been specified, and - * if so, search for the first available port that does have - * console support. - */ - if (co->index =3D=3D -1 || co->index >=3D ARRAY_SIZE(esp32_uart_ports)) - co->index =3D 0; - - sport =3D esp32_uart_ports[co->index]; - if (!sport) - return -ENODEV; - - ret =3D clk_prepare_enable(sport->clk); - if (ret) - return ret; - - if (options) - uart_parse_options(options, &baud, &parity, &bits, &flow); - - return uart_set_options(&sport->port, co, baud, parity, bits, flow); -} - -static int esp32_uart_console_exit(struct console *co) -{ - struct esp32_port *sport =3D esp32_uart_ports[co->index]; - - clk_disable_unprepare(sport->clk); - return 0; -} - -static struct uart_driver esp32_uart_reg; -static struct console esp32_uart_console =3D { - .name =3D DEV_NAME, - .write =3D esp32_uart_console_write, - .device =3D uart_console_device, - .setup =3D esp32_uart_console_setup, - .exit =3D esp32_uart_console_exit, - .flags =3D CON_PRINTBUFFER, - .index =3D -1, - .data =3D &esp32_uart_reg, -}; - -static void esp32_uart_earlycon_putchar(struct uart_port *port, u8 c) -{ - esp32_uart_put_char_sync(port, c); -} - -static void esp32_uart_earlycon_write(struct console *con, const char *s, - unsigned int n) -{ - struct earlycon_device *dev =3D con->data; - - uart_console_write(&dev->port, s, n, esp32_uart_earlycon_putchar); -} - -#ifdef CONFIG_CONSOLE_POLL -static int esp32_uart_earlycon_read(struct console *con, char *s, unsigned= int n) -{ - struct earlycon_device *dev =3D con->data; - unsigned int num_read =3D 0; - - while (num_read < n) { - int c =3D esp32_uart_poll_get_char(&dev->port); - - if (c =3D=3D NO_POLL_CHAR) - break; - s[num_read++] =3D c; - } - return num_read; -} -#endif - -static int __init esp32xx_uart_early_console_setup(struct earlycon_device = *device, - const char *options) -{ - if (!device->port.membase) - return -ENODEV; - - device->con->write =3D esp32_uart_earlycon_write; -#ifdef CONFIG_CONSOLE_POLL - device->con->read =3D esp32_uart_earlycon_read; -#endif - if (device->port.uartclk !=3D BASE_BAUD * 16) - esp32_uart_set_baud(&device->port, device->baud); - - return 0; -} - -static int __init esp32_uart_early_console_setup(struct earlycon_device *d= evice, - const char *options) -{ - device->port.private_data =3D (void *)&esp32_variant; - - return esp32xx_uart_early_console_setup(device, options); -} - -OF_EARLYCON_DECLARE(esp32uart, "esp,esp32-uart", - esp32_uart_early_console_setup); - -static int __init esp32s3_uart_early_console_setup(struct earlycon_device = *device, - const char *options) -{ - device->port.private_data =3D (void *)&esp32s3_variant; - - return esp32xx_uart_early_console_setup(device, options); -} - -OF_EARLYCON_DECLARE(esp32s3uart, "esp,esp32s3-uart", - esp32s3_uart_early_console_setup); - -static struct uart_driver esp32_uart_reg =3D { - .owner =3D THIS_MODULE, - .driver_name =3D DRIVER_NAME, - .dev_name =3D DEV_NAME, - .nr =3D ARRAY_SIZE(esp32_uart_ports), - .cons =3D &esp32_uart_console, -}; - -static int esp32_uart_probe(struct platform_device *pdev) -{ - struct device_node *np =3D pdev->dev.of_node; - struct uart_port *port; - struct esp32_port *sport; - struct resource *res; - int ret; - - sport =3D devm_kzalloc(&pdev->dev, sizeof(*sport), GFP_KERNEL); - if (!sport) - return -ENOMEM; - - port =3D &sport->port; - - ret =3D of_alias_get_id(np, "serial"); - if (ret < 0) { - dev_err(&pdev->dev, "failed to get alias id, errno %d\n", ret); - return ret; - } - if (ret >=3D UART_NR) { - dev_err(&pdev->dev, "driver limited to %d serial ports\n", UART_NR); - return -ENOMEM; - } - - port->line =3D ret; - - res =3D platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) - return -ENODEV; - - port->mapbase =3D res->start; - port->membase =3D devm_ioremap_resource(&pdev->dev, res); - if (IS_ERR(port->membase)) - return PTR_ERR(port->membase); - - sport->clk =3D devm_clk_get(&pdev->dev, NULL); - if (IS_ERR(sport->clk)) - return PTR_ERR(sport->clk); - - port->uartclk =3D clk_get_rate(sport->clk); - port->dev =3D &pdev->dev; - port->type =3D PORT_GENERIC; - port->iotype =3D UPIO_MEM; - port->irq =3D platform_get_irq(pdev, 0); - port->ops =3D &esp32_uart_pops; - port->flags =3D UPF_BOOT_AUTOCONF; - port->has_sysrq =3D 1; - port->fifosize =3D ESP32_UART_TX_FIFO_SIZE; - port->private_data =3D (void *)device_get_match_data(&pdev->dev); - - esp32_uart_ports[port->line] =3D sport; - - platform_set_drvdata(pdev, port); - - return uart_add_one_port(&esp32_uart_reg, port); -} - -static void esp32_uart_remove(struct platform_device *pdev) -{ - struct uart_port *port =3D platform_get_drvdata(pdev); - - uart_remove_one_port(&esp32_uart_reg, port); -} - - -static struct platform_driver esp32_uart_driver =3D { - .probe =3D esp32_uart_probe, - .remove =3D esp32_uart_remove, - .driver =3D { - .name =3D DRIVER_NAME, - .of_match_table =3D esp32_uart_dt_ids, - }, -}; - -static int __init esp32_uart_init(void) -{ - int ret; - - ret =3D uart_register_driver(&esp32_uart_reg); - if (ret) - return ret; - - ret =3D platform_driver_register(&esp32_uart_driver); - if (ret) - uart_unregister_driver(&esp32_uart_reg); - - return ret; -} - -static void __exit esp32_uart_exit(void) -{ - platform_driver_unregister(&esp32_uart_driver); - uart_unregister_driver(&esp32_uart_reg); -} - -module_init(esp32_uart_init); -module_exit(esp32_uart_exit); - -MODULE_AUTHOR("Max Filippov "); -MODULE_DESCRIPTION("Espressif ESP32 UART support"); -MODULE_LICENSE("GPL"); --=20 2.51.2