/* drivers/input/keyreset.c
 *
 * Copyright (C) 2014 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/input.h>
#include <linux/keyreset.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/reboot.h>
#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/syscalls.h>
#include <linux/keycombo.h>

struct keyreset_state {
	int restart_requested;
	int (*reset_fn)(void);
	struct platform_device *pdev_child;
	struct work_struct restart_work;
};

static void do_restart(struct work_struct *unused)
{
	orderly_reboot();
}

static void do_reset_fn(void *priv)
{
	struct keyreset_state *state = priv;
	if (state->restart_requested)
		panic("keyboard reset failed, %d", state->restart_requested);
	if (state->reset_fn) {
		state->restart_requested = state->reset_fn();
	} else {
		pr_info("keyboard reset\n");
		schedule_work(&state->restart_work);
		state->restart_requested = 1;
	}
}

static int keyreset_probe(struct platform_device *pdev)
{
	int ret = -ENOMEM;
	struct keycombo_platform_data *pdata_child;
	struct keyreset_platform_data *pdata = pdev->dev.platform_data;
	int up_size = 0, down_size = 0, size;
	int key, *keyp;
	struct keyreset_state *state;

	if (!pdata)
		return -EINVAL;
	state = devm_kzalloc(&pdev->dev, sizeof(*state), GFP_KERNEL);
	if (!state)
		return -ENOMEM;

	state->pdev_child = platform_device_alloc(KEYCOMBO_NAME,
							PLATFORM_DEVID_AUTO);
	if (!state->pdev_child)
		return -ENOMEM;
	state->pdev_child->dev.parent = &pdev->dev;
	INIT_WORK(&state->restart_work, do_restart);

	keyp = pdata->keys_down;
	while ((key = *keyp++)) {
		if (key >= KEY_MAX)
			continue;
		down_size++;
	}
	if (pdata->keys_up) {
		keyp = pdata->keys_up;
		while ((key = *keyp++)) {
			if (key >= KEY_MAX)
				continue;
			up_size++;
		}
	}
	size = sizeof(struct keycombo_platform_data)
			+ sizeof(int) * (down_size + 1);
	pdata_child = devm_kzalloc(&pdev->dev, size, GFP_KERNEL);
	if (!pdata_child)
		goto error;
	memcpy(pdata_child->keys_down, pdata->keys_down,
						sizeof(int) * down_size);
	if (up_size > 0) {
		pdata_child->keys_up = devm_kzalloc(&pdev->dev, up_size + 1,
								GFP_KERNEL);
		if (!pdata_child->keys_up)
			goto error;
		memcpy(pdata_child->keys_up, pdata->keys_up,
							sizeof(int) * up_size);
		if (!pdata_child->keys_up)
			goto error;
	}
	state->reset_fn = pdata->reset_fn;
	pdata_child->key_down_fn = do_reset_fn;
	pdata_child->priv = state;
	pdata_child->key_down_delay = pdata->key_down_delay;
	ret = platform_device_add_data(state->pdev_child, pdata_child, size);
	if (ret)
		goto error;
	platform_set_drvdata(pdev, state);
	return platform_device_add(state->pdev_child);
error:
	platform_device_put(state->pdev_child);
	return ret;
}

int keyreset_remove(struct platform_device *pdev)
{
	struct keyreset_state *state = platform_get_drvdata(pdev);
	platform_device_put(state->pdev_child);
	return 0;
}


struct platform_driver keyreset_driver = {
	.driver.name = KEYRESET_NAME,
	.probe = keyreset_probe,
	.remove = keyreset_remove,
};

static int __init keyreset_init(void)
{
	return platform_driver_register(&keyreset_driver);
}

static void __exit keyreset_exit(void)
{
	return platform_driver_unregister(&keyreset_driver);
}

module_init(keyreset_init);
module_exit(keyreset_exit);
