/*
 *  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 inline 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);
