/*
 * GPIO Reset Controller driver
 *
 * Copyright 2013 Philipp Zabel, Pengutronix
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 */
#include <linux/delay.h>
#include <linux/err.h>
#include <linux/gpio.h>
#include <linux/module.h>
#include <linux/of_gpio.h>
#include <linux/platform_device.h>
#include <linux/reset-controller.h>

struct gpio_reset_data {
	struct reset_controller_dev rcdev;
	unsigned int gpio;
	bool active_low;
	s32 delay_us;
	s32 post_delay_ms;
};

static void gpio_reset_set(struct reset_controller_dev *rcdev, int asserted)
{
	struct gpio_reset_data *drvdata = container_of(rcdev,
			struct gpio_reset_data, rcdev);
	int value = asserted;

	if (drvdata->active_low)
		value = !value;

	gpio_set_value_cansleep(drvdata->gpio, value);
}

static int gpio_reset(struct reset_controller_dev *rcdev, unsigned long id)
{
	struct gpio_reset_data *drvdata = container_of(rcdev,
			struct gpio_reset_data, rcdev);

	if (drvdata->delay_us < 0)
		return -ENOSYS;

	gpio_reset_set(rcdev, 1);
	udelay(drvdata->delay_us);
	gpio_reset_set(rcdev, 0);

	if (drvdata->post_delay_ms < 0)
		return 0;

	msleep(drvdata->post_delay_ms);
	return 0;
}

static int gpio_reset_assert(struct reset_controller_dev *rcdev,
		unsigned long id)
{
	gpio_reset_set(rcdev, 1);

	return 0;
}

static int gpio_reset_deassert(struct reset_controller_dev *rcdev,
		unsigned long id)
{
	gpio_reset_set(rcdev, 0);

	return 0;
}

static struct reset_control_ops gpio_reset_ops = {
	.reset = gpio_reset,
	.assert = gpio_reset_assert,
	.deassert = gpio_reset_deassert,
};

static int of_gpio_reset_xlate(struct reset_controller_dev *rcdev,
			       const struct of_phandle_args *reset_spec)
{
	if (WARN_ON(reset_spec->args_count != 0))
		return -EINVAL;

	return 0;
}

static int gpio_reset_probe(struct platform_device *pdev)
{
	struct device_node *np = pdev->dev.of_node;
	struct gpio_reset_data *drvdata;
	enum of_gpio_flags flags;
	unsigned long gpio_flags;
	bool initially_in_reset;
	int ret;

	drvdata = devm_kzalloc(&pdev->dev, sizeof(*drvdata), GFP_KERNEL);
	if (drvdata == NULL)
		return -ENOMEM;

	if (of_gpio_named_count(np, "reset-gpios") != 1) {
		dev_err(&pdev->dev,
			"reset-gpios property missing, or not a single gpio\n");
		return -EINVAL;
	}

	drvdata->gpio = of_get_named_gpio_flags(np, "reset-gpios", 0, &flags);
	if (drvdata->gpio == -EPROBE_DEFER) {
		return drvdata->gpio;
	} else if (!gpio_is_valid(drvdata->gpio)) {
		dev_err(&pdev->dev, "invalid reset gpio: %d\n", drvdata->gpio);
		return drvdata->gpio;
	}

	drvdata->active_low = flags & OF_GPIO_ACTIVE_LOW;

	ret = of_property_read_u32(np, "reset-delay-us", &drvdata->delay_us);
	if (ret < 0)
		drvdata->delay_us = -1;
	else if (drvdata->delay_us < 0)
		dev_warn(&pdev->dev, "reset delay too high\n");

	/* It is optional.
	 * Some devices need some milliseconds to wait after reset.
	 */
	ret = of_property_read_u32(np, "reset-post-delay-ms", &drvdata->post_delay_ms);
	if (ret < 0)
		drvdata->post_delay_ms = -1;

	initially_in_reset = of_property_read_bool(np, "initially-in-reset");
	if (drvdata->active_low ^ initially_in_reset)
		gpio_flags = GPIOF_OUT_INIT_HIGH;
	else
		gpio_flags = GPIOF_OUT_INIT_LOW;

	ret = devm_gpio_request_one(&pdev->dev, drvdata->gpio, gpio_flags, NULL);
	if (ret < 0) {
		dev_err(&pdev->dev, "failed to request gpio %d: %d\n",
			drvdata->gpio, ret);
		return ret;
	}

	platform_set_drvdata(pdev, drvdata);

	drvdata->rcdev.of_node = np;
	drvdata->rcdev.owner = THIS_MODULE;
	drvdata->rcdev.nr_resets = 1;
	drvdata->rcdev.ops = &gpio_reset_ops;
	drvdata->rcdev.of_xlate = of_gpio_reset_xlate;
	reset_controller_register(&drvdata->rcdev);

	return 0;
}

static int gpio_reset_remove(struct platform_device *pdev)
{
	struct gpio_reset_data *drvdata = platform_get_drvdata(pdev);

	reset_controller_unregister(&drvdata->rcdev);

	return 0;
}

static struct of_device_id gpio_reset_dt_ids[] = {
	{ .compatible = "gpio-reset" },
	{ }
};

#ifdef CONFIG_PM_SLEEP
static int gpio_reset_suspend(struct device *dev)
{
	pinctrl_pm_select_sleep_state(dev);

	return 0;
}
static int gpio_reset_resume(struct device *dev)
{
	pinctrl_pm_select_default_state(dev);

	return 0;
}
#endif

static const struct dev_pm_ops gpio_reset_pm_ops = {
	SET_LATE_SYSTEM_SLEEP_PM_OPS(gpio_reset_suspend, gpio_reset_resume)
};

static struct platform_driver gpio_reset_driver = {
	.probe = gpio_reset_probe,
	.remove = gpio_reset_remove,
	.driver = {
		.name = "gpio-reset",
		.owner = THIS_MODULE,
		.of_match_table = of_match_ptr(gpio_reset_dt_ids),
		.pm = &gpio_reset_pm_ops,
	},
};

static int __init gpio_reset_init(void)
{
	return platform_driver_register(&gpio_reset_driver);
}
arch_initcall(gpio_reset_init);

static void __exit gpio_reset_exit(void)
{
	platform_driver_unregister(&gpio_reset_driver);
}
module_exit(gpio_reset_exit);

MODULE_AUTHOR("Philipp Zabel <p.zabel@pengutronix.de>");
MODULE_DESCRIPTION("gpio reset controller");
MODULE_LICENSE("GPL");
MODULE_ALIAS("platform:gpio-reset");
MODULE_DEVICE_TABLE(of, gpio_reset_dt_ids);
