/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
 * only version 2 as published by the Free Software Foundation.
 *
 * 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.
 */

#include <linux/kernel.h>
#include <linux/interrupt.h>
#include <linux/reboot.h>
#include <linux/workqueue.h>
#include <linux/io.h>
#include <linux/jiffies.h>
#include <linux/stringify.h>
#include <linux/delay.h>
#include <linux/module.h>
#include <linux/err.h>

#include <mach/irqs.h>
#include <mach/scm.h>
#include <mach/peripheral-loader.h>
#include <mach/subsystem_restart.h>
#include <mach/subsystem_notif.h>

#include "smd_private.h"
#include "modem_notifier.h"
#include "ramdump.h"

#define MODEM_HWIO_MSS_RESET_ADDR       0x00902C48
#define MODULE_NAME			"modem_8660"
#define MODEM_WDOG_ENABLE		0x10020008
#define MODEM_CLEANUP_DELAY_MS		20

#define SUBSYS_FATAL_DEBUG

#if defined(SUBSYS_FATAL_DEBUG)
static void debug_crash_modem_fn(struct work_struct *);
static int reset_modem;
static int ignore_smsm_ack;

static DECLARE_DELAYED_WORK(debug_crash_modem_work,
				debug_crash_modem_fn);

module_param(reset_modem, int, 0644);
#endif

static struct subsys_device *modem_8660_dev;

/* Subsystem restart: Modem data, functions */
static void *modem_ramdump_dev;
static void modem_fatal_fn(struct work_struct *);
static void modem_unlock_timeout(struct work_struct *work);
static int modem_notif_handler(struct notifier_block *this,
				unsigned long code,
				void *_cmd);
static DECLARE_WORK(modem_fatal_work, modem_fatal_fn);
static DECLARE_DELAYED_WORK(modem_unlock_timeout_work,
				modem_unlock_timeout);

static struct notifier_block modem_notif_nb = {
	.notifier_call = modem_notif_handler,
};

static void modem_unlock_timeout(struct work_struct *work)
{
	void __iomem *hwio_modem_reset_addr =
			ioremap_nocache(MODEM_HWIO_MSS_RESET_ADDR, 8);
	pr_crit("%s: Timeout waiting for modem to unlock.\n", MODULE_NAME);

	/* Set MSS_MODEM_RESET to 0x0 since the unlock didn't work */
	writel_relaxed(0x0, hwio_modem_reset_addr);
	/* Write needs to go through before the modem is restarted. */
	mb();
	iounmap(hwio_modem_reset_addr);

	subsystem_restart_dev(modem_8660_dev);
	enable_irq(MARM_WDOG_EXPIRED);
}

static void modem_fatal_fn(struct work_struct *work)
{
	uint32_t modem_state;
	uint32_t panic_smsm_states = SMSM_RESET | SMSM_SYSTEM_DOWNLOAD;
	uint32_t reset_smsm_states = SMSM_SYSTEM_REBOOT_USR |
					SMSM_SYSTEM_PWRDWN_USR;

	pr_err("%s: Watchdog bite received from modem!\n", MODULE_NAME);

	modem_state = smsm_get_state(SMSM_MODEM_STATE);
	pr_err("%s: Modem SMSM state = 0x%x!", MODULE_NAME, modem_state);

	if (modem_state == 0 || modem_state & panic_smsm_states) {

		subsystem_restart_dev(modem_8660_dev);
		enable_irq(MARM_WDOG_EXPIRED);

	} else if (modem_state & reset_smsm_states) {

		pr_err("%s: User-invoked system reset/powerdown.",
			MODULE_NAME);
		kernel_restart(NULL);

	} else {

		int ret;
		void *hwio_modem_reset_addr =
				ioremap_nocache(MODEM_HWIO_MSS_RESET_ADDR, 8);

		pr_err("%s: Modem AHB locked up.\n", MODULE_NAME);
		pr_err("%s: Trying to free up modem!\n", MODULE_NAME);

		writel_relaxed(0x3, hwio_modem_reset_addr);

		/* If we are still alive after 6 seconds (allowing for
		 * the 5-second-delayed-panic-reboot), modem is either
		 * still wedged or SMSM didn't come through. Force panic
		 * in that case.
		*/
		ret = schedule_delayed_work(&modem_unlock_timeout_work,
					msecs_to_jiffies(6000));

		iounmap(hwio_modem_reset_addr);
	}
}

static int modem_notif_handler(struct notifier_block *this,
				unsigned long code,
				void *_cmd)
{
	if (code == MODEM_NOTIFIER_START_RESET) {
		if (ignore_smsm_ack) {
			ignore_smsm_ack = 0;
			goto out;
		}
		pr_err("%s: Modem error fatal'ed.", MODULE_NAME);
		subsystem_restart_dev(modem_8660_dev);
	}
out:
	return NOTIFY_DONE;
}

static int modem_shutdown(const struct subsys_desc *crashed_subsys)
{
	void __iomem *modem_wdog_addr;

	/* If the modem didn't already crash, setting SMSM_RESET
	 * here will help flush caches etc. The ignore_smsm_ack
	 * flag is set to ignore the SMSM_RESET notification
	 * that is generated due to the modem settings its own
	 * SMSM_RESET bit in response to the apps setting the
	 * apps SMSM_RESET bit.
	 */
	if (!(smsm_get_state(SMSM_MODEM_STATE) & SMSM_RESET)) {
		ignore_smsm_ack = 1;
		smsm_reset_modem(SMSM_RESET);
	}

	/* Disable the modem watchdog to allow clean modem bootup */
	modem_wdog_addr = ioremap_nocache(MODEM_WDOG_ENABLE, 8);
	writel_relaxed(0x0, modem_wdog_addr);

	/*
	 * The write above needs to go through before the modem is
	 * powered up again (subsystem restart).
	 */
	mb();
	iounmap(modem_wdog_addr);

	/* Wait here to allow the modem to clean up caches etc. */
	msleep(MODEM_CLEANUP_DELAY_MS);
	pil_force_shutdown("modem");
	disable_irq_nosync(MARM_WDOG_EXPIRED);



	return 0;
}

static int modem_powerup(const struct subsys_desc *crashed_subsys)
{
	int ret;

	ret = pil_force_boot("modem");
	enable_irq(MARM_WDOG_EXPIRED);

	return ret;
}

/* FIXME: Get address, size from PIL */
static struct ramdump_segment modem_segments[] = {
	{0x42F00000, 0x46000000 - 0x42F00000} };

static int modem_ramdump(int enable, const struct subsys_desc *crashed_subsys)
{
	if (enable)
		return do_ramdump(modem_ramdump_dev, modem_segments,
			ARRAY_SIZE(modem_segments));
	else
		return 0;
}

static void modem_crash_shutdown(const struct subsys_desc *crashed_subsys)
{
	/* If modem hasn't already crashed, send SMSM_RESET. */
	if (!(smsm_get_state(SMSM_MODEM_STATE) & SMSM_RESET)) {
		modem_unregister_notifier(&modem_notif_nb);
		smsm_reset_modem(SMSM_RESET);
	}

	/* Wait to allow the modem to clean up caches etc. */
	mdelay(5);
}

static irqreturn_t modem_wdog_bite_irq(int irq, void *dev_id)
{
	int ret;

	ret = schedule_work(&modem_fatal_work);
	disable_irq_nosync(MARM_WDOG_EXPIRED);

	return IRQ_HANDLED;
}

static struct subsys_desc subsys_8660_modem = {
	.name = "modem",
	.shutdown = modem_shutdown,
	.powerup = modem_powerup,
	.ramdump = modem_ramdump,
	.crash_shutdown = modem_crash_shutdown
};

static int __init modem_8660_init(void)
{
	int ret;

	/* Need to listen for SMSM_RESET always */
	modem_register_notifier(&modem_notif_nb);

#if defined(SUBSYS_FATAL_DEBUG)
	schedule_delayed_work(&debug_crash_modem_work, msecs_to_jiffies(5000));
#endif

	ret = request_irq(MARM_WDOG_EXPIRED, modem_wdog_bite_irq,
			IRQF_TRIGGER_RISING, "modem_wdog", NULL);

	if (ret < 0) {
		pr_err("%s: Unable to request MARM_WDOG_EXPIRED irq.",
			__func__);
		goto out;
	}

	modem_ramdump_dev = create_ramdump_device("modem");

	if (!modem_ramdump_dev) {
		ret = -ENOMEM;
		goto out;
	}

	modem_8660_dev = subsys_register(&subsys_8660_modem);
	if (IS_ERR(modem_8660_dev))
		ret = PTR_ERR(modem_8660_dev);
out:
	return ret;
}

static void __exit modem_8660_exit(void)
{
	subsys_unregister(modem_8660_dev);
	free_irq(MARM_WDOG_EXPIRED, NULL);
}

#ifdef SUBSYS_FATAL_DEBUG
static void debug_crash_modem_fn(struct work_struct *work)
{
	if (reset_modem == 1)
		smsm_reset_modem(SMSM_RESET);

	reset_modem = 0;
	schedule_delayed_work(&debug_crash_modem_work, msecs_to_jiffies(1000));
}
#endif

module_init(modem_8660_init);
module_exit(modem_8660_exit);

