/*
 * SVC Greybus "watchdog" driver.
 *
 * Copyright 2016 Google Inc.
 *
 * Released under the GPLv2 only.
 */

#include <linux/delay.h>
#include <linux/suspend.h>
#include <linux/workqueue.h>
#include "greybus.h"

#define SVC_WATCHDOG_PERIOD	(2 * HZ)

struct gb_svc_watchdog {
	struct delayed_work	work;
	struct gb_svc		*svc;
	bool			enabled;
	struct notifier_block pm_notifier;
};

static struct delayed_work reset_work;

static int svc_watchdog_pm_notifier(struct notifier_block *notifier,
				    unsigned long pm_event, void *unused)
{
	struct gb_svc_watchdog *watchdog =
		container_of(notifier, struct gb_svc_watchdog, pm_notifier);

	switch (pm_event) {
	case PM_SUSPEND_PREPARE:
		gb_svc_watchdog_disable(watchdog->svc);
		break;
	case PM_POST_SUSPEND:
		gb_svc_watchdog_enable(watchdog->svc);
		break;
	default:
		break;
	}

	return NOTIFY_DONE;
}

static void greybus_reset(struct work_struct *work)
{
	static char const start_path[] = "/system/bin/start";
	static char *envp[] = {
		"HOME=/",
		"PATH=/sbin:/vendor/bin:/system/sbin:/system/bin:/system/xbin",
		NULL,
	};
	static char *argv[] = {
		(char *)start_path,
		"unipro_reset",
		NULL,
	};

	pr_err("svc_watchdog: calling \"%s %s\" to reset greybus network!\n",
	       argv[0], argv[1]);
	call_usermodehelper(start_path, argv, envp, UMH_WAIT_EXEC);
}

static void do_work(struct work_struct *work)
{
	struct gb_svc_watchdog *watchdog;
	struct gb_svc *svc;
	int retval;

	watchdog = container_of(work, struct gb_svc_watchdog, work.work);
	svc = watchdog->svc;

	dev_dbg(&svc->dev, "%s: ping.\n", __func__);
	retval = gb_svc_ping(svc);
	if (retval) {
		/*
		 * Something went really wrong, let's warn userspace and then
		 * pull the plug and reset the whole greybus network.
		 * We need to do this outside of this workqueue as we will be
		 * tearing down the svc device itself.  So queue up
		 * yet-another-callback to do that.
		 */
		dev_err(&svc->dev,
			"SVC ping has returned %d, something is wrong!!!\n",
			retval);

		if (svc->action == GB_SVC_WATCHDOG_BITE_PANIC_KERNEL) {
			panic("SVC is not responding\n");
		} else if (svc->action == GB_SVC_WATCHDOG_BITE_RESET_UNIPRO) {
			dev_err(&svc->dev, "Resetting the greybus network, watch out!!!\n");

			INIT_DELAYED_WORK(&reset_work, greybus_reset);
			schedule_delayed_work(&reset_work, HZ / 2);

			/*
			 * Disable ourselves, we don't want to trip again unless
			 * userspace wants us to.
			 */
			watchdog->enabled = false;
		}
	}

	/* resubmit our work to happen again, if we are still "alive" */
	if (watchdog->enabled)
		schedule_delayed_work(&watchdog->work, SVC_WATCHDOG_PERIOD);
}

int gb_svc_watchdog_create(struct gb_svc *svc)
{
	struct gb_svc_watchdog *watchdog;
	int retval;

	if (svc->watchdog)
		return 0;

	watchdog = kmalloc(sizeof(*watchdog), GFP_KERNEL);
	if (!watchdog)
		return -ENOMEM;

	watchdog->enabled = false;
	watchdog->svc = svc;
	INIT_DELAYED_WORK(&watchdog->work, do_work);
	svc->watchdog = watchdog;

	watchdog->pm_notifier.notifier_call = svc_watchdog_pm_notifier;
	retval = register_pm_notifier(&watchdog->pm_notifier);
	if (retval) {
		dev_err(&svc->dev, "error registering pm notifier(%d)\n",
			retval);
		goto svc_watchdog_create_err;
	}

	retval = gb_svc_watchdog_enable(svc);
	if (retval) {
		dev_err(&svc->dev, "error enabling watchdog (%d)\n", retval);
		unregister_pm_notifier(&watchdog->pm_notifier);
		goto svc_watchdog_create_err;
	}
	return retval;

svc_watchdog_create_err:
	svc->watchdog = NULL;
	kfree(watchdog);

	return retval;
}

void gb_svc_watchdog_destroy(struct gb_svc *svc)
{
	struct gb_svc_watchdog *watchdog = svc->watchdog;

	if (!watchdog)
		return;

	unregister_pm_notifier(&watchdog->pm_notifier);
	gb_svc_watchdog_disable(svc);
	svc->watchdog = NULL;
	kfree(watchdog);
}

bool gb_svc_watchdog_enabled(struct gb_svc *svc)
{
	if (!svc || !svc->watchdog)
		return false;
	return svc->watchdog->enabled;
}

int gb_svc_watchdog_enable(struct gb_svc *svc)
{
	struct gb_svc_watchdog *watchdog;

	if (!svc->watchdog)
		return -ENODEV;

	watchdog = svc->watchdog;
	if (watchdog->enabled)
		return 0;

	watchdog->enabled = true;
	schedule_delayed_work(&watchdog->work, SVC_WATCHDOG_PERIOD);
	return 0;
}

int gb_svc_watchdog_disable(struct gb_svc *svc)
{
	struct gb_svc_watchdog *watchdog;

	if (!svc->watchdog)
		return -ENODEV;

	watchdog = svc->watchdog;
	if (!watchdog->enabled)
		return 0;

	watchdog->enabled = false;
	cancel_delayed_work_sync(&watchdog->work);
	return 0;
}
