/*
 * Copyright (C) 2013 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;
};

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

#define	MAX_STATE	1

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)
{
	*state = 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(void)
{
	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);

	cool_dev = thermal_cooling_device_register(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);
