/*
 * Copyright (C) 2013-2015 Freescale Semiconductor, Inc.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 *
 */

#include <linux/module.h>
#include <linux/thermal.h>
#include <linux/err.h>
#include <linux/slab.h>

struct devfreq_cooling_device {
	int id;
	struct thermal_cooling_device *cool_dev;
	unsigned int devfreq_state;
	unsigned int max_state;
};

static DEFINE_IDR(devfreq_idr);
static DEFINE_MUTEX(devfreq_cooling_lock);

static BLOCKING_NOTIFIER_HEAD(devfreq_cooling_chain_head);

int register_devfreq_cooling_notifier(struct notifier_block *nb)
{
	return blocking_notifier_chain_register(
		&devfreq_cooling_chain_head, nb);
}
EXPORT_SYMBOL_GPL(register_devfreq_cooling_notifier);

int unregister_devfreq_cooling_notifier(struct notifier_block *nb)
{
	return blocking_notifier_chain_unregister(
		&devfreq_cooling_chain_head, nb);
}
EXPORT_SYMBOL_GPL(unregister_devfreq_cooling_notifier);

static int devfreq_cooling_notifier_call_chain(unsigned long val)
{
	return (blocking_notifier_call_chain(
		&devfreq_cooling_chain_head, val, NULL)
		== NOTIFY_BAD) ? -EINVAL : 0;
}

static int devfreq_set_cur_state(struct thermal_cooling_device *cdev,
				 unsigned long state)
{
	struct devfreq_cooling_device *devfreq_device = cdev->devdata;
	int ret;

	ret = devfreq_cooling_notifier_call_chain(state);
	if (ret)
		return -EINVAL;
	devfreq_device->devfreq_state = state;

	return 0;
}

static int devfreq_get_max_state(struct thermal_cooling_device *cdev,
				 unsigned long *state)
{
	struct devfreq_cooling_device *devfreq_device = cdev->devdata;
	*state = devfreq_device->max_state;

	return 0;
}

static int devfreq_get_cur_state(struct thermal_cooling_device *cdev,
				 unsigned long *state)
{
	struct devfreq_cooling_device *devfreq_device = cdev->devdata;

	*state = devfreq_device->devfreq_state;

	return 0;
}

static struct thermal_cooling_device_ops const devfreq_cooling_ops = {
	.get_max_state = devfreq_get_max_state,
	.get_cur_state = devfreq_get_cur_state,
	.set_cur_state = devfreq_set_cur_state,
};

static int get_idr(struct idr *idr, int *id)
{
	int ret;

	mutex_lock(&devfreq_cooling_lock);
	ret = idr_alloc(idr, NULL, 0, 0, GFP_KERNEL);
	mutex_unlock(&devfreq_cooling_lock);
	if (unlikely(ret < 0))
		return ret;
	*id = ret;

	return 0;
}

static void release_idr(struct idr *idr, int id)
{
	mutex_lock(&devfreq_cooling_lock);
	idr_remove(idr, id);
	mutex_unlock(&devfreq_cooling_lock);
}

struct thermal_cooling_device *devfreq_cooling_register(struct device_node *np,
							unsigned long states)
{
	struct thermal_cooling_device *cool_dev;
	struct devfreq_cooling_device *devfreq_dev = NULL;
	char dev_name[THERMAL_NAME_LENGTH];
	int ret = 0;

	devfreq_dev = kzalloc(sizeof(struct devfreq_cooling_device),
			      GFP_KERNEL);
	if (!devfreq_dev)
		return ERR_PTR(-ENOMEM);

	ret = get_idr(&devfreq_idr, &devfreq_dev->id);
	if (ret) {
		kfree(devfreq_dev);
		return ERR_PTR(-EINVAL);
	}

	snprintf(dev_name, sizeof(dev_name), "thermal-devfreq-%d",
		 devfreq_dev->id);
	devfreq_dev->max_state = states;

	cool_dev = thermal_of_cooling_device_register(np, dev_name,
						   devfreq_dev,
						   &devfreq_cooling_ops);
	if (!cool_dev) {
		release_idr(&devfreq_idr, devfreq_dev->id);
		kfree(devfreq_dev);
		return ERR_PTR(-EINVAL);
	}
	devfreq_dev->cool_dev = cool_dev;
	devfreq_dev->devfreq_state = 0;

	return cool_dev;
}
EXPORT_SYMBOL_GPL(devfreq_cooling_register);

void devfreq_cooling_unregister(struct thermal_cooling_device *cdev)
{
	struct devfreq_cooling_device *devfreq_dev = cdev->devdata;

	thermal_cooling_device_unregister(devfreq_dev->cool_dev);
	release_idr(&devfreq_idr, devfreq_dev->id);
	kfree(devfreq_dev);
}
EXPORT_SYMBOL_GPL(devfreq_cooling_unregister);
