/*
 * Copyright (c) 2012-2013, The Linux Foundation. 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/init.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/io.h>
#include <linux/err.h>
#include <linux/of.h>
#include <linux/clk.h>
#include <linux/workqueue.h>
#include <linux/interrupt.h>
#include <linux/delay.h>
#include <linux/sysfs.h>
#include <linux/of_gpio.h>

#include <mach/clk.h>
#include <mach/subsystem_restart.h>
#include <mach/subsystem_notif.h>
#include <mach/scm.h>
#include <mach/ramdump.h>
#include <mach/msm_smem.h>

#include "peripheral-loader.h"
#include "pil-q6v5.h"
#include "scm-pas.h"
#include "sysmon.h"

#define QDSP6SS_RST_EVB			0x010
#define PROXY_TIMEOUT_MS		10000

static struct kobject *lpass_status;
static char status[32];

struct lpass_data {
	struct q6v5_data *q6;
	struct subsys_device *subsys;
	struct subsys_desc subsys_desc;
	void *ramdump_dev;
	int wdog_irq;
	struct work_struct work;
	void *wcnss_notif_hdle;
	void *modem_notif_hdle;
	int crash_shutdown;
	unsigned int err_fatal_irq;
	int force_stop_gpio;
};

#define subsys_to_drv(d) container_of(d, struct lpass_data, subsys_desc)

static int pil_lpass_enable_clks(struct q6v5_data *drv)
{
	int ret;

	ret = clk_reset(drv->core_clk, CLK_RESET_DEASSERT);
	if (ret)
		goto err_reset;
	ret = clk_prepare_enable(drv->core_clk);
	if (ret)
		goto err_core_clk;
	ret = clk_prepare_enable(drv->ahb_clk);
	if (ret)
		goto err_ahb_clk;
	ret = clk_prepare_enable(drv->axi_clk);
	if (ret)
		goto err_axi_clk;
	ret = clk_prepare_enable(drv->reg_clk);
	if (ret)
		goto err_reg_clk;

	return 0;

err_reg_clk:
	clk_disable_unprepare(drv->axi_clk);
err_axi_clk:
	clk_disable_unprepare(drv->ahb_clk);
err_ahb_clk:
	clk_disable_unprepare(drv->core_clk);
err_core_clk:
	clk_reset(drv->core_clk, CLK_RESET_ASSERT);
err_reset:
	return ret;
}

static void pil_lpass_disable_clks(struct q6v5_data *drv)
{
	clk_disable_unprepare(drv->reg_clk);
	clk_disable_unprepare(drv->axi_clk);
	clk_disable_unprepare(drv->ahb_clk);
	clk_disable_unprepare(drv->core_clk);
	clk_reset(drv->core_clk, CLK_RESET_ASSERT);
}

static int pil_lpass_shutdown(struct pil_desc *pil)
{
	struct q6v5_data *drv = container_of(pil, struct q6v5_data, desc);

	pil_q6v5_halt_axi_port(pil, drv->axi_halt_base);

	/*
	 * If the shutdown function is called before the reset function, clocks
	 * will not be enabled yet. Enable them here so that register writes
	 * performed during the shutdown succeed.
	 */
	if (drv->is_booted == false)
		pil_lpass_enable_clks(drv);

	pil_q6v5_shutdown(pil);
	pil_lpass_disable_clks(drv);

	writel_relaxed(1, drv->restart_reg);

	drv->is_booted = false;

	return 0;
}

static int pil_lpass_reset(struct pil_desc *pil)
{
	struct q6v5_data *drv = container_of(pil, struct q6v5_data, desc);
	phys_addr_t start_addr = pil_get_entry_addr(pil);
	int ret;

	/* Deassert reset to subsystem and wait for propagation */
	writel_relaxed(0, drv->restart_reg);
	mb();
	udelay(2);

	ret = pil_lpass_enable_clks(drv);
	if (ret)
		return ret;

	/* Program Image Address */
	writel_relaxed((start_addr >> 4) & 0x0FFFFFF0,
				drv->reg_base + QDSP6SS_RST_EVB);

	ret = pil_q6v5_reset(pil);
	if (ret) {
		pil_lpass_disable_clks(drv);
		return ret;
	}

	drv->is_booted = true;

	return 0;
}

static struct pil_reset_ops pil_lpass_ops = {
	.proxy_vote = pil_q6v5_make_proxy_votes,
	.proxy_unvote = pil_q6v5_remove_proxy_votes,
	.auth_and_reset = pil_lpass_reset,
	.shutdown = pil_lpass_shutdown,
};

static int pil_lpass_init_image_trusted(struct pil_desc *pil,
		const u8 *metadata, size_t size)
{
	return pas_init_image(PAS_Q6, metadata, size);
}

static int pil_lpass_mem_setup_trusted(struct pil_desc *pil, phys_addr_t addr,
			       size_t size)
{
	return pas_mem_setup(PAS_Q6, addr, size);
}

static int pil_lpass_reset_trusted(struct pil_desc *pil)
{
	struct q6v5_data *drv = container_of(pil, struct q6v5_data, desc);
	int ret;

	ret = clk_prepare_enable(drv->axi_clk);
	if (ret)
		return ret;
	return pas_auth_and_reset(PAS_Q6);
}

static int pil_lpass_shutdown_trusted(struct pil_desc *pil)
{
	struct q6v5_data *drv = container_of(pil, struct q6v5_data, desc);
	int ret;

	ret = pas_shutdown(PAS_Q6);
	if (ret)
		return ret;
	clk_disable_unprepare(drv->axi_clk);
	return 0;
}

static struct pil_reset_ops pil_lpass_ops_trusted = {
	.init_image = pil_lpass_init_image_trusted,
	.mem_setup = pil_lpass_mem_setup_trusted,
	.proxy_vote = pil_q6v5_make_proxy_votes,
	.proxy_unvote = pil_q6v5_remove_proxy_votes,
	.auth_and_reset = pil_lpass_reset_trusted,
	.shutdown = pil_lpass_shutdown_trusted,
};

static int wcnss_notifier_cb(struct notifier_block *this, unsigned long code,
								void *ss_handle)
{
	int ret;
	pr_debug("%s: W-Notify: event %lu\n", __func__, code);
	ret = sysmon_send_event(SYSMON_SS_LPASS, "wcnss", code);
	if (ret < 0)
		pr_err("%s: sysmon_send_event error %d", __func__, ret);
	return NOTIFY_DONE;
}

static struct notifier_block wnb = {
	.notifier_call = wcnss_notifier_cb,
};

static int modem_notifier_cb(struct notifier_block *this, unsigned long code,
								void *ss_handle)
{
	int ret;
	pr_debug("%s: M-Notify: event %lu\n", __func__, code);
	ret = sysmon_send_event(SYSMON_SS_LPASS, "modem", code);
	if (ret < 0)
		pr_err("%s: sysmon_send_event error %d", __func__, ret);
	return NOTIFY_DONE;
}

static struct notifier_block mnb = {
	.notifier_call = modem_notifier_cb,
};

static void adsp_log_failure_reason(void)
{
	char *reason;
	char buffer[81];
	unsigned size;

	reason = smem_get_entry(SMEM_SSR_REASON_LPASS0, &size);

	if (!reason) {
		pr_err("ADSP subsystem failure reason: (unknown, smem_get_entry failed).");
		return;
	}

	if (reason[0] == '\0') {
		pr_err("ADSP subsystem failure reason: (unknown, init value found)");
		return;
	}

	size = min(size, sizeof(buffer) - 1);
	memcpy(buffer, reason, size);
	buffer[size] = '\0';
	pr_err("ADSP subsystem failure reason: %s", buffer);
	memset((void *)reason, 0x0, size);
	wmb();
}

static void restart_adsp(struct lpass_data *drv)
{
	adsp_log_failure_reason();
	subsystem_restart_dev(drv->subsys);
}

static void adsp_fatal_fn(struct work_struct *work)
{
	struct lpass_data *drv = container_of(work, struct lpass_data, work);

	pr_err("Watchdog bite received from ADSP!\n");
	restart_adsp(drv);
}

static irqreturn_t adsp_err_fatal_intr_handler (int irq, void *dev_id)
{
	struct lpass_data *drv = dev_id;

	/* Ignore if we're the one that set the force stop bit in the outbound
	 * entry
	 */
	if (drv->crash_shutdown)
		return IRQ_HANDLED;

	pr_err("Fatal error on the ADSP!\n");
	restart_adsp(drv);
	return IRQ_HANDLED;
}

#define SCM_Q6_NMI_CMD 0x1

static void send_q6_nmi(void)
{
	/* Send NMI to QDSP6 via an SCM call. */
	scm_call_atomic1(SCM_SVC_UTIL, SCM_Q6_NMI_CMD, 0x1);
	pr_debug("%s: Q6 NMI was sent.\n", __func__);
}

/*
 * The "status" file where a static variable is read from and written to.
 */
static ssize_t adsp_state_show(struct kobject *kobj,
			struct kobj_attribute *attr,
			char *buf)
{
	return snprintf(buf, sizeof(status), "%s\n", status);
}

static struct kobj_attribute adsp_state_attribute =
	__ATTR(status, 0444, adsp_state_show, NULL);

static struct attribute *attrs[] = {
	&adsp_state_attribute.attr,
	NULL,   /* need to NULL terminate the list of attributes */
};

static struct attribute_group attr_group = {
	.attrs = attrs,
};

static void adsp_set_state(char *state)
{
	strlcpy(status, state, sizeof(status));
	sysfs_notify(lpass_status, NULL, "status");
}

#define subsys_to_lpass(d) container_of(d, struct lpass_data, subsys_desc)

static int adsp_shutdown(const struct subsys_desc *subsys)
{
	struct lpass_data *drv = subsys_to_lpass(subsys);

	send_q6_nmi();
	/* The write needs to go through before the q6 is shutdown. */
	mb();
	pil_shutdown(&drv->q6->desc);
	disable_irq_nosync(drv->wdog_irq);

	pr_debug("ADSP is Down\n");
	adsp_set_state("OFFLINE");
	return 0;
}

static int adsp_powerup(const struct subsys_desc *subsys)
{
	struct lpass_data *drv = subsys_to_lpass(subsys);
	int ret = 0;
	ret = pil_boot(&drv->q6->desc);
	enable_irq(drv->wdog_irq);

	pr_debug("ADSP is back online\n");
	adsp_set_state("ONLINE");
	return ret;
}

static int adsp_ramdump(int enable, const struct subsys_desc *subsys)
{
	struct lpass_data *drv = subsys_to_lpass(subsys);

	if (!enable)
		return 0;

	return pil_do_ramdump(&drv->q6->desc, drv->ramdump_dev);
}

static void adsp_crash_shutdown(const struct subsys_desc *subsys)
{
	struct lpass_data *drv = subsys_to_lpass(subsys);

	drv->crash_shutdown = 1;
	gpio_set_value(drv->force_stop_gpio, 1);
	send_q6_nmi();
}

static irqreturn_t adsp_wdog_bite_irq(int irq, void *dev_id)
{
	struct lpass_data *drv = dev_id;

	disable_irq_nosync(drv->wdog_irq);
	schedule_work(&drv->work);

	return IRQ_HANDLED;
}

static int lpass_start(const struct subsys_desc *desc)
{
	struct lpass_data *drv = subsys_to_drv(desc);

	return pil_boot(&drv->q6->desc);
}

static void lpass_stop(const struct subsys_desc *desc)
{
	struct lpass_data *drv = subsys_to_drv(desc);
	pil_shutdown(&drv->q6->desc);
}

static int __devinit pil_lpass_driver_probe(struct platform_device *pdev)
{
	struct lpass_data *drv;
	struct q6v5_data *q6;
	struct pil_desc *desc;
	struct resource *res;
	int ret, gpio_clk_ready;

	drv = devm_kzalloc(&pdev->dev, sizeof(*drv), GFP_KERNEL);
	if (!drv)
		return -ENOMEM;
	platform_set_drvdata(pdev, drv);

	drv->wdog_irq = platform_get_irq(pdev, 0);
	if (drv->wdog_irq < 0)
		return drv->wdog_irq;

	ret = gpio_to_irq(of_get_named_gpio(pdev->dev.of_node,
					    "qcom,gpio-err-fatal", 0));
	if (ret < 0)
		return ret;
	drv->err_fatal_irq = ret;

	ret = gpio_to_irq(of_get_named_gpio(pdev->dev.of_node,
					    "qcom,gpio-proxy-unvote", 0));
	if (ret < 0)
		return ret;
	gpio_clk_ready = ret;

	drv->force_stop_gpio = of_get_named_gpio(pdev->dev.of_node,
						"qcom,gpio-force-stop", 0);
	if (drv->force_stop_gpio < 0)
		return drv->force_stop_gpio;

	q6 = pil_q6v5_init(pdev);
	if (IS_ERR(q6))
		return PTR_ERR(q6);
	drv->q6 = q6;

	desc = &q6->desc;
	desc->owner = THIS_MODULE;
	desc->proxy_timeout = PROXY_TIMEOUT_MS;
	desc->proxy_unvote_irq = gpio_clk_ready;

	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "restart_reg");
	q6->restart_reg = devm_request_and_ioremap(&pdev->dev, res);
	if (!q6->restart_reg)
		return -ENOMEM;

	q6->core_clk = devm_clk_get(&pdev->dev, "core_clk");
	if (IS_ERR(q6->core_clk))
		return PTR_ERR(q6->core_clk);

	q6->ahb_clk = devm_clk_get(&pdev->dev, "iface_clk");
	if (IS_ERR(q6->ahb_clk))
		return PTR_ERR(q6->ahb_clk);

	q6->axi_clk = devm_clk_get(&pdev->dev, "bus_clk");
	if (IS_ERR(q6->axi_clk))
		return PTR_ERR(q6->axi_clk);

	q6->reg_clk = devm_clk_get(&pdev->dev, "reg_clk");
	if (IS_ERR(q6->reg_clk))
		return PTR_ERR(q6->reg_clk);

	if (pas_supported(PAS_Q6) > 0) {
		desc->ops = &pil_lpass_ops_trusted;
		dev_info(&pdev->dev, "using secure boot\n");
	} else {
		desc->ops = &pil_lpass_ops;
		dev_info(&pdev->dev, "using non-secure boot\n");
	}

	ret = pil_desc_init(desc);
	if (ret)
		return ret;

	drv->subsys_desc.name = desc->name;
	drv->subsys_desc.owner = THIS_MODULE;
	drv->subsys_desc.dev = &pdev->dev;
	drv->subsys_desc.shutdown = adsp_shutdown;
	drv->subsys_desc.powerup = adsp_powerup;
	drv->subsys_desc.ramdump = adsp_ramdump;
	drv->subsys_desc.crash_shutdown = adsp_crash_shutdown;
	drv->subsys_desc.start = lpass_start;
	drv->subsys_desc.stop = lpass_stop;

	INIT_WORK(&drv->work, adsp_fatal_fn);

	drv->ramdump_dev = create_ramdump_device("adsp", &pdev->dev);
	if (!drv->ramdump_dev) {
		ret = -ENOMEM;
		goto err_ramdump;
	}

	drv->subsys = subsys_register(&drv->subsys_desc);
	if (IS_ERR(drv->subsys)) {
		ret = PTR_ERR(drv->subsys);
		goto err_subsys;
	}

	ret = devm_request_irq(&pdev->dev, drv->wdog_irq, adsp_wdog_bite_irq,
			IRQF_TRIGGER_RISING, dev_name(&pdev->dev), drv);
	if (ret)
		goto err_irq;

	ret = devm_request_irq(&pdev->dev, drv->err_fatal_irq,
				adsp_err_fatal_intr_handler,
				IRQF_TRIGGER_RISING,
				dev_name(&pdev->dev), drv);
	if (ret)
		goto err_irq;

	drv->wcnss_notif_hdle = subsys_notif_register_notifier("wcnss", &wnb);
	if (IS_ERR(drv->wcnss_notif_hdle)) {
		ret = PTR_ERR(drv->wcnss_notif_hdle);
		goto err_notif_wcnss;
	}

	drv->modem_notif_hdle = subsys_notif_register_notifier("modem", &mnb);
	if (IS_ERR(drv->modem_notif_hdle)) {
		ret = PTR_ERR(drv->modem_notif_hdle);
		goto err_notif_modem;
	}
	lpass_status = kobject_create_and_add("audio_voice_service",
						kernel_kobj);
	if (!lpass_status) {
		pr_err("%s: kobject create failed\n", __func__);
		ret = -ENOMEM;
		goto err_notif_modem;
	}

	ret = sysfs_create_group(lpass_status, &attr_group);
	if (ret) {
		pr_err("%s: sysfs create group failed\n", __func__);
		goto err_kobj;
	}

	adsp_set_state("ONLINE");
	return 0;
err_kobj:
	kobject_put(lpass_status);
err_notif_modem:
	subsys_notif_unregister_notifier(drv->wcnss_notif_hdle, &wnb);
err_notif_wcnss:
err_irq:
	subsys_unregister(drv->subsys);
err_subsys:
	destroy_ramdump_device(drv->ramdump_dev);
err_ramdump:
	pil_desc_release(desc);
	return ret;
}

static int __devexit pil_lpass_driver_exit(struct platform_device *pdev)
{
	struct lpass_data *drv = platform_get_drvdata(pdev);
	subsys_notif_unregister_notifier(drv->wcnss_notif_hdle, &wnb);
	subsys_notif_unregister_notifier(drv->modem_notif_hdle, &mnb);
	subsys_unregister(drv->subsys);
	destroy_ramdump_device(drv->ramdump_dev);
	pil_desc_release(&drv->q6->desc);
	sysfs_remove_group(lpass_status, &attr_group);
	kobject_del(lpass_status);
	return 0;
}

static struct of_device_id lpass_match_table[] = {
	{ .compatible = "qcom,pil-q6v5-lpass" },
	{}
};

static struct platform_driver pil_lpass_driver = {
	.probe = pil_lpass_driver_probe,
	.remove = __devexit_p(pil_lpass_driver_exit),
	.driver = {
		.name = "pil-q6v5-lpass",
		.of_match_table = lpass_match_table,
		.owner = THIS_MODULE,
	},
};

static int __init pil_lpass_init(void)
{
	return platform_driver_register(&pil_lpass_driver);
}
module_init(pil_lpass_init);

static void __exit pil_lpass_exit(void)
{
	platform_driver_unregister(&pil_lpass_driver);
}
module_exit(pil_lpass_exit);

MODULE_DESCRIPTION("Support for booting low-power audio subsystems with QDSP6v5 (Hexagon) processors");
MODULE_LICENSE("GPL v2");
