/*
 * Copyright (c) 2020 Intel Corporation
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <logging/log.h>
LOG_MODULE_REGISTER(uart_mux, CONFIG_UART_MUX_LOG_LEVEL);

#include <sys/__assert.h>
#include <kernel.h>
#include <init.h>
#include <syscall_handler.h>
#include <device.h>
#include <drivers/uart.h>
#include <drivers/console/uart_mux.h>
#include <sys/ring_buffer.h>
#include <sys/util.h>
#include <sys/atomic.h>

#include "gsm_mux.h"

#if CONFIG_UART_MUX_DEVICE_COUNT == 0
#error "CONFIG_UART_MUX_DEVICE_COUNT tells number of DLCIs to create " \
	"and must be >0"
#endif

#define UART_MUX_WORKQ_PRIORITY CONFIG_UART_MUX_RX_PRIORITY
#define UART_MUX_WORKQ_STACK_SIZE CONFIG_UART_MUX_RX_STACK_SIZE

/* All the RX/TX data is passed via own workqueue. This is done like this
 * as the GSM modem uses global workqueue which causes difficulties if we do
 * the same here. This workqueue is shared between all the DLCI channels.
 */
K_KERNEL_STACK_DEFINE(uart_mux_stack, UART_MUX_WORKQ_STACK_SIZE);
static struct k_work_q uart_mux_workq;

/* The UART mux contains information about the real UART. It will synchronize
 * the access to the real UART and pass data between it and GSM muxing API.
 * Usually there is only one instance of these in the system, if we have only
 * one UART connected to modem device.
 */
struct uart_mux {
	/* The real UART device that is shared between muxed UARTs */
	const struct device *uart;

	/* GSM mux related to this UART */
	struct gsm_mux *mux;

	/* Received data is routed from ISR to MUX API via ring buffer */
	struct ring_buf *rx_ringbuf;

	/* RX worker that passes data from RX ISR to GSM mux API */
	struct k_work rx_work;

	/* Mutex for accessing the real UART */
	struct k_mutex lock;

	/* Flag that tells whether this instance is initialized or not */
	atomic_t init_done;

	/* Temporary buffer when reading data in ISR */
	uint8_t rx_buf[CONFIG_UART_MUX_TEMP_BUF_SIZE];
};

#define DEFINE_UART_MUX(x, _)						\
	RING_BUF_DECLARE(uart_rx_ringbuf_##x,				\
			 CONFIG_UART_MUX_RINGBUF_SIZE);			\
	static struct uart_mux uart_mux_##x __used			\
		__attribute__((__section__(".uart_mux.data"))) = {	\
			.rx_ringbuf = &uart_rx_ringbuf_##x,		\
	}

LISTIFY(CONFIG_UART_MUX_REAL_DEVICE_COUNT, DEFINE_UART_MUX, (;), _);

extern struct uart_mux __uart_mux_start[];
extern struct uart_mux __uart_mux_end[];

/* UART Mux Driver Status Codes */
enum uart_mux_status_code {
	UART_MUX_UNKNOWN,      /* Initial connection status   */
	UART_MUX_CONFIGURED,   /* UART mux configuration done */
	UART_MUX_CONNECTED,    /* UART mux connected          */
	UART_MUX_DISCONNECTED, /* UART mux connection lost    */
};

struct uart_mux_config {
};

struct uart_mux_dev_data {
	sys_snode_t node;

	/* Configuration data */
	struct uart_mux_config cfg;

	/* This UART mux device */
	const struct device *dev;

	/* The UART device where we are running on top of */
	struct uart_mux *real_uart;

	/* TX worker that will mux the transmitted data */
	struct k_work tx_work;

	/* ISR function callback worker */
	struct k_work cb_work;

	/* ISR function callback */
	uart_irq_callback_user_data_t cb;
	void *cb_user_data;

	/* Attach callback */
	uart_mux_attach_cb_t attach_cb;
	void *attach_user_data;

	/* TX data from application is handled via ring buffer */
	struct ring_buf *tx_ringbuf;

	/* Received data is routed from RX worker to application via ring
	 * buffer.
	 */
	struct ring_buf *rx_ringbuf;

	/* Muxing status */
	enum uart_mux_status_code status;

	/* DLCI (muxing virtual channel) linked to this muxed UART */
	struct gsm_dlci *dlci;

	/* Status (enabled / disabled) for RX and TX */
	bool rx_enabled : 1;
	bool tx_enabled : 1;
	bool rx_ready : 1;
	bool tx_ready : 1;
	bool in_use : 1;
};

struct uart_mux_cfg_data {
};

static sys_slist_t uart_mux_data_devlist;

static void uart_mux_cb_work(struct k_work *work)
{
	struct uart_mux_dev_data *dev_data =
		CONTAINER_OF(work, struct uart_mux_dev_data, cb_work);

	dev_data->cb(dev_data->dev, dev_data->cb_user_data);
}

static int uart_mux_consume_ringbuf(struct uart_mux *uart_mux)
{
	uint8_t *data;
	size_t len;
	int ret;

	len = ring_buf_get_claim(uart_mux->rx_ringbuf, &data,
				 CONFIG_UART_MUX_RINGBUF_SIZE);
	if (len == 0) {
		LOG_DBG("Ringbuf %p is empty!", uart_mux->rx_ringbuf);
		return 0;
	}

	/* We have now received muxed data. Push that through GSM mux API which
	 * will parse it and call proper functions to get the data to the user.
	 */

	if (IS_ENABLED(CONFIG_UART_MUX_VERBOSE_DEBUG)) {
		char tmp[sizeof("RECV muxed ") + 10];

		snprintk(tmp, sizeof(tmp), "RECV muxed %s",
			 uart_mux->uart->name);
		LOG_HEXDUMP_DBG(data, len, log_strdup(tmp));
	}

	gsm_mux_recv_buf(uart_mux->mux, data, len);

	ret = ring_buf_get_finish(uart_mux->rx_ringbuf, len);
	if (ret < 0) {
		LOG_DBG("Cannot flush ring buffer (%d)", ret);
	}

	return -EAGAIN;
}

static void uart_mux_rx_work(struct k_work *work)
{
	struct uart_mux *uart_mux =
		CONTAINER_OF(work, struct uart_mux, rx_work);;
	int ret;

	do {
		ret = uart_mux_consume_ringbuf(uart_mux);
	} while (ret == -EAGAIN);
}

static void uart_mux_tx_work(struct k_work *work)
{
	struct uart_mux_dev_data *dev_data =
		CONTAINER_OF(work, struct uart_mux_dev_data, tx_work);
	uint8_t *data;
	size_t len;

	len = ring_buf_get_claim(dev_data->tx_ringbuf, &data,
				 CONFIG_UART_MUX_RINGBUF_SIZE);
	if (!len) {
		LOG_DBG("Ringbuf %p empty!", dev_data->tx_ringbuf);
		return;
	}

	LOG_DBG("Got %ld bytes from ringbuffer send to uart %p", (unsigned long)len,
		dev_data->dev);

	if (IS_ENABLED(CONFIG_UART_MUX_VERBOSE_DEBUG)) {
		char tmp[sizeof("SEND _x") +
			 sizeof(CONFIG_UART_MUX_DEVICE_NAME)];

		snprintk(tmp, sizeof(tmp), "SEND %s",
			 dev_data->dev->name);
		LOG_HEXDUMP_DBG(data, len, log_strdup(tmp));
	}

	(void)gsm_dlci_send(dev_data->dlci, data, len);

	ring_buf_get_finish(dev_data->tx_ringbuf, len);
}

static int uart_mux_init(const struct device *dev)
{
	struct uart_mux_dev_data *dev_data = dev->data;

	gsm_mux_init();

	dev_data->dev = dev;
	dev_data->real_uart = NULL; /* will be set when user attach to it */

	sys_slist_find_and_remove(&uart_mux_data_devlist, &dev_data->node);
	sys_slist_prepend(&uart_mux_data_devlist, &dev_data->node);

	k_work_init(&dev_data->tx_work, uart_mux_tx_work);
	k_work_init(&dev_data->cb_work, uart_mux_cb_work);

	LOG_DBG("Device %s dev %p dev_data %p cfg %p created",
		dev->name, dev, dev_data, dev->config);

	return 0;
}

/* This IRQ handler is shared between muxing UARTs. After we have received
 * data from it in uart_mux_rx_work(), we push the data to GSM mux API which
 * will call proper callbacks to pass data to correct recipient.
 */
static void uart_mux_isr(const struct device *uart, void *user_data)
{
	struct uart_mux *real_uart = user_data;
	int rx = 0;
	size_t wrote = 0;

	/* Read all data off UART, and send to RX worker for unmuxing */
	while (uart_irq_update(uart) &&
	       uart_irq_rx_ready(uart)) {
		rx = uart_fifo_read(uart, real_uart->rx_buf,
				    sizeof(real_uart->rx_buf));
		if (rx <= 0) {
			continue;
		}

		wrote = ring_buf_put(real_uart->rx_ringbuf,
				     real_uart->rx_buf, rx);
		if (wrote < rx) {
			LOG_ERR("Ring buffer full, drop %ld bytes", (long)(rx - wrote));
		}

		k_work_submit_to_queue(&uart_mux_workq, &real_uart->rx_work);
	}
}

static void uart_mux_flush_isr(const struct device *dev)
{
	uint8_t c;

	while (uart_fifo_read(dev, &c, 1) > 0) {
		continue;
	}
}

void uart_mux_disable(const struct device *dev)
{
	struct uart_mux_dev_data *dev_data = dev->data;
	const struct device *uart = dev_data->real_uart->uart;

	uart_irq_rx_disable(uart);
	uart_irq_tx_disable(uart);
	uart_mux_flush_isr(uart);

	gsm_mux_detach(dev_data->real_uart->mux);
}

void uart_mux_enable(const struct device *dev)
{
	struct uart_mux_dev_data *dev_data = dev->data;
	struct uart_mux *real_uart = dev_data->real_uart;

	LOG_DBG("Claiming uart for uart_mux");

	uart_irq_rx_disable(real_uart->uart);
	uart_irq_tx_disable(real_uart->uart);
	uart_mux_flush_isr(real_uart->uart);
	uart_irq_callback_user_data_set(
		real_uart->uart, uart_mux_isr,
		real_uart);

	uart_irq_rx_enable(real_uart->uart);
}

static void dlci_created_cb(struct gsm_dlci *dlci, bool connected,
			    void *user_data)
{
	struct uart_mux_dev_data *dev_data = user_data;

	if (connected) {
		dev_data->status = UART_MUX_CONNECTED;
	} else {
		dev_data->status = UART_MUX_DISCONNECTED;
	}

	LOG_DBG("%s %s", dev_data->dev->name,
		dev_data->status == UART_MUX_CONNECTED ? "connected" :
							 "disconnected");

	if (dev_data->attach_cb) {
		dev_data->attach_cb(dev_data->dev,
				    dlci ? gsm_dlci_id(dlci) : -1,
				    connected,
				    dev_data->attach_user_data);
	}
}

static int init_real_uart(const struct device *mux, const struct device *uart,
			  struct uart_mux **mux_uart)
{
	bool found = false;
	struct uart_mux *real_uart;

	for (real_uart = __uart_mux_start; real_uart != __uart_mux_end;
	     real_uart++) {
		if (real_uart->uart == uart) {
			found = true;
			break;
		}
	}

	if (found == false) {
		for (real_uart = __uart_mux_start; real_uart != __uart_mux_end;
		     real_uart++) {
			if (real_uart->uart == NULL) {
				real_uart->uart = uart;
				found = true;
				break;
			}
		}

		if (found == false) {
			return -ENOENT;
		}
	}

	/* Init the real UART only once */
	if (atomic_cas(&real_uart->init_done, false, true)) {
		real_uart->mux = gsm_mux_create(mux);

		LOG_DBG("Initializing UART %s and GSM mux %p",
			real_uart->uart->name, (void *)real_uart->mux);

		if (!real_uart->mux) {
			real_uart->uart = NULL;
			atomic_clear(&real_uart->init_done);
			return -ENOMEM;
		}

		k_work_init(&real_uart->rx_work, uart_mux_rx_work);
		k_mutex_init(&real_uart->lock);

		uart_irq_rx_disable(real_uart->uart);
		uart_irq_tx_disable(real_uart->uart);
		uart_mux_flush_isr(real_uart->uart);
		uart_irq_callback_user_data_set(
			real_uart->uart, uart_mux_isr,
			real_uart);

		uart_irq_rx_enable(real_uart->uart);
	}

	__ASSERT(real_uart->uart, "Real UART not set");

	*mux_uart = real_uart;

	return 0;
}

/* This will bind the physical (real) UART to this muxed UART */
static int attach(const struct device *mux_uart, const struct device *uart,
		  int dlci_address, uart_mux_attach_cb_t cb,
		  void *user_data)
{
	sys_snode_t *sn, *sns;

	if (mux_uart == NULL || uart == NULL) {
		return -EINVAL;
	}

	LOG_DBG("Attach DLCI %d (%s) to %s", dlci_address,
		mux_uart->name, uart->name);

	SYS_SLIST_FOR_EACH_NODE_SAFE(&uart_mux_data_devlist, sn, sns) {
		struct uart_mux_dev_data *dev_data =
			CONTAINER_OF(sn, struct uart_mux_dev_data, node);

		if (dev_data->dev == mux_uart) {
			struct uart_mux *real_uart;
			int ret;

			ret = init_real_uart(mux_uart, uart, &real_uart);
			if (ret < 0) {
				return ret;
			}

			dev_data->real_uart = real_uart;
			dev_data->tx_ready = true;
			dev_data->tx_enabled = true;
			dev_data->rx_enabled = true;
			dev_data->attach_cb = cb;
			dev_data->attach_user_data = user_data;
			dev_data->status = UART_MUX_CONFIGURED;

			ret = gsm_dlci_create(real_uart->mux,
					      mux_uart,
					      dlci_address,
					      dlci_created_cb,
					      dev_data,
					      &dev_data->dlci);
			if (ret < 0) {
				LOG_DBG("Cannot create DLCI %d (%d)",
					dlci_address, ret);
				return ret;
			}

			return 0;
		}
	}

	return -ENOENT;
}

static int uart_mux_poll_in(const struct device *dev, unsigned char *p_char)
{
	ARG_UNUSED(dev);
	ARG_UNUSED(p_char);

	return -ENOTSUP;
}

static void uart_mux_poll_out(const struct device *dev,
			      unsigned char out_char)
{
	struct uart_mux_dev_data *dev_data = dev->data;

	if (dev_data->dev == NULL) {
		return;
	}

	(void)gsm_dlci_send(dev_data->dlci, &out_char, 1);
}

static int uart_mux_err_check(const struct device *dev)
{
	ARG_UNUSED(dev);

	return -ENOTSUP;
}

static int uart_mux_configure(const struct device *dev,
			      const struct uart_config *cfg)
{
	ARG_UNUSED(dev);
	ARG_UNUSED(cfg);

	return -ENOTSUP;
}

static int uart_mux_config_get(const struct device *dev,
			       struct uart_config *cfg)
{
	ARG_UNUSED(dev);
	ARG_UNUSED(cfg);

	return -ENOTSUP;
}

static int uart_mux_fifo_fill(const struct device *dev,
			      const uint8_t *tx_data, int len)
{
	struct uart_mux_dev_data *dev_data;
	size_t wrote;

	if (dev == NULL) {
		return -EINVAL;
	}

	dev_data = dev->data;
	if (dev_data->dev == NULL) {
		return -ENOENT;
	}

	/* If we're not in ISR context, do the xfer synchronously. This
	 * effectively let's applications use this implementation of fifo_fill
	 * as a multi-byte poll_out which prevents each byte getting wrapped by
	 * mux headers.
	 */
	if (!k_is_in_isr() && dev_data->dlci) {
		return gsm_dlci_send(dev_data->dlci, tx_data, len);
	}

	LOG_DBG("dev_data %p len %d tx_ringbuf space %u",
		dev_data, len, ring_buf_space_get(dev_data->tx_ringbuf));

	if (dev_data->status != UART_MUX_CONNECTED) {
		LOG_WRN("UART mux not connected, drop %d bytes", len);
		return 0;
	}

	dev_data->tx_ready = false;

	wrote = ring_buf_put(dev_data->tx_ringbuf, tx_data, len);
	if (wrote < len) {
		LOG_WRN("Ring buffer full, drop %ld bytes", (long)(len - wrote));
	}

	k_work_submit_to_queue(&uart_mux_workq, &dev_data->tx_work);

	return wrote;
}

static int uart_mux_fifo_read(const struct device *dev, uint8_t *rx_data,
			      const int size)
{
	struct uart_mux_dev_data *dev_data;
	uint32_t len;

	if (dev == NULL) {
		return -EINVAL;
	}

	dev_data = dev->data;
	if (dev_data->dev == NULL) {
		return -ENOENT;
	}

	LOG_DBG("%s size %d rx_ringbuf space %u",
		dev->name, size,
		ring_buf_space_get(dev_data->rx_ringbuf));

	len = ring_buf_get(dev_data->rx_ringbuf, rx_data, size);

	if (ring_buf_is_empty(dev_data->rx_ringbuf)) {
		dev_data->rx_ready = false;
	}

	return len;
}

static void uart_mux_irq_tx_enable(const struct device *dev)
{
	struct uart_mux_dev_data *dev_data = dev->data;

	if (dev_data == NULL || dev_data->dev == NULL) {
		return;
	}

	dev_data->tx_enabled = true;

	if (dev_data->cb && dev_data->tx_ready) {
		k_work_submit_to_queue(&uart_mux_workq, &dev_data->cb_work);
	}
}

static void uart_mux_irq_tx_disable(const struct device *dev)
{
	struct uart_mux_dev_data *dev_data = dev->data;

	if (dev_data == NULL || dev_data->dev == NULL) {
		return;
	}

	dev_data->tx_enabled = false;
}

static int uart_mux_irq_tx_ready(const struct device *dev)
{
	struct uart_mux_dev_data *dev_data = dev->data;

	if (dev_data == NULL) {
		return -EINVAL;
	}

	if (dev_data->dev == NULL) {
		return -ENOENT;
	}

	return dev_data->tx_ready;
}

static void uart_mux_irq_rx_enable(const struct device *dev)
{
	struct uart_mux_dev_data *dev_data = dev->data;

	if (dev_data == NULL || dev_data->dev == NULL) {
		return;
	}

	dev_data->rx_enabled = true;

	if (dev_data->cb && dev_data->rx_ready) {
		k_work_submit_to_queue(&uart_mux_workq, &dev_data->cb_work);
	}
}

static void uart_mux_irq_rx_disable(const struct device *dev)
{
	struct uart_mux_dev_data *dev_data = dev->data;

	if (dev_data == NULL || dev_data->dev == NULL) {
		return;
	}

	dev_data->rx_enabled = false;
}

static int uart_mux_irq_tx_complete(const struct device *dev)
{
	ARG_UNUSED(dev);

	return -ENOTSUP;
}

static int uart_mux_irq_rx_ready(const struct device *dev)
{
	struct uart_mux_dev_data *dev_data = dev->data;

	if (dev_data == NULL) {
		return -EINVAL;
	}

	if (dev_data->dev == NULL) {
		return -ENOENT;
	}

	return dev_data->rx_ready;
}

static void uart_mux_irq_err_enable(const struct device *dev)
{
	ARG_UNUSED(dev);
}

static void uart_mux_irq_err_disable(const struct device *dev)
{
	ARG_UNUSED(dev);
}

static int uart_mux_irq_is_pending(const struct device *dev)
{
	struct uart_mux_dev_data *dev_data = dev->data;

	if (dev_data == NULL || dev_data->dev == NULL) {
		return 0;
	}

	if (dev_data->tx_ready && dev_data->tx_enabled) {
		return 1;
	}

	if (dev_data->rx_ready && dev_data->rx_enabled) {
		return 1;
	}

	return 0;
}

static int uart_mux_irq_update(const struct device *dev)
{
	ARG_UNUSED(dev);

	return 1;
}

static void uart_mux_irq_callback_set(const struct device *dev,
				      uart_irq_callback_user_data_t cb,
				      void *user_data)
{
	struct uart_mux_dev_data *dev_data = dev->data;

	if (dev_data == NULL) {
		return;
	}

	dev_data->cb = cb;
	dev_data->cb_user_data = user_data;
}

static struct uart_mux_driver_api uart_mux_driver_api = {
	.uart_api.poll_in = uart_mux_poll_in,
	.uart_api.poll_out = uart_mux_poll_out,
	.uart_api.err_check = uart_mux_err_check,
	.uart_api.configure = uart_mux_configure,
	.uart_api.config_get = uart_mux_config_get,
	.uart_api.fifo_fill = uart_mux_fifo_fill,
	.uart_api.fifo_read = uart_mux_fifo_read,
	.uart_api.irq_tx_enable = uart_mux_irq_tx_enable,
	.uart_api.irq_tx_disable = uart_mux_irq_tx_disable,
	.uart_api.irq_tx_ready = uart_mux_irq_tx_ready,
	.uart_api.irq_rx_enable = uart_mux_irq_rx_enable,
	.uart_api.irq_rx_disable = uart_mux_irq_rx_disable,
	.uart_api.irq_tx_complete = uart_mux_irq_tx_complete,
	.uart_api.irq_rx_ready = uart_mux_irq_rx_ready,
	.uart_api.irq_err_enable = uart_mux_irq_err_enable,
	.uart_api.irq_err_disable = uart_mux_irq_err_disable,
	.uart_api.irq_is_pending = uart_mux_irq_is_pending,
	.uart_api.irq_update = uart_mux_irq_update,
	.uart_api.irq_callback_set = uart_mux_irq_callback_set,

	.attach = attach,
};

const struct device *uart_mux_alloc(void)
{
	sys_snode_t *sn, *sns;

	SYS_SLIST_FOR_EACH_NODE_SAFE(&uart_mux_data_devlist, sn, sns) {
		struct uart_mux_dev_data *dev_data =
			CONTAINER_OF(sn, struct uart_mux_dev_data, node);

		if (dev_data->in_use) {
			continue;
		}

		dev_data->in_use = true;

		return dev_data->dev;
	}

	return NULL;
}

#ifdef CONFIG_USERSPACE
static inline const struct device *z_vrfy_uart_mux_find(int dlci_address)
{
	return z_impl_uart_mux_find(dlci_address);
}
#include <syscalls/uart_mux_find_mrsh.c>
#endif /* CONFIG_USERSPACE */

const struct device *z_impl_uart_mux_find(int dlci_address)
{
	sys_snode_t *sn, *sns;

	SYS_SLIST_FOR_EACH_NODE_SAFE(&uart_mux_data_devlist, sn, sns) {
		struct uart_mux_dev_data *dev_data =
			CONTAINER_OF(sn, struct uart_mux_dev_data, node);

		if (!dev_data->in_use) {
			continue;
		}

		if (dev_data->dlci == NULL) {
			continue;
		}

		if (gsm_dlci_id(dev_data->dlci) == dlci_address) {
			return dev_data->dev;
		}
	}

	return NULL;
}

int uart_mux_send(const struct device *uart, const uint8_t *buf, size_t size)
{
	struct uart_mux_dev_data *dev_data = uart->data;

	if (size == 0) {
		return 0;
	}

	if (atomic_get(&dev_data->real_uart->init_done) == false) {
		return -ENODEV;
	}

	if (IS_ENABLED(CONFIG_UART_MUX_VERBOSE_DEBUG)) {
		char tmp[sizeof("SEND muxed ") + 10];

		snprintk(tmp, sizeof(tmp), "SEND muxed %s",
			 dev_data->real_uart->uart->name);
		LOG_HEXDUMP_DBG(buf, size, log_strdup(tmp));
	}

	k_mutex_lock(&dev_data->real_uart->lock, K_FOREVER);

	do {
		uart_poll_out(dev_data->real_uart->uart, *buf++);
	} while (--size);

	k_mutex_unlock(&dev_data->real_uart->lock);

	return 0;
}

int uart_mux_recv(const struct device *mux, struct gsm_dlci *dlci,
		  uint8_t *data,
		  size_t len)
{
	struct uart_mux_dev_data *dev_data = mux->data;
	size_t wrote = 0;

	LOG_DBG("%s: dlci %p data %p len %zd", mux->name, (void *)dlci,
		data, len);

	if (IS_ENABLED(CONFIG_UART_MUX_VERBOSE_DEBUG)) {
		char tmp[sizeof("RECV _x") +
			 sizeof(CONFIG_UART_MUX_DEVICE_NAME)];

		snprintk(tmp, sizeof(tmp), "RECV %s",
			 dev_data->dev->name);
		LOG_HEXDUMP_DBG(data, len, log_strdup(tmp));
	}

	wrote = ring_buf_put(dev_data->rx_ringbuf, data, len);
	if (wrote < len) {
		LOG_ERR("Ring buffer full, drop %ld bytes", (long)(len - wrote));
	}

	dev_data->rx_ready = true;

	if (dev_data->cb && dev_data->rx_enabled) {
		k_work_submit_to_queue(&uart_mux_workq, &dev_data->cb_work);
	}

	return wrote;
}

void uart_mux_foreach(uart_mux_cb_t cb, void *user_data)
{
	sys_snode_t *sn, *sns;

	SYS_SLIST_FOR_EACH_NODE_SAFE(&uart_mux_data_devlist, sn, sns) {
		struct uart_mux_dev_data *dev_data =
			CONTAINER_OF(sn, struct uart_mux_dev_data, node);

		if (!dev_data->in_use) {
			continue;
		}

		cb(dev_data->real_uart->uart, dev_data->dev,
		   dev_data->dlci ? gsm_dlci_id(dev_data->dlci) : -1,
		   user_data);
	}
}

#define DEFINE_UART_MUX_CFG_DATA(x, _)					  \
	struct uart_mux_cfg_data uart_mux_config_##x = {		  \
	}

#define DEFINE_UART_MUX_DEV_DATA(x, _)					  \
	RING_BUF_DECLARE(tx_ringbuf_##x, CONFIG_UART_MUX_RINGBUF_SIZE);	  \
	RING_BUF_DECLARE(rx_ringbuf_##x, CONFIG_UART_MUX_RINGBUF_SIZE);	  \
	static struct uart_mux_dev_data uart_mux_dev_data_##x = {	  \
		.tx_ringbuf = &tx_ringbuf_##x,				  \
		.rx_ringbuf = &rx_ringbuf_##x,				  \
	}

#define DEFINE_UART_MUX_DEVICE(x, _)					  \
	DEVICE_DEFINE(uart_mux_##x,					  \
			    CONFIG_UART_MUX_DEVICE_NAME "_" #x,		  \
			    &uart_mux_init,				  \
			    NULL,					  \
			    &uart_mux_dev_data_##x,			  \
			    &uart_mux_config_##x,			  \
			    POST_KERNEL,				  \
			    CONFIG_CONSOLE_INIT_PRIORITY,		  \
			    &uart_mux_driver_api)

LISTIFY(CONFIG_UART_MUX_DEVICE_COUNT, DEFINE_UART_MUX_CFG_DATA, (;),  _);
LISTIFY(CONFIG_UART_MUX_DEVICE_COUNT, DEFINE_UART_MUX_DEV_DATA, (;), _);
LISTIFY(CONFIG_UART_MUX_DEVICE_COUNT, DEFINE_UART_MUX_DEVICE, (;), _);

static int init_uart_mux(const struct device *dev)
{
	ARG_UNUSED(dev);

	k_work_queue_start(&uart_mux_workq, uart_mux_stack,
			   K_KERNEL_STACK_SIZEOF(uart_mux_stack),
			   K_PRIO_COOP(UART_MUX_WORKQ_PRIORITY), NULL);
	k_thread_name_set(&uart_mux_workq.thread, "uart_mux_workq");

	return 0;
}

SYS_INIT(init_uart_mux, POST_KERNEL, CONFIG_CONSOLE_INIT_PRIORITY);
