/*
 *  drivers/s390/char/sclp_con.c
 *    SCLP line mode console driver
 *
 *  S390 version
 *    Copyright (C) 1999 IBM Deutschland Entwicklung GmbH, IBM Corporation
 *    Author(s): Martin Peschke <mpeschke@de.ibm.com>
 *		 Martin Schwidefsky <schwidefsky@de.ibm.com>
 */

#include <linux/kmod.h>
#include <linux/console.h>
#include <linux/init.h>
#include <linux/timer.h>
#include <linux/jiffies.h>
#include <linux/bootmem.h>
#include <linux/err.h>

#include "sclp.h"
#include "sclp_rw.h"
#include "sclp_tty.h"

#define SCLP_CON_PRINT_HEADER "sclp console driver: "

#define sclp_console_major 4		/* TTYAUX_MAJOR */
#define sclp_console_minor 64
#define sclp_console_name  "ttyS"

/* Lock to guard over changes to global variables */
static spinlock_t sclp_con_lock;
/* List of free pages that can be used for console output buffering */
static struct list_head sclp_con_pages;
/* List of full struct sclp_buffer structures ready for output */
static struct list_head sclp_con_outqueue;
/* Counter how many buffers are emitted (max 1) and how many */
/* are on the output queue. */
static int sclp_con_buffer_count;
/* Pointer to current console buffer */
static struct sclp_buffer *sclp_conbuf;
/* Timer for delayed output of console messages */
static struct timer_list sclp_con_timer;

/* Output format for console messages */
static unsigned short sclp_con_columns;
static unsigned short sclp_con_width_htab;

static void
sclp_conbuf_callback(struct sclp_buffer *buffer, int rc)
{
	unsigned long flags;
	void *page;

	do {
		page = sclp_unmake_buffer(buffer);
		spin_lock_irqsave(&sclp_con_lock, flags);
		/* Remove buffer from outqueue */
		list_del(&buffer->list);
		sclp_con_buffer_count--;
		list_add_tail((struct list_head *) page, &sclp_con_pages);
		/* Check if there is a pending buffer on the out queue. */
		buffer = NULL;
		if (!list_empty(&sclp_con_outqueue))
			buffer = list_entry(sclp_con_outqueue.next,
					    struct sclp_buffer, list);
		spin_unlock_irqrestore(&sclp_con_lock, flags);
	} while (buffer && sclp_emit_buffer(buffer, sclp_conbuf_callback));
}

static void
sclp_conbuf_emit(void)
{
	struct sclp_buffer* buffer;
	unsigned long flags;
	int count;
	int rc;

	spin_lock_irqsave(&sclp_con_lock, flags);
	buffer = sclp_conbuf;
	sclp_conbuf = NULL;
	if (buffer == NULL) {
		spin_unlock_irqrestore(&sclp_con_lock, flags);
		return;
	}
	list_add_tail(&buffer->list, &sclp_con_outqueue);
	count = sclp_con_buffer_count++;
	spin_unlock_irqrestore(&sclp_con_lock, flags);
	if (count)
		return;
	rc = sclp_emit_buffer(buffer, sclp_conbuf_callback);
	if (rc)
		sclp_conbuf_callback(buffer, rc);
}

/*
 * When this routine is called from the timer then we flush the
 * temporary write buffer without further waiting on a final new line.
 */
static void
sclp_console_timeout(unsigned long data)
{
	sclp_conbuf_emit();
}

/*
 * Writes the given message to S390 system console
 */
static void
sclp_console_write(struct console *console, const char *message,
		   unsigned int count)
{
	unsigned long flags;
	void *page;
	int written;

	if (count == 0)
		return;
	spin_lock_irqsave(&sclp_con_lock, flags);
	/*
	 * process escape characters, write message into buffer,
	 * send buffer to SCLP
	 */
	do {
		/* make sure we have a console output buffer */
		if (sclp_conbuf == NULL) {
			while (list_empty(&sclp_con_pages)) {
				spin_unlock_irqrestore(&sclp_con_lock, flags);
				sclp_sync_wait();
				spin_lock_irqsave(&sclp_con_lock, flags);
			}
			page = sclp_con_pages.next;
			list_del((struct list_head *) page);
			sclp_conbuf = sclp_make_buffer(page, sclp_con_columns,
						       sclp_con_width_htab);
		}
		/* try to write the string to the current output buffer */
		written = sclp_write(sclp_conbuf, (const unsigned char *)
				     message, count);
		if (written == count)
			break;
		/*
		 * Not all characters could be written to the current
		 * output buffer. Emit the buffer, create a new buffer
		 * and then output the rest of the string.
		 */
		spin_unlock_irqrestore(&sclp_con_lock, flags);
		sclp_conbuf_emit();
		spin_lock_irqsave(&sclp_con_lock, flags);
		message += written;
		count -= written;
	} while (count > 0);
	/* Setup timer to output current console buffer after 1/10 second */
	if (sclp_conbuf != NULL && sclp_chars_in_buffer(sclp_conbuf) != 0 &&
	    !timer_pending(&sclp_con_timer)) {
		init_timer(&sclp_con_timer);
		sclp_con_timer.function = sclp_console_timeout;
		sclp_con_timer.data = 0UL;
		sclp_con_timer.expires = jiffies + HZ/10;
		add_timer(&sclp_con_timer);
	}
	spin_unlock_irqrestore(&sclp_con_lock, flags);
}

static struct tty_driver *
sclp_console_device(struct console *c, int *index)
{
	*index = c->index;
	return sclp_tty_driver;
}

/*
 * This routine is called from panic when the kernel
 * is going to give up. We have to make sure that all buffers
 * will be flushed to the SCLP.
 */
static void
sclp_console_unblank(void)
{
	unsigned long flags;

	sclp_conbuf_emit();
	spin_lock_irqsave(&sclp_con_lock, flags);
	if (timer_pending(&sclp_con_timer))
		del_timer(&sclp_con_timer);
	while (sclp_con_buffer_count > 0) {
		spin_unlock_irqrestore(&sclp_con_lock, flags);
		sclp_sync_wait();
		spin_lock_irqsave(&sclp_con_lock, flags);
	}
	spin_unlock_irqrestore(&sclp_con_lock, flags);
}

/*
 * used to register the SCLP console to the kernel and to
 * give printk necessary information
 */
static struct console sclp_console =
{
	.name = sclp_console_name,
	.write = sclp_console_write,
	.device = sclp_console_device,
	.unblank = sclp_console_unblank,
	.flags = CON_PRINTBUFFER,
	.index = 0 /* ttyS0 */
};

/*
 * called by console_init() in drivers/char/tty_io.c at boot-time.
 */
static int __init
sclp_console_init(void)
{
	void *page;
	int i;
	int rc;

	if (!CONSOLE_IS_SCLP)
		return 0;
	rc = sclp_rw_init();
	if (rc)
		return rc;
	/* Allocate pages for output buffering */
	INIT_LIST_HEAD(&sclp_con_pages);
	for (i = 0; i < MAX_CONSOLE_PAGES; i++) {
		page = alloc_bootmem_low_pages(PAGE_SIZE);
		if (page == NULL)
			return -ENOMEM;
		list_add_tail((struct list_head *) page, &sclp_con_pages);
	}
	INIT_LIST_HEAD(&sclp_con_outqueue);
	spin_lock_init(&sclp_con_lock);
	sclp_con_buffer_count = 0;
	sclp_conbuf = NULL;
	init_timer(&sclp_con_timer);

	/* Set output format */
	if (MACHINE_IS_VM)
		/*
		 * save 4 characters for the CPU number
		 * written at start of each line by VM/CP
		 */
		sclp_con_columns = 76;
	else
		sclp_con_columns = 80;
	sclp_con_width_htab = 8;

	/* enable printk-access to this driver */
	register_console(&sclp_console);
	return 0;
}

console_initcall(sclp_console_init);
