/*
 * Copyright (c) 2018 Samsung Electronics Co., Ltd.
 *		http://www.samsung.com/
 *
 * HAFM-TB(AFM with HIU TB) support
 * Auther : PARK CHOONGHOON (choong.park@samsung.com)
 * 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/cpumask.h>
#include <linux/regmap.h>
#include <linux/of_irq.h>
#include <linux/of.h>
#include <linux/slab.h>
#include <linux/platform_device.h>
#include <linux/io.h>
#include <linux/kthread.h>
#include <linux/delay.h>

#include "exynos-hiu.h"
#include "../../cpufreq/exynos-ff.h"
#include "../../cpufreq/exynos-acme.h"

static struct exynos_hiu_data *data;

static void hiu_stats_create_table(struct cpufreq_policy *policy);

#define POLL_PERIOD 100

/****************************************************************/
/*			HIU HELPER FUNCTION			*/
/****************************************************************/
static unsigned int hiu_get_freq_level(unsigned int freq)
{
	int level;
	struct hiu_stats *stats = data->stats;

	if (unlikely(!stats))
		return 0;

	for (level = 0; level < stats->last_level; level++)
		if (stats->freq_table[level] == freq)
			return level + data->level_offset;

	return -EINVAL;
}

static unsigned int hiu_get_power_budget(unsigned int freq)
{
	return data->sw_pbl;
}

static void hiu_update_reg(int offset, int mask, int shift, unsigned int val)
{
	unsigned int reg_val;

	reg_val = __raw_readl(data->base + offset);
	reg_val &= ~(mask << shift);
	reg_val |= val << shift;
	__raw_writel(reg_val, data->base + offset);
}

static unsigned int hiu_read_reg(int offset, int mask, int shift)
{
	unsigned int reg_val;

	reg_val = __raw_readl(data->base + offset);
	return (reg_val >> shift) & mask;
}

static unsigned int hiu_get_act_dvfs(void)
{
	return hiu_read_reg(HIUTOPCTL1, ACTDVFS_MASK, ACTDVFS_SHIFT);
}

static void hiu_control_err_interrupts(int enable)
{
	if (enable)
		hiu_update_reg(HIUTOPCTL1, ENB_ERR_INTERRUPTS_MASK, 0, ENB_ERR_INTERRUPTS_MASK);
	else
		hiu_update_reg(HIUTOPCTL1, ENB_ERR_INTERRUPTS_MASK, 0, 0);
}

static void hiu_control_mailbox(int enable)
{
	hiu_update_reg(HIUTOPCTL1, ENB_SR1INTR_MASK, ENB_SR1INTR_SHIFT, !!enable);
	hiu_update_reg(HIUTOPCTL1, ENB_ACPM_COMM_MASK, ENB_ACPM_COMM_SHIFT, !!enable);
}

static void hiu_set_limit_dvfs(unsigned int freq)
{
	unsigned int level;

	level = hiu_get_freq_level(freq);

	hiu_update_reg(HIUTOPCTL2, LIMITDVFS_MASK, LIMITDVFS_SHIFT, level);
}

static void hiu_set_tb_dvfs(unsigned int freq)
{
	unsigned int level;

	level = hiu_get_freq_level(freq);

	hiu_update_reg(HIUTBCTL, TBDVFS_MASK, TBDVFS_SHIFT, level);
}

static void hiu_control_tb(int enable)
{
	hiu_update_reg(HIUTBCTL, TB_ENB_MASK, TB_ENB_SHIFT, !!enable);
}

static void hiu_control_pc(int enable)
{
	hiu_update_reg(HIUTBCTL, PC_DISABLE_MASK, PC_DISABLE_SHIFT, !enable);
}

static void hiu_set_boost_level_inc(void)
{
	unsigned int inc;
	struct device_node *dn = data->dn;

	if (!of_property_read_u32(dn, "bl1-inc", &inc))
		hiu_update_reg(HIUTBCTL, B1_INC_MASK, B1_INC_SHIFT, inc);
	if (!of_property_read_u32(dn, "bl2-inc", &inc))
		hiu_update_reg(HIUTBCTL, B2_INC_MASK, B2_INC_SHIFT, inc);
	if (!of_property_read_u32(dn, "bl3-inc", &inc))
		hiu_update_reg(HIUTBCTL, B3_INC_MASK, B3_INC_SHIFT, inc);
}

static void hiu_set_tb_ps_cfg_each(int index, unsigned int cfg_val)
{
	int offset;

	offset = HIUTBPSCFG_BASE + index * HIUTBPSCFG_OFFSET;
	hiu_update_reg(offset, HIUTBPSCFG_MASK, 0, cfg_val);
}

static int hiu_set_tb_ps_cfg(void)
{
	int size, index;
	unsigned int val;
	struct hiu_cfg *table;
	struct device_node *dn = data->dn;

	size = of_property_count_u32_elems(dn, "config-table");
	if (size < 0)
		return size;

	table = kzalloc(sizeof(struct hiu_cfg) * size / 4, GFP_KERNEL);
	if (!table)
		return -ENOMEM;

	of_property_read_u32_array(dn, "config-table", (unsigned int *)table, size);

	for (index = 0; index < size / 4; index++) {
		val = 0;
		val |= table[index].power_borrowed << PB_SHIFT;
		val |= table[index].boost_level << BL_SHIFT;
		val |= table[index].power_budget_limit << PBL_SHIFT;
		val |= table[index].power_threshold_inc << TBPWRTHRESH_INC_SHIFT;

		hiu_set_tb_ps_cfg_each(index, val);
	}

	kfree(table);

	return 0;
}

static bool check_hiu_sr1_irq_pending(void)
{
	return !!hiu_read_reg(HIUTOPCTL1, HIU_MBOX_RESPONSE_MASK, SR1INTR_SHIFT);
}

static void clear_hiu_sr1_irq_pending(void)
{
	hiu_update_reg(HIUTOPCTL1, HIU_MBOX_RESPONSE_MASK, SR1INTR_SHIFT, 0);
}

static bool check_hiu_mailbox_err_pending(void)
{
	return !!hiu_read_reg(HIUTOPCTL1, HIU_MBOX_ERR_MASK, HIU_MBOX_ERR_SHIFT);
}

static unsigned int get_hiu_mailbox_err(void)
{
	return hiu_read_reg(HIUTOPCTL1, HIU_MBOX_ERR_MASK, HIU_MBOX_ERR_SHIFT);
}

static void hiu_mailbox_err_handler(void)
{
	unsigned int err, val;

	err = get_hiu_mailbox_err();

	if (err & SR1UXPERR_MASK)
		pr_err("exynos-hiu: unexpected error occurs\n");

	if (err & SR1SNERR_MASK) {
		val = __raw_readl(data->base + HIUTOPCTL2);
		val = (val >> SEQNUM_SHIFT) & SEQNUM_MASK;
		pr_err("exynos-hiu: erroneous sequence num %d\n", val);
	}

	if (err & SR1TIMEOUT_MASK)
		pr_err("exynos-hiu: TIMEOUT on SR1 write\n");

	if (err & SR0RDERR_MASK)
		pr_err("exynos-hiu: SR0 read twice or more\n");
}

static bool check_hiu_req_freq_updated(unsigned int req_freq)
{
	unsigned int cur_level, cur_freq;

	cur_level = hiu_get_act_dvfs();
	cur_freq = data->stats->freq_table[cur_level - data->level_offset];

	/*
	 * If req_freq == boost_threshold, HIU could request turbo boost
	 * That's why in case of req_freq == boost_threshold,
	 * requested frequency update is consdered as done,
	 * if act_dvfs is larger than or equal to boost threshold
	 */
	if (req_freq == data->boost_threshold)
		return cur_freq >= data->boost_threshold;

	return cur_freq == req_freq;
}

static bool check_hiu_normal_req_done(unsigned int req_freq)
{
	return check_hiu_sr1_irq_pending() &&
		check_hiu_req_freq_updated(req_freq);
}

static bool check_hiu_need_register_restore(void)
{
	return !hiu_read_reg(HIUTOPCTL1, ENB_SR1INTR_MASK, ENB_SR1INTR_SHIFT);
}

static int request_dvfs_on_sr0(unsigned int req_freq)
{
	unsigned int val, level, budget;

	/* Get dvfs level */
	level = hiu_get_freq_level(req_freq);
	if (level < 0)
		return -EINVAL;

	/* Get power budget */
	budget = hiu_get_power_budget(req_freq);
	if (budget < 0)
		return -EINVAL;

	/* write REQDVFS & REQPBL to HIU SFR */
	val = __raw_readl(data->base + HIUTOPCTL2);
	val &= ~(REQDVFS_MASK << REQDVFS_SHIFT | REQPBL_MASK << REQPBL_SHIFT);
	val |= (level << REQDVFS_SHIFT | budget << REQPBL_SHIFT);
	__raw_writel(val, data->base + HIUTOPCTL2);

	return 0;
}

/****************************************************************/
/*			     HIU API				*/
/****************************************************************/
static int hiu_sr1_check_loop(void *unused);
static void __exynos_hiu_update_data(struct cpufreq_policy *policy);

int exynos_hiu_set_freq(unsigned int id, unsigned int req_freq)
{
	bool need_update_cur_freq = true;

	if (unlikely(!data))
		return -ENODEV;

	if (!data->enabled)
		return -ENODEV;

	pr_debug("exynos-hiu: update data->cur_freq:%d\n", data->cur_freq);

	mutex_lock(&data->lock);

	if (check_hiu_need_register_restore())
		__exynos_hiu_update_data(NULL);

	/* PM QoS could make req_freq bigger than boost_threshold */
	if (req_freq >= data->boost_threshold){
		/*
		 * 1) If turbo boost is already activated
		 *    just update cur_freq and return.
		 * 2) If not, req_freq should be boost_threshold;
		 *    DO NOT allow req_freq to be bigger than boost_threshold.
		 */
		if (data->cur_freq >= data->boost_threshold) {
			data->cur_freq = req_freq;
			mutex_unlock(&data->lock);
			return 0;
		}
		else {
			data->cur_freq = req_freq;
			req_freq = data->boost_threshold;
			need_update_cur_freq = false;
		}
	}

	/* Write req_freq on SR0 to request DVFS */
	request_dvfs_on_sr0(req_freq);

	if (data->operation_mode == POLLING_MODE) {
		while (!check_hiu_normal_req_done(req_freq) &&
			!check_hiu_mailbox_err_pending())
			usleep_range(POLL_PERIOD, 2 * POLL_PERIOD);

		if (check_hiu_mailbox_err_pending()) {
			hiu_mailbox_err_handler();
			BUG_ON(1);
		}

		if (need_update_cur_freq)
			data->cur_freq = req_freq;
		clear_hiu_sr1_irq_pending();

		if (req_freq == data->boost_threshold && !data->boosting_activated) {
			data->boosting_activated = true;
			wake_up(&data->polling_wait);
		}
	}

	mutex_unlock(&data->lock);

	pr_debug("exynos-hiu: set REQDVFS to HIU : %ukHz\n", req_freq);

	return 0;
}

int exynos_hiu_get_freq(unsigned int id)
{
	if (unlikely(!data))
		return -ENODEV;

	return data->cur_freq;
}

int exynos_hiu_get_max_freq(void)
{
	if (unlikely(!data))
		return -1;

	return data->clipped_freq;
}

unsigned int exynos_pstate_get_boost_freq(int cpu)
{
	if (!cpumask_test_cpu(cpu, &data->cpus))
		return 0;

	return data->boost_max;
}

/****************************************************************/
/*			HIU SR1 WRITE HANDLER			*/
/****************************************************************/
static void exynos_hiu_work(struct work_struct *work)
{
	unsigned int boost_freq, level;
	struct cpufreq_policy *policy;
	struct hiu_stats *stats = data->stats;
	struct cpumask *mask;

	level = hiu_get_act_dvfs();
	boost_freq = stats->freq_table[level - data->level_offset];

	/*
	 * Only when TB bit is set, this work callback is called.
	 * However, while this callback is waiting to start,
	 * well... turbo boost could be released.
	 * So, acting frequency coulde be lower than turbo boost threshold.
	 * This condition code is for treating that case.
	 */
	if (boost_freq < data->boost_threshold)
		goto done;

	policy = cpufreq_cpu_get(cpumask_first(cpu_coregroup_mask(0)));
	if (!policy) {
		pr_debug("Failed to get CPUFreq policy in HIU work\n");
		goto done;
	}

	__cpufreq_driver_target(policy, boost_freq,
                                CPUFREQ_RELATION_H | CPUFREQ_HW_DVFS_REQ);

	cpufreq_cpu_put(policy);
done:
	data->hwidvfs_done = true;
	wake_up(&data->hwidvfs_wait);
}

static irqreturn_t exynos_hiu_irq_handler(int irq, void *id)
{
	schedule_work_on(data->cpu, &data->work);

	return IRQ_HANDLED;
}

static bool hiu_need_hw_request(void)
{
       unsigned int cur_level, cur_freq;

       cur_level = hiu_get_act_dvfs();
       cur_freq = data->stats->freq_table[cur_level - data->level_offset];

       return cur_freq >= data->boost_threshold;
}

static int hiu_sr1_check_loop(void *unused)
{
wait:
	wait_event(data->polling_wait, data->boosting_activated);
poll:
	mutex_lock(&data->lock);

	if (data->cur_freq < data->boost_threshold)
		goto done;

	while (!check_hiu_sr1_irq_pending() &&
		!check_hiu_mailbox_err_pending()) {
		mutex_unlock(&data->lock);
		usleep_range(POLL_PERIOD, 2 * POLL_PERIOD);
		mutex_lock(&data->lock);

		if (data->cur_freq < data->boost_threshold)
			goto done;
	}

	if (check_hiu_mailbox_err_pending()) {
		hiu_mailbox_err_handler();
		BUG_ON(1);
	}

	if (hiu_need_hw_request()) {
		schedule_work_on(cpumask_first(cpu_coregroup_mask(0)), &data->work);
		clear_hiu_sr1_irq_pending();
		mutex_unlock(&data->lock);

		wait_event(data->hwidvfs_wait, data->hwidvfs_done);
		data->hwidvfs_done = false;

		goto poll;
	}

done:
	data->boosting_activated = false;
	mutex_unlock(&data->lock);
	goto wait;

	/* NEVER come here */

	return 0;
}

/****************************************************************/
/*			EXTERNAL EVENT HANDLER			*/
/****************************************************************/
static void __exynos_hiu_update_data(struct cpufreq_policy *policy)
{
	/* Explicitly disable the whole HW */
	/*	ex) hiu_control_pc, tb(0), hiu_control_mailbox(0) */

	/* Set dvfs limit and TB threshold */
	hiu_set_limit_dvfs(data->clipped_freq);
	hiu_set_tb_dvfs(data->boost_threshold);

	/* Initialize TB level offset */
	hiu_set_boost_level_inc();

	/* Initialize TB power state config */
	hiu_set_tb_ps_cfg();

	/* Enable TB */
	hiu_control_pc(data->pc_enabled);
	hiu_control_tb(data->tb_enabled);

	/* Enable error interrupts */
	hiu_control_err_interrupts(1);
	/* Enable mailbox communication with ACPM */
	hiu_control_mailbox(1);
}

static int exynos_hiu_update_data(struct cpufreq_policy *policy)
{
	if (!cpumask_test_cpu(data->cpu, policy->cpus))
		return 0;

	data->clipped_freq = data->boost_max;
	hiu_stats_create_table(policy);

	__exynos_hiu_update_data(policy);

	data->enabled = true;

	pr_info("exynos-hiu: HIU data structure update complete\n");

	return 0;
}

static struct exynos_cpufreq_ready_block exynos_hiu_ready = {
	.update = exynos_hiu_update_data,
};

static bool check_hiu_need_boost_thrott(void)
{
	return data->cur_freq > data->boost_threshold &&
		data->cur_freq > data->clipped_freq;
}

static int exynos_hiu_policy_callback(struct notifier_block *nb,
				unsigned long event, void *info)
{
	struct cpufreq_policy *policy = info;

	if (policy->cpu != data->cpu)
		return NOTIFY_DONE;

	if (policy->max == data->clipped_freq)
		return NOTIFY_DONE;

	switch (event) {
	case CPUFREQ_NOTIFY:

		/* Note : MUST write LIMIT_DVFS to HIU SFR */
		mutex_lock(&data->lock);
		if (policy->max >= data->boost_threshold) {
			data->clipped_freq = policy->max;
			hiu_set_limit_dvfs(data->clipped_freq);
		}
		mutex_unlock(&data->lock);

		pr_debug("exynos-hiu: update clipped freq:%d\n", data->clipped_freq);
		if (check_hiu_need_boost_thrott())
			atomic_inc(&boost_throttling);
		break;
	default:
		;
	}

	return NOTIFY_OK;
}

static struct notifier_block exynos_hiu_policy_notifier = {
	.notifier_call = exynos_hiu_policy_callback,
};

static int exynos_hiu_transition_callback(struct notifier_block *nb,
				unsigned long event, void *info)
{
	struct cpufreq_freqs *freq = info;
	int cpu = freq->cpu;

	if (cpu != data->cpu)
		return NOTIFY_DONE;

	if (event != CPUFREQ_POSTCHANGE)
		return NOTIFY_DONE;

	if (atomic_read(&boost_throttling) &&
	    data->cur_freq <= data->clipped_freq) {
		atomic_dec(&boost_throttling);
	}

	return NOTIFY_OK;
}

static struct notifier_block exynos_hiu_transition_notifier = {
	.notifier_call = exynos_hiu_transition_callback,
	.priority = INT_MIN,
};

/****************************************************************/
/*			SYSFS INTERFACE				*/
/****************************************************************/
static ssize_t
hiu_enable_show(struct device *dev, struct device_attribute *devattr,
		       char *buf)
{
	return snprintf(buf, PAGE_SIZE, "%d\n", data->enabled);
}

static ssize_t
hiu_enable_store(struct device *dev, struct device_attribute *devattr,
			const char *buf, size_t count)
{
	unsigned int input;

	if (kstrtos32(buf, 10, &input))
		return -EINVAL;

	return count;
}

static ssize_t
hiu_boosted_show(struct device *dev, struct device_attribute *devattr,
		       char *buf)
{
	unsigned int boosted = hiu_read_reg(HIUTBCTL, BOOSTED_MASK, BOOSTED_SHIFT);

	return snprintf(buf, PAGE_SIZE, "%d\n", boosted);
}

static ssize_t
hiu_boost_threshold_show(struct device *dev, struct device_attribute *devattr,
		       char *buf)
{
	return snprintf(buf, PAGE_SIZE, "%d\n", data->boost_threshold);
}

static ssize_t
hiu_dvfs_limit_show(struct device *dev, struct device_attribute *devattr,
		       char *buf)
{
	unsigned int dvfs_limit = hiu_read_reg(HIUTOPCTL2, LIMITDVFS_MASK, LIMITDVFS_SHIFT);

	return snprintf(buf, PAGE_SIZE, "%d\n", dvfs_limit);
}

static ssize_t
hiu_dvfs_limit_store(struct device *dev, struct device_attribute *devattr,
			const char *buf, size_t count)
{
	unsigned int input;

	if (kstrtos32(buf, 10, &input))
		return -EINVAL;

	hiu_update_reg(HIUTOPCTL2, LIMITDVFS_MASK, LIMITDVFS_SHIFT, input);

	return count;
}

static DEVICE_ATTR(enabled, 0644, hiu_enable_show, hiu_enable_store);
static DEVICE_ATTR(boosted, 0444, hiu_boosted_show, NULL);
static DEVICE_ATTR(boost_threshold, 0444, hiu_boost_threshold_show, NULL);
static DEVICE_ATTR(dvfs_limit, 0644, hiu_dvfs_limit_show, hiu_dvfs_limit_store);

static struct attribute *exynos_hiu_attrs[] = {
	&dev_attr_enabled.attr,
	&dev_attr_boosted.attr,
	&dev_attr_boost_threshold.attr,
	&dev_attr_dvfs_limit.attr,
	NULL,
};

static struct attribute_group exynos_hiu_attr_group = {
	.name = "hiu",
	.attrs = exynos_hiu_attrs,
};

/****************************************************************/
/*		INITIALIZE EXYNOS HIU DRIVER			*/
/****************************************************************/
static int hiu_dt_parsing(struct device_node *dn)
{
	const char *buf;
	int ret = 0;

	ret |= of_property_read_u32(dn, "operation-mode", &data->operation_mode);
	ret |= of_property_read_u32(dn, "boot-freq", &data->cur_freq);
	ret |= of_property_read_u32(dn, "boost-threshold", &data->boost_threshold);
	ret |= of_property_read_u32(dn, "boost-max", &data->boost_max);
	ret |= of_property_read_u32(dn, "sw-pbl", &data->sw_pbl);
	ret |= of_property_read_string(dn, "sibling-cpus", &buf);
	if (ret)
		return ret;

	if (of_property_read_bool(dn, "pc-enabled"))
		data->pc_enabled = true;

	if (of_property_read_bool(dn, "tb-enabled"))
		data->tb_enabled = true;

	cpulist_parse(buf, &data->cpus);
	cpumask_and(&data->cpus, &data->cpus, cpu_possible_mask);
	if (cpumask_weight(&data->cpus) == 0)
		return -ENODEV;

	data->cpu = cpumask_first(&data->cpus);

	return 0;
}

static void hiu_stats_create_table(struct cpufreq_policy *policy)
{
	unsigned int i = 0, count = 0, alloc_size;
	struct hiu_stats *stats;
	struct cpufreq_frequency_table *pos, *table;

	table = policy->freq_table;
	if (unlikely(!table))
		return;

	stats = kzalloc(sizeof(*stats), GFP_KERNEL);
	if (!stats)
		return;

	cpufreq_for_each_valid_entry(pos, table)
		count++;

	alloc_size = count * (sizeof(unsigned int) + sizeof(u64));

	stats->freq_table = kzalloc(alloc_size, GFP_KERNEL);
	if (!stats->freq_table)
		goto free_stat;

	stats->time_in_state = (unsigned long long *)(stats->freq_table + count);

	stats->last_level = count;

	cpufreq_for_each_valid_entry(pos, table)
		stats->freq_table[i++] = pos->frequency;

	data->stats = stats;

	cpufreq_for_each_valid_entry(pos, table) {
		data->level_offset = pos->driver_data;
		break;
	}

	return;
free_stat:
	kfree(stats);
}

static int exynos_hiu_probe(struct platform_device *pdev)
{
	struct task_struct *polling_thread;
	struct device_node *dn = pdev->dev.of_node;
	int ret;

	data = kzalloc(sizeof(struct exynos_hiu_data), GFP_KERNEL);
	if (!data)
		return -ENOMEM;

	mutex_init(&data->lock);

	platform_set_drvdata(pdev, data);

	data->base = ioremap(GCU_BASE, SZ_4K);

	ret = hiu_dt_parsing(dn);
	if (ret) {
		dev_err(&pdev->dev, "Failed to parse HIU data\n");
		return -ENODEV;
	}

	data->dn = dn;

	if (data->operation_mode == INTERRUPT_MODE) {
		data->irq = irq_of_parse_and_map(dn, 0);
		if (data->irq <= 0) {
			dev_err(&pdev->dev, "Failed to get IRQ\n");
			return -ENODEV;
		}

		ret = devm_request_irq(&pdev->dev, data->irq, exynos_hiu_irq_handler,
				IRQF_TRIGGER_RISING, dev_name(&pdev->dev), data);
		if (ret) {
			dev_err(&pdev->dev, "Failed to request IRQ handler: %d\n", data->irq);
			return -ENODEV;
		}
	} else {
		init_waitqueue_head(&data->polling_wait);
		data->boosting_activated = false;

		polling_thread = kthread_create(hiu_sr1_check_loop, NULL, "hiu_polling");
		kthread_bind_mask(polling_thread, cpu_coregroup_mask(0));
		wake_up_process(polling_thread);
	}

	cpufreq_register_notifier(&exynos_hiu_policy_notifier, CPUFREQ_POLICY_NOTIFIER);
	cpufreq_register_notifier(&exynos_hiu_transition_notifier, CPUFREQ_TRANSITION_NOTIFIER);

	INIT_WORK(&data->work, exynos_hiu_work);
	init_waitqueue_head(&data->hwidvfs_wait);

	ret = sysfs_create_group(&pdev->dev.kobj, &exynos_hiu_attr_group);
	if (ret)
		dev_err(&pdev->dev, "Failed to create Exynos HIU attr group");

	exynos_cpufreq_ready_list_add(&exynos_hiu_ready);

	dev_info(&pdev->dev, "HIU Handler initialization complete\n");
	return 0;
}

static int exynos_hiu_suspend(struct platform_device *pdev, pm_message_t state)
{
	/* HACK : disable turbo boost */
	return 0;
}

static int exynos_hiu_resume(struct platform_device *pdev)
{
	/* HACK : enable turbo boost */
	return 0;
}

static const struct of_device_id of_exynos_hiu_match[] = {
	{ .compatible = "samsung,exynos-hiu", },
	{ },
};

static const struct platform_device_id exynos_hiu_ids[] = {
	{ "exynos-hiu", },
	{ }
};

static struct platform_driver exynos_hiu_driver = {
	.driver = {
		.name = "exynos-hiu",
		.owner = THIS_MODULE,
		.of_match_table = of_exynos_hiu_match,
	},
	.probe		= exynos_hiu_probe,
	.suspend	= exynos_hiu_suspend,
	.resume		= exynos_hiu_resume,
	.id_table	= exynos_hiu_ids,
};

int __init exynos_hiu_init(void)
{
	return platform_driver_register(&exynos_hiu_driver);
}
arch_initcall(exynos_hiu_init);
