/*
 * AVR power-management chip interface for the Buffalo Linkstation /
 * Kurobox Platform.
 *
 * Author: 2006 (c) G. Liakhovetski
 *	 g.liakhovetski@gmx.de
 *
 * This file is licensed under the terms of the GNU General Public License
 * version 2.  This program is licensed "as is" without any warranty of
 * any kind, whether express or implied.
 */
#include <linux/workqueue.h>
#include <linux/string.h>
#include <linux/delay.h>
#include <linux/serial_reg.h>
#include <linux/serial_8250.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <asm/io.h>
#include <asm/termbits.h>

#include "mpc10x.h"

static void __iomem *avr_addr;
static unsigned long avr_clock;

static struct work_struct wd_work;

static void wd_stop(struct work_struct *unused)
{
	const char string[] = "AAAAFFFFJJJJ>>>>VVVV>>>>ZZZZVVVVKKKK";
	int i = 0, rescue = 8;
	int len = strlen(string);

	while (rescue--) {
		int j;
		char lsr = in_8(avr_addr + UART_LSR);

		if (lsr & (UART_LSR_THRE | UART_LSR_TEMT)) {
			for (j = 0; j < 16 && i < len; j++, i++)
				out_8(avr_addr + UART_TX, string[i]);
			if (i == len) {
				/* Read "OK" back: 4ms for the last "KKKK"
				   plus a couple bytes back */
				msleep(7);
				printk("linkstation: disarming the AVR watchdog: ");
				while (in_8(avr_addr + UART_LSR) & UART_LSR_DR)
					printk("%c", in_8(avr_addr + UART_RX));
				break;
			}
		}
		msleep(17);
	}
	printk("\n");
}

#define AVR_QUOT(clock) ((clock) + 8 * 9600) / (16 * 9600)

void avr_uart_configure(void)
{
	unsigned char cval = UART_LCR_WLEN8;
	unsigned int quot = AVR_QUOT(avr_clock);

	if (!avr_addr || !avr_clock)
		return;

	out_8(avr_addr + UART_LCR, cval);			/* initialise UART */
	out_8(avr_addr + UART_MCR, 0);
	out_8(avr_addr + UART_IER, 0);

	cval |= UART_LCR_STOP | UART_LCR_PARITY | UART_LCR_EPAR;

	out_8(avr_addr + UART_LCR, cval);			/* Set character format */

	out_8(avr_addr + UART_LCR, cval | UART_LCR_DLAB);	/* set DLAB */
	out_8(avr_addr + UART_DLL, quot & 0xff);		/* LS of divisor */
	out_8(avr_addr + UART_DLM, quot >> 8);			/* MS of divisor */
	out_8(avr_addr + UART_LCR, cval);			/* reset DLAB */
	out_8(avr_addr + UART_FCR, UART_FCR_ENABLE_FIFO);	/* enable FIFO */
}

void avr_uart_send(const char c)
{
	if (!avr_addr || !avr_clock)
		return;

	out_8(avr_addr + UART_TX, c);
	out_8(avr_addr + UART_TX, c);
	out_8(avr_addr + UART_TX, c);
	out_8(avr_addr + UART_TX, c);
}

static void __init ls_uart_init(void)
{
	local_irq_disable();

#ifndef CONFIG_SERIAL_8250
	out_8(avr_addr + UART_FCR, UART_FCR_ENABLE_FIFO);	/* enable FIFO */
	out_8(avr_addr + UART_FCR, UART_FCR_ENABLE_FIFO |
	      UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT);	/* clear FIFOs */
	out_8(avr_addr + UART_FCR, 0);
	out_8(avr_addr + UART_IER, 0);

	/* Clear up interrupts */
	(void) in_8(avr_addr + UART_LSR);
	(void) in_8(avr_addr + UART_RX);
	(void) in_8(avr_addr + UART_IIR);
	(void) in_8(avr_addr + UART_MSR);
#endif
	avr_uart_configure();

	local_irq_enable();
}

static int __init ls_uarts_init(void)
{
	struct device_node *avr;
	struct resource res;
	int len, ret;

	avr = of_find_node_by_path("/soc10x/serial@80004500");
	if (!avr)
		return -EINVAL;

	avr_clock = *(u32*)of_get_property(avr, "clock-frequency", &len);
	if (!avr_clock)
		return -EINVAL;

	ret = of_address_to_resource(avr, 0, &res);
	if (ret)
		return ret;

	of_node_put(avr);

	avr_addr = ioremap(res.start, 32);
	if (!avr_addr)
		return -EFAULT;

	ls_uart_init();

	INIT_WORK(&wd_work, wd_stop);
	schedule_work(&wd_work);

	return 0;
}

machine_late_initcall(linkstation, ls_uarts_init);
