/* Copyright (c) 2010-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/module.h>
#include <linux/platform_device.h>
#include <linux/err.h>
#include <linux/slab.h>
#include <linux/io.h>
#include <linux/mutex.h>
#include <linux/miscdevice.h>
#include <linux/fs.h>
#include <linux/gpio.h>
#include <linux/kernel.h>
#include <linux/irq.h>
#include <linux/ioctl.h>
#include <linux/delay.h>
#include <linux/reboot.h>
#include <linux/debugfs.h>
#include <linux/completion.h>
#include <linux/workqueue.h>
#include <asm/mach-types.h>
#include <asm/uaccess.h>
#include <linux/mfd/pm8xxx/misc.h>
#include <mach/mdm.h>
#include <mach/restart.h>
#include <mach/subsystem_notif.h>
#include <mach/subsystem_restart.h>
#include <linux/msm_charm.h>
#include "msm_watchdog.h"
#include "devices.h"

#define CHARM_MODEM_TIMEOUT	6000
#define CHARM_HOLD_TIME		4000
#define CHARM_MODEM_DELTA	100

static void (*power_on_charm)(void);
static void (*power_down_charm)(void);

static int charm_debug_on;
static int charm_status_irq;
static int charm_errfatal_irq;
static int charm_ready;
static enum charm_boot_type boot_type = CHARM_NORMAL_BOOT;
static int charm_boot_status;
static int charm_ram_dump_status;
static struct workqueue_struct *charm_queue;

#define CHARM_DBG(...)	do { if (charm_debug_on) \
					pr_info(__VA_ARGS__); \
			} while (0);


DECLARE_COMPLETION(charm_needs_reload);
DECLARE_COMPLETION(charm_boot);
DECLARE_COMPLETION(charm_ram_dumps);

static void charm_disable_irqs(void)
{
	disable_irq_nosync(charm_errfatal_irq);
	disable_irq_nosync(charm_status_irq);

}

static int charm_subsys_shutdown(const struct subsys_desc *crashed_subsys)
{
	charm_ready = 0;
	power_down_charm();
	return 0;
}

static int charm_subsys_powerup(const struct subsys_desc *crashed_subsys)
{
	power_on_charm();
	boot_type = CHARM_NORMAL_BOOT;
	complete(&charm_needs_reload);
	wait_for_completion(&charm_boot);
	pr_info("%s: charm modem has been restarted\n", __func__);
	INIT_COMPLETION(charm_boot);
	return charm_boot_status;
}

static int charm_subsys_ramdumps(int want_dumps,
				const struct subsys_desc *crashed_subsys)
{
	charm_ram_dump_status = 0;
	if (want_dumps) {
		boot_type = CHARM_RAM_DUMPS;
		complete(&charm_needs_reload);
		wait_for_completion(&charm_ram_dumps);
		INIT_COMPLETION(charm_ram_dumps);
		power_down_charm();
	}
	return charm_ram_dump_status;
}

static struct subsys_device *charm_subsys;

static struct subsys_desc charm_subsystem = {
	.shutdown = charm_subsys_shutdown,
	.ramdump = charm_subsys_ramdumps,
	.powerup = charm_subsys_powerup,
	.name = "external_modem",
};

static int charm_panic_prep(struct notifier_block *this,
				unsigned long event, void *ptr)
{
	int i;

	CHARM_DBG("%s: setting AP2MDM_ERRFATAL high for a non graceful reset\n",
			 __func__);
	if (get_restart_level() == RESET_SOC)
		pm8xxx_stay_on();

	charm_disable_irqs();
	gpio_set_value(AP2MDM_ERRFATAL, 1);
	gpio_set_value(AP2MDM_WAKEUP, 1);
	for (i = CHARM_MODEM_TIMEOUT; i > 0; i -= CHARM_MODEM_DELTA) {
		pet_watchdog();
		mdelay(CHARM_MODEM_DELTA);
		if (gpio_get_value(MDM2AP_STATUS) == 0)
			break;
	}
	if (i <= 0)
		pr_err("%s: MDM2AP_STATUS never went low\n", __func__);
	return NOTIFY_DONE;
}

static struct notifier_block charm_panic_blk = {
	.notifier_call  = charm_panic_prep,
};

static int first_boot = 1;

static long charm_modem_ioctl(struct file *filp, unsigned int cmd,
				unsigned long arg)
{

	int status, ret = 0;

	if (_IOC_TYPE(cmd) != CHARM_CODE) {
		pr_err("%s: invalid ioctl code\n", __func__);
		return -EINVAL;
	}

	CHARM_DBG("%s: Entering ioctl cmd = %d\n", __func__, _IOC_NR(cmd));
	switch (cmd) {
	case WAKE_CHARM:
		CHARM_DBG("%s: Powering on\n", __func__);
		power_on_charm();
		break;
	case CHECK_FOR_BOOT:
		if (gpio_get_value(MDM2AP_STATUS) == 0)
			put_user(1, (unsigned long __user *) arg);
		else
			put_user(0, (unsigned long __user *) arg);
		break;
	case NORMAL_BOOT_DONE:
		CHARM_DBG("%s: check if charm is booted up\n", __func__);
		get_user(status, (unsigned long __user *) arg);
		if (status)
			charm_boot_status = -EIO;
		else
			charm_boot_status = 0;
		charm_ready = 1;

		gpio_set_value(AP2MDM_KPDPWR_N, 0);
		if (!first_boot)
			complete(&charm_boot);
		else
			first_boot = 0;
		break;
	case RAM_DUMP_DONE:
		CHARM_DBG("%s: charm done collecting RAM dumps\n", __func__);
		get_user(status, (unsigned long __user *) arg);
		if (status)
			charm_ram_dump_status = -EIO;
		else
			charm_ram_dump_status = 0;
		complete(&charm_ram_dumps);
		break;
	case WAIT_FOR_RESTART:
		CHARM_DBG("%s: wait for charm to need images reloaded\n",
				__func__);
		ret = wait_for_completion_interruptible(&charm_needs_reload);
		if (!ret)
			put_user(boot_type, (unsigned long __user *) arg);
		INIT_COMPLETION(charm_needs_reload);
		break;
	default:
		pr_err("%s: invalid ioctl cmd = %d\n", __func__, _IOC_NR(cmd));
		ret = -EINVAL;
		break;
	}

	return ret;
}

static int charm_modem_open(struct inode *inode, struct file *file)
{
	return 0;
}

static const struct file_operations charm_modem_fops = {
	.owner		= THIS_MODULE,
	.open		= charm_modem_open,
	.unlocked_ioctl	= charm_modem_ioctl,
};


struct miscdevice charm_modem_misc = {
	.minor	= MISC_DYNAMIC_MINOR,
	.name	= "mdm",
	.fops	= &charm_modem_fops
};



static void charm_status_fn(struct work_struct *work)
{
	pr_info("Reseting the charm because status changed\n");
	subsystem_restart_dev(charm_subsys);
}

static DECLARE_WORK(charm_status_work, charm_status_fn);

static void charm_fatal_fn(struct work_struct *work)
{
	pr_info("Reseting the charm due to an errfatal\n");
	if (get_restart_level() == RESET_SOC)
		pm8xxx_stay_on();
	subsystem_restart_dev(charm_subsys);
}

static DECLARE_WORK(charm_fatal_work, charm_fatal_fn);

static irqreturn_t charm_errfatal(int irq, void *dev_id)
{
	CHARM_DBG("%s: charm got errfatal interrupt\n", __func__);
	if (charm_ready && (gpio_get_value(MDM2AP_STATUS) == 1)) {
		CHARM_DBG("%s: scheduling work now\n", __func__);
		queue_work(charm_queue, &charm_fatal_work);
	}
	return IRQ_HANDLED;
}

static irqreturn_t charm_status_change(int irq, void *dev_id)
{
	CHARM_DBG("%s: charm sent status change interrupt\n", __func__);
	if ((gpio_get_value(MDM2AP_STATUS) == 0) && charm_ready) {
		CHARM_DBG("%s: scheduling work now\n", __func__);
		queue_work(charm_queue, &charm_status_work);
	} else if (gpio_get_value(MDM2AP_STATUS) == 1) {
		CHARM_DBG("%s: charm is now ready\n", __func__);
	}
	return IRQ_HANDLED;
}

static int charm_debug_on_set(void *data, u64 val)
{
	charm_debug_on = val;
	return 0;
}

static int charm_debug_on_get(void *data, u64 *val)
{
	*val = charm_debug_on;
	return 0;
}

DEFINE_SIMPLE_ATTRIBUTE(charm_debug_on_fops,
			charm_debug_on_get,
			charm_debug_on_set, "%llu\n");

static int charm_debugfs_init(void)
{
	struct dentry *dent;

	dent = debugfs_create_dir("charm_dbg", 0);
	if (IS_ERR(dent))
		return PTR_ERR(dent);

	debugfs_create_file("debug_on", 0644, dent, NULL,
			&charm_debug_on_fops);
	return 0;
}

static int gsbi9_uart_notifier_cb(struct notifier_block *this,
					unsigned long code, void *_cmd)
{
	switch (code) {
	case SUBSYS_AFTER_SHUTDOWN:
		platform_device_unregister(msm_device_uart_gsbi9);
		msm_device_uart_gsbi9 = msm_add_gsbi9_uart();
		if (IS_ERR(msm_device_uart_gsbi9))
			pr_err("%s(): Failed to create uart gsbi9 device\n",
								__func__);
	default:
		break;
	}
	return NOTIFY_DONE;
}

static struct notifier_block gsbi9_nb = {
	.notifier_call = gsbi9_uart_notifier_cb,
};

static int __init charm_modem_probe(struct platform_device *pdev)
{
	int ret, irq;
	struct charm_platform_data *d = pdev->dev.platform_data;

	gpio_request(AP2MDM_STATUS, "AP2MDM_STATUS");
	gpio_request(AP2MDM_ERRFATAL, "AP2MDM_ERRFATAL");
	gpio_request(AP2MDM_KPDPWR_N, "AP2MDM_KPDPWR_N");
	gpio_request(AP2MDM_PMIC_RESET_N, "AP2MDM_PMIC_RESET_N");
	gpio_request(MDM2AP_STATUS, "MDM2AP_STATUS");
	gpio_request(MDM2AP_ERRFATAL, "MDM2AP_ERRFATAL");
	gpio_request(AP2MDM_WAKEUP, "AP2MDM_WAKEUP");

	gpio_direction_output(AP2MDM_STATUS, 1);
	gpio_direction_output(AP2MDM_ERRFATAL, 0);
	gpio_direction_output(AP2MDM_WAKEUP, 0);
	gpio_direction_input(MDM2AP_STATUS);
	gpio_direction_input(MDM2AP_ERRFATAL);

	power_on_charm = d->charm_modem_on;
	power_down_charm = d->charm_modem_off;

	charm_queue = create_singlethread_workqueue("charm_queue");
	if (!charm_queue) {
		pr_err("%s: could not create workqueue. All charm \
				functionality will be disabled\n",
			__func__);
		ret = -ENOMEM;
		goto fatal_err;
	}

	atomic_notifier_chain_register(&panic_notifier_list, &charm_panic_blk);
	charm_debugfs_init();

	charm_subsys = subsys_register(&charm_subsystem);
	if (IS_ERR(charm_subsys)) {
		ret = PTR_ERR(charm_subsys);
		goto fatal_err;
	}
	subsys_default_online(charm_subsys);

	irq = platform_get_irq(pdev, 0);
	if (irq < 0) {
		pr_err("%s: could not get MDM2AP_ERRFATAL IRQ resource. \
			error=%d No IRQ will be generated on errfatal.",
			__func__, irq);
		goto errfatal_err;
	}

	ret = request_irq(irq, charm_errfatal,
		IRQF_TRIGGER_RISING , "charm errfatal", NULL);

	if (ret < 0) {
		pr_err("%s: MDM2AP_ERRFATAL IRQ#%d request failed with error=%d\
			. No IRQ will be generated on errfatal.",
			__func__, irq, ret);
		goto errfatal_err;
	}
	charm_errfatal_irq = irq;

errfatal_err:

	irq = platform_get_irq(pdev, 1);
	if (irq < 0) {
		pr_err("%s: could not get MDM2AP_STATUS IRQ resource. \
			error=%d No IRQ will be generated on status change.",
			__func__, irq);
		goto status_err;
	}

	ret = request_threaded_irq(irq, NULL, charm_status_change,
		IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
		"charm status", NULL);

	if (ret < 0) {
		pr_err("%s: MDM2AP_STATUS IRQ#%d request failed with error=%d\
			. No IRQ will be generated on status change.",
			__func__, irq, ret);
		goto status_err;
	}
	charm_status_irq = irq;

status_err:
	subsys_notif_register_notifier("external_modem", &gsbi9_nb);

	pr_info("%s: Registering charm modem\n", __func__);

	return misc_register(&charm_modem_misc);

fatal_err:
	gpio_free(AP2MDM_STATUS);
	gpio_free(AP2MDM_ERRFATAL);
	gpio_free(AP2MDM_KPDPWR_N);
	gpio_free(AP2MDM_PMIC_RESET_N);
	gpio_free(MDM2AP_STATUS);
	gpio_free(MDM2AP_ERRFATAL);
	return ret;

}


static int __devexit charm_modem_remove(struct platform_device *pdev)
{
	gpio_free(AP2MDM_STATUS);
	gpio_free(AP2MDM_ERRFATAL);
	gpio_free(AP2MDM_KPDPWR_N);
	gpio_free(AP2MDM_PMIC_RESET_N);
	gpio_free(MDM2AP_STATUS);
	gpio_free(MDM2AP_ERRFATAL);

	return misc_deregister(&charm_modem_misc);
}

static void charm_modem_shutdown(struct platform_device *pdev)
{
	int i;

	CHARM_DBG("%s: setting AP2MDM_STATUS low for a graceful restart\n",
		__func__);

	charm_disable_irqs();

	gpio_set_value(AP2MDM_STATUS, 0);
	gpio_set_value(AP2MDM_WAKEUP, 1);

	for (i = CHARM_MODEM_TIMEOUT; i > 0; i -= CHARM_MODEM_DELTA) {
		pet_watchdog();
		msleep(CHARM_MODEM_DELTA);
		if (gpio_get_value(MDM2AP_STATUS) == 0)
			break;
	}

	if (i <= 0) {
		pr_err("%s: MDM2AP_STATUS never went low.\n",
			 __func__);
		gpio_direction_output(AP2MDM_PMIC_RESET_N, 1);
		for (i = CHARM_HOLD_TIME; i > 0; i -= CHARM_MODEM_DELTA) {
			pet_watchdog();
			msleep(CHARM_MODEM_DELTA);
		}
		gpio_direction_output(AP2MDM_PMIC_RESET_N, 0);
	}
	gpio_set_value(AP2MDM_WAKEUP, 0);
}

static struct platform_driver charm_modem_driver = {
	.remove         = charm_modem_remove,
	.shutdown	= charm_modem_shutdown,
	.driver         = {
		.name = "charm_modem",
		.owner = THIS_MODULE
	},
};

static int __init charm_modem_init(void)
{
	return platform_driver_probe(&charm_modem_driver, charm_modem_probe);
}

static void __exit charm_modem_exit(void)
{
	platform_driver_unregister(&charm_modem_driver);
}

module_init(charm_modem_init);
module_exit(charm_modem_exit);

MODULE_LICENSE("GPL v2");
MODULE_DESCRIPTION("msm8660 charm modem driver");
MODULE_VERSION("1.0");
MODULE_ALIAS("charm_modem");
