/*
 * RM200 specific code
 *
 * This file is subject to the terms and conditions of the GNU General Public
 * License.  See the file "COPYING" in the main directory of this archive
 * for more details.
 *
 * Copyright (C) 2006 Thomas Bogendoerfer (tsbogend@alpha.franken.de)
 */

#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/platform_device.h>
#include <linux/serial_8250.h>

#include <asm/sni.h>
#include <asm/time.h>
#include <asm/ds1216.h>
#include <asm/irq_cpu.h>

#define PORT(_base,_irq)				\
	{						\
		.iobase		= _base,		\
		.irq		= _irq,			\
		.uartclk	= 1843200,		\
		.iotype		= UPIO_PORT,		\
		.flags		= UPF_BOOT_AUTOCONF,	\
	}

static struct plat_serial8250_port rm200_data[] = {
	PORT(0x3f8, 4),
	PORT(0x2f8, 3),
	{ },
};

static struct platform_device rm200_serial8250_device = {
	.name			= "serial8250",
	.id			= PLAT8250_DEV_PLATFORM,
	.dev			= {
		.platform_data	= rm200_data,
	},
};

static struct resource snirm_82596_rm200_rsrc[] = {
	{
		.start = 0xb8000000,
		.end   = 0xb80fffff,
		.flags = IORESOURCE_MEM
	},
	{
		.start = 0xbb000000,
		.end   = 0xbb000004,
		.flags = IORESOURCE_MEM
	},
	{
		.start = 0xbff00000,
		.end   = 0xbff00020,
		.flags = IORESOURCE_MEM
	},
	{
		.start = 27,
		.end   = 27,
		.flags = IORESOURCE_IRQ
	},
	{
		.flags = 0x00
	}
};

static struct platform_device snirm_82596_rm200_pdev = {
	.name           = "snirm_82596",
	.num_resources  = ARRAY_SIZE(snirm_82596_rm200_rsrc),
	.resource       = snirm_82596_rm200_rsrc
};

static struct resource snirm_53c710_rm200_rsrc[] = {
	{
		.start = 0xb9000000,
		.end   = 0xb90fffff,
		.flags = IORESOURCE_MEM
	},
	{
		.start = 26,
		.end   = 26,
		.flags = IORESOURCE_IRQ
	}
};

static struct platform_device snirm_53c710_rm200_pdev = {
	.name           = "snirm_53c710",
	.num_resources  = ARRAY_SIZE(snirm_53c710_rm200_rsrc),
	.resource       = snirm_53c710_rm200_rsrc
};

static int __init snirm_setup_devinit(void)
{
	if (sni_brd_type == SNI_BRD_RM200) {
		platform_device_register(&rm200_serial8250_device);
		platform_device_register(&snirm_82596_rm200_pdev);
		platform_device_register(&snirm_53c710_rm200_pdev);
	}
	return 0;
}

device_initcall(snirm_setup_devinit);


#define SNI_RM200_INT_STAT_REG  0xbc000000
#define SNI_RM200_INT_ENA_REG   0xbc080000

#define SNI_RM200_INT_START  24
#define SNI_RM200_INT_END    28

static void enable_rm200_irq(unsigned int irq)
{
	unsigned int mask = 1 << (irq - SNI_RM200_INT_START);

	*(volatile u8 *)SNI_RM200_INT_ENA_REG &= ~mask;
}

void disable_rm200_irq(unsigned int irq)
{
	unsigned int mask = 1 << (irq - SNI_RM200_INT_START);

	*(volatile u8 *)SNI_RM200_INT_ENA_REG |= mask;
}

void end_rm200_irq(unsigned int irq)
{
	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
		enable_rm200_irq(irq);
}

static struct irq_chip rm200_irq_type = {
	.typename = "RM200",
	.ack = disable_rm200_irq,
	.mask = disable_rm200_irq,
	.mask_ack = disable_rm200_irq,
	.unmask = enable_rm200_irq,
	.end = end_rm200_irq,
};

static void sni_rm200_hwint(void)
{
	u32 pending = read_c0_cause() & read_c0_status();
	u8 mask;
	u8 stat;
	int irq;

	if (pending & C_IRQ5)
		do_IRQ (SNI_MIPS_IRQ_CPU_BASE + 7);
	else if (pending & C_IRQ0) {
		clear_c0_status (IE_IRQ0);
		mask = *(volatile u8 *)SNI_RM200_INT_ENA_REG ^ 0x1f;
		stat = *(volatile u8 *)SNI_RM200_INT_STAT_REG ^ 0x14;
		irq = ffs(stat & mask & 0x1f);

		if (likely(irq > 0))
			do_IRQ (irq + SNI_RM200_INT_START - 1);
		set_c0_status (IE_IRQ0);
	}
}

void __init sni_rm200_irq_init(void)
{
	int i;

	* (volatile u8 *)SNI_RM200_INT_ENA_REG = 0x1f;

	mips_cpu_irq_init();
	/* Actually we've got more interrupts to handle ...  */
	for (i = SNI_RM200_INT_START; i <= SNI_RM200_INT_END; i++)
		set_irq_chip(i, &rm200_irq_type);
	sni_hwint = sni_rm200_hwint;
	change_c0_status(ST0_IM, IE_IRQ0);
	setup_irq (SNI_RM200_INT_START + 0, &sni_isa_irq);
}

void sni_rm200_init(void)
{
	set_io_port_base(SNI_PORT_BASE + 0x02000000);
	ioport_resource.end += 0x02000000;
	ds1216_base = (volatile unsigned char *) SNI_DS1216_RM200_BASE;
	rtc_mips_get_time = ds1216_get_cmos_time;
	board_time_init = sni_cpu_time_init;
}
