/*
 *  Copyright (c) 2013 Qualcomm Atheros, Inc.
 *
 *  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.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

//#include <linux/config.h>
#include <linux/device.h>
#include <linux/platform_device.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/resource.h>

#include <linux/console.h>
#include <asm/serial.h>

#include <linux/tty.h>
#include <linux/time.h>
#include <linux/serial_core.h>
#include <linux/serial.h>
#include <linux/serial_8250.h>
#include <linux/miscdevice.h>

#include <asm/mach-atheros/atheros.h>
#include <asm/delay.h>

#define ATH_DEFAULT_WD_TMO	(20ul * USEC_PER_SEC)

#define FACTORY_RESET		0x89ABCDEF

#define ATH_GPIO_RESET	21

#ifdef ATH_WDT_TEST_CODE
#	define wddbg printk
#else
#	define wddbg(junk, ...)
#endif /* ATH_WDT_TEST_CODE 8 */

extern uint32_t ath_ahb_freq;

typedef struct {
	int open:1, can_close:1, tmo, action;
	wait_queue_head_t wq;
} ath_wdt_t;

static ath_wdt_t wdt_softc_array;

static ath_wdt_t *wdt = &wdt_softc_array;

irqreturn_t ath_wdt_isr(int, void *);

#ifdef ATH_WDT_TEST_CODE
/* Return the value present in the watchdog register */
static inline uint32_t ath_get_wd_timer(void)
{
	uint32_t val;

	val = (uint32_t) ath_reg_rd(ATH_WATCHDOG_TMR);
	val = (val * USEC_PER_SEC) / ath_ahb_freq;

	return val;
}
#endif /* ATH_WDT_TEST_CODE */

/* Set the timeout value in the watchdog register */
void ath_set_wd_timer(uint32_t usec /* micro seconds */)
{
#if defined(CONFIG_MACH_QCA956x)
        uint32_t vTmpusec = 0;
        uint32_t vCnt = 0;
#endif
#if defined(CONFIG_MACH_AR934x) || defined(CONFIG_MACH_QCA955x) || \
    defined(CONFIG_MACH_QCA953x) || defined(CONFIG_MACH_QCA956x)
	usec = usec * (ath_ref_freq / USEC_PER_SEC);
#else
	usec = usec * (ath_ahb_freq / USEC_PER_SEC);
#endif

	wddbg("%s: 0x%08x\n", __func__, usec);

#if defined(CONFIG_MACH_QCA956x)
        //EV[131847], wait WDT timer write in( wait limit time )
        vTmpusec = ath_reg_rd(ATH_WATCHDOG_TMR);
        ath_reg_wr(ATH_WATCHDOG_TMR, usec);

        while(ath_reg_rd(ATH_WATCHDOG_TMR) <= vTmpusec)
        {
            vCnt++;
            if(vCnt >= 100)
            {
                 printk("%s: Write WDT Timer fail !\n",__func__);
                 break;
            }
        }
#else
	ath_reg_wr(ATH_WATCHDOG_TMR, usec);
#endif
		
}

int ath_set_wd_timer_action(uint32_t val)
{
	if (val & ~ATH_WD_ACT_MASK) {
		return EINVAL;
	}

	wdt->action = val;

	/*
	 * bits  : 31 30 - 2 0-1
	 * access: RO  rsvd  Action
	 *
	 * Since bit 31 is read only and rest of the bits
	 * are zero, don't have to do a read-modify-write
	 */
	ath_reg_wr(ATH_WATCHDOG_TMR_CONTROL, val);
	return 0;
}

#ifdef ATH_WDT_TEST_CODE
static inline uint32_t ath_get_wd_timer_action(void)
{
	return (uint32_t) (ath_reg_rd(ATH_WATCHDOG_TMR_CONTROL) &
			   ATH_WD_ACT_MASK);
}

static inline uint32_t ath_get_wd_timer_last(void)
{
	return ((uint32_t) (ath_reg_rd(ATH_WATCHDOG_TMR_CONTROL) &
			    ATH_WD_LAST_MASK) >> ATH_WD_LAST_SHIFT);
}
#endif /* ATH_WDT_TEST_CODE */

#ifndef CONFIG_WATCHDOG_RESET_TIMER
irqreturn_t ath_wdt_isr(int cpl, void *dev_id)
{
	unsigned delay;
	extern int ath_gpio_in_val(int);

#define UDELAY_COUNT 4000

	wddbg("%s: invoked\n", __func__);

	for (delay = UDELAY_COUNT; delay; delay--) {
		if (ath_gpio_in_val(ATH_GPIO_RESET)) {
			break;
		}
		udelay(1000);
	}

	wddbg("%s: %d", __func__, delay);

	if (!delay) {
		wake_up(&wdt->wq);
	} else {
		extern void ath_restart(char *);
		ath_restart(NULL);
	}
	return IRQ_HANDLED;
}
#endif /* CONFIG_WATCHDOG_RESET_TIMER */

static int athwdt_open(struct inode *inode, struct file *file)
{
	wddbg("%s: called\n", __func__);

	if (MINOR(inode->i_rdev) != WATCHDOG_MINOR) {
		return -ENODEV;
	}

	if (wdt->open) {
		return -EBUSY;
	}

	wdt->open = 1;
	wdt->tmo = ATH_DEFAULT_WD_TMO;
	wdt->action = ATH_WD_ACT_NONE;
	wdt->can_close = 0;
	init_waitqueue_head(&wdt->wq);

	ath_set_wd_timer(wdt->tmo);
	ath_set_wd_timer_action(ATH_WD_ACT_NONE);

	return nonseekable_open(inode, file);
}

static int athwdt_close(struct inode *inode, struct file *file)
{
	wddbg("%s: called\n", __func__);

	if (MINOR(inode->i_rdev) != WATCHDOG_MINOR) {
		return -ENODEV;
	}

	if (!wdt->can_close) {
		wddbg("%s: clearing action\n", __func__);
		ath_set_wd_timer_action(ATH_WD_ACT_NONE);
	} else {
		wddbg("%s: not clearing action\n", __func__);
	}
	wdt->open = 0;
	return 0;
}

static ssize_t
athwdt_read(struct file *file, char *buf, size_t count, loff_t * ppos)
{
	wddbg("%s: called\n", __func__);

	return -ENOTSUPP;
}

static int
athwdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
		unsigned long arg)
{
	int ret = 0;

	wddbg("%s: called\n", __func__);

	switch (cmd) {
	case FACTORY_RESET:
		wddbg("%s: intr action\n", __func__);

		if ((ret = request_irq(ATH_MISC_IRQ_WATCHDOG,
				       ath_wdt_isr,
				       0, "Watchdog Timer", wdt))) {
			wddbg("%s: request_irq %d\n", __func__, ret);
			return ret;
		}

		ath_set_wd_timer_action(ATH_WD_ACT_GP_INTR);
		sleep_on(&wdt->wq);
		free_irq(ATH_MISC_IRQ_WATCHDOG, wdt);
		break;

	default:
		ret = -EINVAL;
	}

	return ret;
}

static ssize_t
athwdt_write(struct file *file, const char *buf, size_t count, loff_t * ppos)
{
	int i;
	char c;

	wddbg("%s: called\n", __func__);

	for (i = 0; i != count; i++) {
		if (get_user(c, buf + i)) {
			return -EFAULT;
		}

		if (c == 'V') {
			wdt->can_close = 1;
			break;
		}
	}

	if (i) {
		ath_set_wd_timer(wdt->tmo);
		return 1;
	}

	return 0;
}

static struct file_operations athwdt_fops = {
      read:athwdt_read,
      write:athwdt_write,
      ioctl:athwdt_ioctl,
      open:athwdt_open,
      release:athwdt_close
};

static struct miscdevice athwdt_miscdev = {
	WATCHDOG_MINOR,
	"watchdog",
	&athwdt_fops
};

#ifdef CONFIG_WATCHDOG_RESET_TIMER
extern int athwdt_init(void);
#else
int __init athwdt_init(void)
{
	int		ret;
	uint32_t	*sram = KSEG1ADDR(ATH_SRAM_BASE + 0x934);

	extern void ath_gpio_config_input(int);
#ifdef CONFIG_MACH_AR934x
	extern void athwdt_timer_init(void);
#endif

	printk("%s: Registering WDT ", __func__);
	if ((ret = misc_register(&athwdt_miscdev))) {
		printk("failed %d\n", ret);
		return ret;
	} else {
		printk("success\n");
	}

	if (ath_reg_rd(RST_WATCHDOG_TIMER_CONTROL_ADDRESS) &
		RST_WATCHDOG_TIMER_CONTROL_LAST_MASK) {
		*sram = (*sram + 1);
		printk("Watchdog Reset count: %u\n", *sram);
	} else {
		*sram = 0;
	}


#ifdef CONFIG_MACH_AR934x
	athwdt_timer_init();
#endif
	ath_gpio_config_input(ATH_GPIO_RESET);

	return 0;
}
#endif /* CONFIG_WATCHDOG_RESET_TIMER */

late_initcall(athwdt_init);
