// SPDX-License-Identifier: GPL-2.0
/* Copyright (c) 2010, 2014, 2022 The Linux Foundation. All rights reserved.  */

#include <linux/console.h>
#include <linux/cpu.h>
#include <linux/cpumask.h>
#include <linux/init.h>
#include <linux/kfifo.h>
#include <linux/moduleparam.h>
#include <linux/serial.h>
#include <linux/serial_core.h>
#include <linux/smp.h>
#include <linux/spinlock.h>

#include <asm/dcc.h>
#include <asm/processor.h>

#include "hvc_console.h"

/*
 * Disable DCC driver at runtime. Want driver enabled for GKI, but some devices
 * do not support the registers and crash when driver pokes the registers
 */
static bool enable;
module_param(enable, bool, 0444);

/* DCC Status Bits */
#define DCC_STATUS_RX		(1 << 30)
#define DCC_STATUS_TX		(1 << 29)

#define DCC_INBUF_SIZE		128
#define DCC_OUTBUF_SIZE		1024

/* Lock to serialize access to DCC fifo */
static DEFINE_SPINLOCK(dcc_lock);

static DEFINE_KFIFO(inbuf, unsigned char, DCC_INBUF_SIZE);
static DEFINE_KFIFO(outbuf, unsigned char, DCC_OUTBUF_SIZE);

static void dcc_uart_console_putchar(struct uart_port *port, unsigned char ch)
{
	while (__dcc_getstatus() & DCC_STATUS_TX)
		cpu_relax();

	__dcc_putchar(ch);
}

static void dcc_early_write(struct console *con, const char *s, unsigned n)
{
	struct earlycon_device *dev = con->data;

	uart_console_write(&dev->port, s, n, dcc_uart_console_putchar);
}

static int __init dcc_early_console_setup(struct earlycon_device *device,
					  const char *opt)
{
	device->con->write = dcc_early_write;

	return 0;
}

EARLYCON_DECLARE(dcc, dcc_early_console_setup);

static int hvc_dcc_put_chars(uint32_t vt, const char *buf, int count)
{
	int i;

	for (i = 0; i < count; i++) {
		while (__dcc_getstatus() & DCC_STATUS_TX)
			cpu_relax();

		__dcc_putchar(buf[i]);
	}

	return count;
}

static int hvc_dcc_get_chars(uint32_t vt, char *buf, int count)
{
	int i;

	for (i = 0; i < count; ++i)
		if (__dcc_getstatus() & DCC_STATUS_RX)
			buf[i] = __dcc_getchar();
		else
			break;

	return i;
}

/*
 * Check if the DCC is enabled. If CONFIG_HVC_DCC_SERIALIZE_SMP is enabled,
 * then we assume then this function will be called first on core0. That way,
 * dcc_core0_available will be true only if it's available on core0.
 */
static bool hvc_dcc_check(void)
{
	unsigned long time = jiffies + (HZ / 10);
	static bool dcc_core0_available;

	/*
	 * If we're not on core 0, but we previously confirmed that DCC is
	 * active, then just return true.
	 */
	int cpu = get_cpu();

	if (IS_ENABLED(CONFIG_HVC_DCC_SERIALIZE_SMP) && cpu && dcc_core0_available) {
		put_cpu();
		return true;
	}

	put_cpu();

	/* Write a test character to check if it is handled */
	__dcc_putchar('\n');

	while (time_is_after_jiffies(time)) {
		if (!(__dcc_getstatus() & DCC_STATUS_TX)) {
			dcc_core0_available = true;
			return true;
		}
	}

	return false;
}

/*
 * Workqueue function that writes the output FIFO to the DCC on core 0.
 */
static void dcc_put_work(struct work_struct *work)
{
	unsigned char ch;
	unsigned long irqflags;

	spin_lock_irqsave(&dcc_lock, irqflags);

	/* While there's data in the output FIFO, write it to the DCC */
	while (kfifo_get(&outbuf, &ch))
		hvc_dcc_put_chars(0, &ch, 1);

	/* While we're at it, check for any input characters */
	while (!kfifo_is_full(&inbuf)) {
		if (!hvc_dcc_get_chars(0, &ch, 1))
			break;
		kfifo_put(&inbuf, ch);
	}

	spin_unlock_irqrestore(&dcc_lock, irqflags);
}

static DECLARE_WORK(dcc_pwork, dcc_put_work);

/*
 * Workqueue function that reads characters from DCC and puts them into the
 * input FIFO.
 */
static void dcc_get_work(struct work_struct *work)
{
	unsigned char ch;
	unsigned long irqflags;

	/*
	 * Read characters from DCC and put them into the input FIFO, as
	 * long as there is room and we have characters to read.
	 */
	spin_lock_irqsave(&dcc_lock, irqflags);

	while (!kfifo_is_full(&inbuf)) {
		if (!hvc_dcc_get_chars(0, &ch, 1))
			break;
		kfifo_put(&inbuf, ch);
	}
	spin_unlock_irqrestore(&dcc_lock, irqflags);
}

static DECLARE_WORK(dcc_gwork, dcc_get_work);

/*
 * Write characters directly to the DCC if we're on core 0 and the FIFO
 * is empty, or write them to the FIFO if we're not.
 */
static int hvc_dcc0_put_chars(u32 vt, const char *buf, int count)
{
	int len;
	unsigned long irqflags;

	if (!IS_ENABLED(CONFIG_HVC_DCC_SERIALIZE_SMP))
		return hvc_dcc_put_chars(vt, buf, count);

	spin_lock_irqsave(&dcc_lock, irqflags);
	if (smp_processor_id() || (!kfifo_is_empty(&outbuf))) {
		len = kfifo_in(&outbuf, buf, count);
		spin_unlock_irqrestore(&dcc_lock, irqflags);

		/*
		 * We just push data to the output FIFO, so schedule the
		 * workqueue that will actually write that data to DCC.
		 * CPU hotplug is disabled in dcc_init so CPU0 cannot be
		 * offlined after the cpu online check.
		 */
		if (cpu_online(0))
			schedule_work_on(0, &dcc_pwork);

		return len;
	}

	/*
	 * If we're already on core 0, and the FIFO is empty, then just
	 * write the data to DCC.
	 */
	len = hvc_dcc_put_chars(vt, buf, count);
	spin_unlock_irqrestore(&dcc_lock, irqflags);

	return len;
}

/*
 * Read characters directly from the DCC if we're on core 0 and the FIFO
 * is empty, or read them from the FIFO if we're not.
 */
static int hvc_dcc0_get_chars(u32 vt, char *buf, int count)
{
	int len;
	unsigned long irqflags;

	if (!IS_ENABLED(CONFIG_HVC_DCC_SERIALIZE_SMP))
		return hvc_dcc_get_chars(vt, buf, count);

	spin_lock_irqsave(&dcc_lock, irqflags);

	if (smp_processor_id() || (!kfifo_is_empty(&inbuf))) {
		len = kfifo_out(&inbuf, buf, count);
		spin_unlock_irqrestore(&dcc_lock, irqflags);

		/*
		 * If the FIFO was empty, there may be characters in the DCC
		 * that we haven't read yet.  Schedule a workqueue to fill
		 * the input FIFO, so that the next time this function is
		 * called, we'll have data. CPU hotplug is disabled in dcc_init
		 * so CPU0 cannot be offlined after the cpu online check.
		 */
		if (!len && cpu_online(0))
			schedule_work_on(0, &dcc_gwork);

		return len;
	}

	/*
	 * If we're already on core 0, and the FIFO is empty, then just
	 * read the data from DCC.
	 */
	len = hvc_dcc_get_chars(vt, buf, count);
	spin_unlock_irqrestore(&dcc_lock, irqflags);

	return len;
}

static const struct hv_ops hvc_dcc_get_put_ops = {
	.get_chars = hvc_dcc0_get_chars,
	.put_chars = hvc_dcc0_put_chars,
};

static int __init hvc_dcc_console_init(void)
{
	int ret;

	if (!enable || !hvc_dcc_check())
		return -ENODEV;

	/* Returns -1 if error */
	ret = hvc_instantiate(0, 0, &hvc_dcc_get_put_ops);

	return ret < 0 ? -ENODEV : 0;
}
console_initcall(hvc_dcc_console_init);

static int __init hvc_dcc_init(void)
{
	struct hvc_struct *p;

	if (!enable || !hvc_dcc_check())
		return -ENODEV;

	if (IS_ENABLED(CONFIG_HVC_DCC_SERIALIZE_SMP)) {
		pr_warn("\n");
		pr_warn("********************************************************************\n");
		pr_warn("**     NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE           **\n");
		pr_warn("**                                                                **\n");
		pr_warn("**  HVC_DCC_SERIALIZE_SMP SUPPORT HAS BEEN ENABLED IN THIS KERNEL **\n");
		pr_warn("**                                                                **\n");
		pr_warn("** This means that this is a DEBUG kernel and unsafe for          **\n");
		pr_warn("** production use and has important feature like CPU hotplug      **\n");
		pr_warn("** disabled.                                                      **\n");
		pr_warn("**                                                                **\n");
		pr_warn("** If you see this message and you are not debugging the          **\n");
		pr_warn("** kernel, report this immediately to your vendor!                **\n");
		pr_warn("**                                                                **\n");
		pr_warn("**     NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE           **\n");
		pr_warn("********************************************************************\n");

		cpu_hotplug_disable();
	}

	p = hvc_alloc(0, 0, &hvc_dcc_get_put_ops, 128);

	return PTR_ERR_OR_ZERO(p);
}
device_initcall(hvc_dcc_init);
