/*
 * PIKA Warp(tm) board specific routines
 *
 * Copyright (c) 2008-2009 PIKA Technologies
 *   Sean MacLennan <smaclennan@pikatech.com>
 *
 * This program is free software; you can redistribute  it and/or modify it
 * under  the terms of  the GNU General  Public License as published by the
 * Free Software Foundation;  either version 2 of the  License, or (at your
 * option) any later version.
 */
#include <linux/init.h>
#include <linux/of_platform.h>
#include <linux/kthread.h>
#include <linux/i2c.h>
#include <linux/interrupt.h>
#include <linux/delay.h>
#include <linux/of_gpio.h>
#include <linux/slab.h>
#include <linux/export.h>

#include <asm/machdep.h>
#include <asm/prom.h>
#include <asm/udbg.h>
#include <asm/time.h>
#include <asm/uic.h>
#include <asm/ppc4xx.h>
#include <asm/dma.h>


static const struct of_device_id warp_of_bus[] __initconst = {
	{ .compatible = "ibm,plb4", },
	{ .compatible = "ibm,opb", },
	{ .compatible = "ibm,ebc", },
	{},
};

static int __init warp_device_probe(void)
{
	of_platform_bus_probe(NULL, warp_of_bus, NULL);
	return 0;
}
machine_device_initcall(warp, warp_device_probe);

static int __init warp_probe(void)
{
	if (!of_machine_is_compatible("pika,warp"))
		return 0;

	/* For arch_dma_alloc */
	ISA_DMA_THRESHOLD = ~0L;

	return 1;
}

define_machine(warp) {
	.name		= "Warp",
	.probe 		= warp_probe,
	.progress 	= udbg_progress,
	.init_IRQ 	= uic_init_tree,
	.get_irq 	= uic_get_irq,
	.restart	= ppc4xx_reset_system,
	.calibrate_decr = generic_calibrate_decr,
};


static int __init warp_post_info(void)
{
	struct device_node *np;
	void __iomem *fpga;
	u32 post1, post2;

	/* Sighhhh... POST information is in the sd area. */
	np = of_find_compatible_node(NULL, NULL, "pika,fpga-sd");
	if (np == NULL)
		return -ENOENT;

	fpga = of_iomap(np, 0);
	of_node_put(np);
	if (fpga == NULL)
		return -ENOENT;

	post1 = in_be32(fpga + 0x40);
	post2 = in_be32(fpga + 0x44);

	iounmap(fpga);

	if (post1 || post2)
		printk(KERN_INFO "Warp POST %08x %08x\n", post1, post2);
	else
		printk(KERN_INFO "Warp POST OK\n");

	return 0;
}


#ifdef CONFIG_SENSORS_AD7414

static LIST_HEAD(dtm_shutdown_list);
static void __iomem *dtm_fpga;
static unsigned green_led, red_led;


struct dtm_shutdown {
	struct list_head list;
	void (*func)(void *arg);
	void *arg;
};


int pika_dtm_register_shutdown(void (*func)(void *arg), void *arg)
{
	struct dtm_shutdown *shutdown;

	shutdown = kmalloc(sizeof(struct dtm_shutdown), GFP_KERNEL);
	if (shutdown == NULL)
		return -ENOMEM;

	shutdown->func = func;
	shutdown->arg = arg;

	list_add(&shutdown->list, &dtm_shutdown_list);

	return 0;
}

int pika_dtm_unregister_shutdown(void (*func)(void *arg), void *arg)
{
	struct dtm_shutdown *shutdown;

	list_for_each_entry(shutdown, &dtm_shutdown_list, list)
		if (shutdown->func == func && shutdown->arg == arg) {
			list_del(&shutdown->list);
			kfree(shutdown);
			return 0;
		}

	return -EINVAL;
}

static irqreturn_t temp_isr(int irq, void *context)
{
	struct dtm_shutdown *shutdown;
	int value = 1;

	local_irq_disable();

	gpio_set_value(green_led, 0);

	/* Run through the shutdown list. */
	list_for_each_entry(shutdown, &dtm_shutdown_list, list)
		shutdown->func(shutdown->arg);

	printk(KERN_EMERG "\n\nCritical Temperature Shutdown\n\n");

	while (1) {
		if (dtm_fpga) {
			unsigned reset = in_be32(dtm_fpga + 0x14);
			out_be32(dtm_fpga + 0x14, reset);
		}

		gpio_set_value(red_led, value);
		value ^= 1;
		mdelay(500);
	}

	/* Not reached */
	return IRQ_HANDLED;
}

static int pika_setup_leds(void)
{
	struct device_node *np, *child;

	np = of_find_compatible_node(NULL, NULL, "gpio-leds");
	if (!np) {
		printk(KERN_ERR __FILE__ ": Unable to find leds\n");
		return -ENOENT;
	}

	for_each_child_of_node(np, child)
		if (of_node_name_eq(child, "green"))
			green_led = of_get_gpio(child, 0);
		else if (of_node_name_eq(child, "red"))
			red_led = of_get_gpio(child, 0);

	of_node_put(np);

	return 0;
}

static void pika_setup_critical_temp(struct device_node *np,
				     struct i2c_client *client)
{
	int irq, rc;

	/* Do this before enabling critical temp interrupt since we
	 * may immediately interrupt.
	 */
	pika_setup_leds();

	/* These registers are in 1 degree increments. */
	i2c_smbus_write_byte_data(client, 2, 65); /* Thigh */
	i2c_smbus_write_byte_data(client, 3,  0); /* Tlow */

	irq = irq_of_parse_and_map(np, 0);
	if (!irq) {
		printk(KERN_ERR __FILE__ ": Unable to get ad7414 irq\n");
		return;
	}

	rc = request_irq(irq, temp_isr, 0, "ad7414", NULL);
	if (rc) {
		printk(KERN_ERR __FILE__
		       ": Unable to request ad7414 irq %d = %d\n", irq, rc);
		return;
	}
}

static inline void pika_dtm_check_fan(void __iomem *fpga)
{
	static int fan_state;
	u32 fan = in_be32(fpga + 0x34) & (1 << 14);

	if (fan_state != fan) {
		fan_state = fan;
		if (fan)
			printk(KERN_WARNING "Fan rotation error detected."
				   " Please check hardware.\n");
	}
}

static int pika_dtm_thread(void __iomem *fpga)
{
	struct device_node *np;
	struct i2c_client *client;

	np = of_find_compatible_node(NULL, NULL, "adi,ad7414");
	if (np == NULL)
		return -ENOENT;

	client = of_find_i2c_device_by_node(np);
	if (client == NULL) {
		of_node_put(np);
		return -ENOENT;
	}

	pika_setup_critical_temp(np, client);

	of_node_put(np);

	printk(KERN_INFO "Warp DTM thread running.\n");

	while (!kthread_should_stop()) {
		int val;

		val = i2c_smbus_read_word_data(client, 0);
		if (val < 0)
			dev_dbg(&client->dev, "DTM read temp failed.\n");
		else {
			s16 temp = swab16(val);
			out_be32(fpga + 0x20, temp);
		}

		pika_dtm_check_fan(fpga);

		set_current_state(TASK_INTERRUPTIBLE);
		schedule_timeout(HZ);
	}

	return 0;
}

static int __init pika_dtm_start(void)
{
	struct task_struct *dtm_thread;
	struct device_node *np;

	np = of_find_compatible_node(NULL, NULL, "pika,fpga");
	if (np == NULL)
		return -ENOENT;

	dtm_fpga = of_iomap(np, 0);
	of_node_put(np);
	if (dtm_fpga == NULL)
		return -ENOENT;

	/* Must get post info before thread starts. */
	warp_post_info();

	dtm_thread = kthread_run(pika_dtm_thread, dtm_fpga, "pika-dtm");
	if (IS_ERR(dtm_thread)) {
		iounmap(dtm_fpga);
		return PTR_ERR(dtm_thread);
	}

	return 0;
}
machine_late_initcall(warp, pika_dtm_start);

#else /* !CONFIG_SENSORS_AD7414 */

int pika_dtm_register_shutdown(void (*func)(void *arg), void *arg)
{
	return 0;
}

int pika_dtm_unregister_shutdown(void (*func)(void *arg), void *arg)
{
	return 0;
}

machine_late_initcall(warp, warp_post_info);

#endif

EXPORT_SYMBOL(pika_dtm_register_shutdown);
EXPORT_SYMBOL(pika_dtm_unregister_shutdown);
