/*
 * otg-wakelock.c
 *
 * Copyright (C) 2011 Google, Inc.
 *
 * This software is licensed under the terms of the GNU General Public
 * License version 2, as published by the Free Software Foundation, and
 * may be copied, distributed, and modified under those terms.
 *
 * 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/device.h>
#include <linux/module.h>
#include <linux/notifier.h>
#include <linux/wakelock.h>
#include <linux/spinlock.h>
#include <linux/usb/otg.h>

#define TEMPORARY_HOLD_TIME	2000

static bool enabled = true;
static struct otg_transceiver *otgwl_xceiv;
static struct notifier_block otgwl_nb;

/*
 * otgwl_spinlock is held while the VBUS lock is grabbed or dropped and the
 * held field is updated to match.
 */

static DEFINE_SPINLOCK(otgwl_spinlock);

/*
 * Only one lock, but since these 3 fields are associated with each other...
 */

struct otgwl_lock {
	char name[40];
	struct wake_lock wakelock;
	bool held;
};

/*
 * VBUS present lock.  Also used as a timed lock on charger
 * connect/disconnect and USB host disconnect, to allow the system
 * to react to the change in power.
 */

static struct otgwl_lock vbus_lock;

static void otgwl_hold(struct otgwl_lock *lock)
{
	if (!lock->held) {
		wake_lock(&lock->wakelock);
		lock->held = true;
	}
}

static void otgwl_temporary_hold(struct otgwl_lock *lock)
{
	wake_lock_timeout(&lock->wakelock,
			  msecs_to_jiffies(TEMPORARY_HOLD_TIME));
	lock->held = false;
}

static void otgwl_drop(struct otgwl_lock *lock)
{
	if (lock->held) {
		wake_unlock(&lock->wakelock);
		lock->held = false;
	}
}

static void otgwl_handle_event(unsigned long event)
{
	unsigned long irqflags;

	spin_lock_irqsave(&otgwl_spinlock, irqflags);

	if (!enabled) {
		otgwl_drop(&vbus_lock);
		spin_unlock_irqrestore(&otgwl_spinlock, irqflags);
		return;
	}

	switch (event) {
	case USB_EVENT_VBUS:
	case USB_EVENT_ENUMERATED:
		otgwl_hold(&vbus_lock);
		break;

	case USB_EVENT_NONE:
	case USB_EVENT_ID:
	case USB_EVENT_CHARGER:
		otgwl_temporary_hold(&vbus_lock);
		break;

	default:
		break;
	}

	spin_unlock_irqrestore(&otgwl_spinlock, irqflags);
}

static int otgwl_otg_notifications(struct notifier_block *nb,
				   unsigned long event, void *unused)
{
	otgwl_handle_event(event);
	return NOTIFY_OK;
}

static int set_enabled(const char *val, const struct kernel_param *kp)
{
	int rv = param_set_bool(val, kp);

	if (rv)
		return rv;

	if (otgwl_xceiv)
		otgwl_handle_event(otgwl_xceiv->last_event);

	return 0;
}

static struct kernel_param_ops enabled_param_ops = {
	.set = set_enabled,
	.get = param_get_bool,
};

module_param_cb(enabled, &enabled_param_ops, &enabled, 0644);
MODULE_PARM_DESC(enabled, "enable wakelock when VBUS present");

static int __init otg_wakelock_init(void)
{
	int ret;

	otgwl_xceiv = otg_get_transceiver();

	if (!otgwl_xceiv) {
		pr_err("%s: No OTG transceiver found\n", __func__);
		return -ENODEV;
	}

	snprintf(vbus_lock.name, sizeof(vbus_lock.name), "vbus-%s",
		 dev_name(otgwl_xceiv->dev));
	wake_lock_init(&vbus_lock.wakelock, WAKE_LOCK_SUSPEND,
		       vbus_lock.name);

	otgwl_nb.notifier_call = otgwl_otg_notifications;
	ret = otg_register_notifier(otgwl_xceiv, &otgwl_nb);

	if (ret) {
		pr_err("%s: otg_register_notifier on transceiver %s"
		       " failed\n", __func__,
		       dev_name(otgwl_xceiv->dev));
		otgwl_xceiv = NULL;
		wake_lock_destroy(&vbus_lock.wakelock);
		return ret;
	}

	otgwl_handle_event(otgwl_xceiv->last_event);
	return ret;
}

late_initcall(otg_wakelock_init);
