/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
 * only version 2 as published by the Free Software Foundation.
 *
 * 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.
 */
#define pr_fmt(fmt)	KBUILD_MODNAME ": " fmt

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/string.h>
#include <linux/iommu.h>
#include <linux/slab.h>
#include <linux/device.h>
#include <linux/interrupt.h>
#include <linux/bitops.h>
#include <linux/debugfs.h>
#include <mach/iommu.h>
#include <mach/iommu_perfmon.h>

static LIST_HEAD(iommu_list);
static struct dentry *msm_iommu_root_debugfs_dir;
static const char *NO_EVENT_CLASS_NAME = "none";
static const unsigned int MAX_EVEN_CLASS_NAME_LEN = 36;

struct event_class {
	unsigned int event_number;
	const char *desc;
};

static struct event_class pmu_event_classes[] = {
	{ 0x00, "cycle_count"      },
	{ 0x01, "cycle_count64"    },
	{ 0x08, "tlb_refill"       },
	{ 0x09, "tlb_refill_read"  },
	{ 0x0A, "tlb_refill_write" },
	{ 0x10, "access"           },
	{ 0x11, "access_read"      },
	{ 0x12, "access_write"     },
	{ 0x80, "full_misses"      },
	{ 0x81, "partial_miss_1lbfb_hit" },
	{ 0x82, "partial_miss_2lbfb_hit" },
	{ 0x83, "full_hit" },
	{ 0x90, "pred_req_full_miss" },
	{ 0x91, "pred_req_partial_miss_1lbfb_hit" },
	{ 0x92, "pred_req_partial_miss_2lbfb_hit" },
	{ 0xb0, "tot_num_miss_axi_htw_read_req" },
	{ 0xb1, "tot_num_pred_axi_htw_read_req" },
};

static unsigned int iommu_pm_create_sup_cls_str(char **buf,
						struct iommu_pmon *pmon)
{
	unsigned long buf_size = ARRAY_SIZE(pmu_event_classes) *
				 MAX_EVEN_CLASS_NAME_LEN;
	unsigned int pos = 0;
	unsigned int nevent_cls = pmon->nevent_cls_supported;

	*buf = kzalloc(buf_size, GFP_KERNEL);
	if (*buf) {
		unsigned int j;
		int i;
		struct event_class *ptr;
		size_t array_len = ARRAY_SIZE(pmu_event_classes);
		ptr = pmu_event_classes;

		for (j = 0; j < nevent_cls; ++j) {
			for (i = 0; i < array_len; ++i) {

				if (ptr[i].event_number !=
						pmon->event_cls_supported[j])
					continue;

				if (pos < buf_size) {
					pos += snprintf(&(*buf)[pos],
							buf_size-pos,
							"[%u] %s\n",
							ptr[i].event_number,
							ptr[i].desc);
				}
				break;
			}
		}
	}
	return pos;
}

static int iommu_pm_event_class_supported(struct iommu_pmon *pmon,
					  int event_class)
{
	unsigned int nevent_cls = pmon->nevent_cls_supported;
	unsigned int i;

	for (i = 0; i < nevent_cls; ++i) {
		if (event_class == pmon->event_cls_supported[i])
			return event_class;
	}
	return MSM_IOMMU_PMU_NO_EVENT_CLASS;
}

static const char *iommu_pm_find_event_class_name(int event_class)
{
	size_t array_len;
	struct event_class *ptr;
	int i;
	const char *event_class_name = NO_EVENT_CLASS_NAME;
	if (event_class < 0)
		goto out;

	array_len = ARRAY_SIZE(pmu_event_classes);
	ptr = pmu_event_classes;

	for (i = 0; i < array_len; ++i) {
		if (ptr[i].event_number == event_class) {
			event_class_name =  ptr[i].desc;
			break;
		}
	}

out:
	return event_class_name;
}

static int iommu_pm_find_event_class(struct iommu_pmon *pmon,
				     const char *event_class_name)
{
	size_t array_len;
	struct event_class *ptr;
	int i;
	int event_class = MSM_IOMMU_PMU_NO_EVENT_CLASS;

	if (strcmp(event_class_name, NO_EVENT_CLASS_NAME) == 0)
		goto out;

	array_len = ARRAY_SIZE(pmu_event_classes);
	ptr = pmu_event_classes;

	for (i = 0; i < array_len; ++i) {
		if (strcmp(ptr[i].desc, event_class_name) == 0) {
			event_class =  ptr[i].event_number;
			goto out;
		}
	}

out:
	event_class = iommu_pm_event_class_supported(pmon, event_class);
	return event_class;
}

static inline void iommu_pm_add_to_iommu_list(struct iommu_pmon *iommu_pmon)
{
	list_add(&iommu_pmon->iommu_list, &iommu_list);
}

static inline void iommu_pm_del_from_iommu_list(struct iommu_pmon *iommu_pmon)
{
	list_del(&iommu_pmon->iommu_list);
}

static struct iommu_pmon *iommu_pm_get_pm_by_dev(struct device *dev)
{
	struct iommu_pmon *pmon;
	struct iommu_info *info;
	struct list_head *ent;
	list_for_each(ent, &iommu_list) {
		pmon = list_entry(ent, struct iommu_pmon, iommu_list);
		info = &pmon->iommu;
		if (dev == info->iommu_dev)
			return pmon;
	}
	return NULL;
}

static void iommu_pm_set_event_type(struct iommu_pmon *pmon,
				    struct iommu_pmon_counter *counter)
{
	int event_class;
	unsigned int count_no;
	struct iommu_info *iommu = &pmon->iommu;

	event_class = counter->current_event_class;
	count_no = counter->absolute_counter_no;

	if (event_class == MSM_IOMMU_PMU_NO_EVENT_CLASS) {
		if (iommu->hw_ops->is_hw_access_OK(pmon)) {
			iommu->ops->iommu_lock_acquire(1);
			iommu->hw_ops->counter_disable(iommu, counter);
			iommu->hw_ops->ovfl_int_disable(iommu, counter);
			iommu->hw_ops->set_event_class(pmon, count_no, 0);
			iommu->ops->iommu_lock_release(1);
		}
		counter->overflow_count = 0;
		counter->value = 0;
	} else {
		counter->overflow_count = 0;
		counter->value = 0;
		if (iommu->hw_ops->is_hw_access_OK(pmon)) {
			iommu->ops->iommu_lock_acquire(1);
			iommu->hw_ops->set_event_class(pmon, count_no,
					event_class);
			iommu->hw_ops->ovfl_int_enable(iommu, counter);
			iommu->hw_ops->counter_enable(iommu, counter);
			iommu->ops->iommu_lock_release(1);
		}
	}
}

static void iommu_pm_reset_counts(struct iommu_pmon *pmon)
{
	unsigned int i;
	unsigned int j;
	for (i = 0; i < pmon->num_groups; ++i) {
		struct iommu_pmon_cnt_group *cnt_grp = &pmon->cnt_grp[i];
		for (j = 0; j < cnt_grp->num_counters; ++j) {
			cnt_grp->counters[j].value = 0;
			cnt_grp->counters[j].overflow_count = 0;
		}
	}
}

static void iommu_pm_set_all_counters(struct iommu_pmon *pmon)
{
	unsigned int i;
	unsigned int j;
	for (i = 0; i < pmon->num_groups; ++i) {
		struct iommu_pmon_cnt_group *cnt_grp = &pmon->cnt_grp[i];
		for (j = 0; j < cnt_grp->num_counters; ++j)
			iommu_pm_set_event_type(pmon, &cnt_grp->counters[j]);
	}
}

static void iommu_pm_read_all_counters(struct iommu_pmon *pmon)
{
	unsigned int i;
	unsigned int j;
	struct iommu_info *iommu = &pmon->iommu;
	for (i = 0; i < pmon->num_groups; ++i) {
		struct iommu_pmon_cnt_group *cnt_grp = &pmon->cnt_grp[i];
		for (j = 0; j < cnt_grp->num_counters; ++j) {
			struct iommu_pmon_counter *counter;
			counter = &cnt_grp->counters[j];
			counter->value = iommu->hw_ops->read_counter(counter);
		}
	}
}

static void iommu_pm_on(struct iommu_pmon *pmon)
{
	unsigned int i;
	struct iommu_info *iommu = &pmon->iommu;
	struct msm_iommu_drvdata *iommu_drvdata =
					dev_get_drvdata(iommu->iommu_dev);

	iommu->ops->iommu_power_on(iommu_drvdata);
	iommu->ops->iommu_bus_vote(iommu_drvdata, 1);
	iommu->ops->iommu_clk_on(iommu_drvdata);

	/* Reset counters in HW */
	iommu->ops->iommu_lock_acquire(1);
	iommu->hw_ops->reset_counters(&pmon->iommu);
	iommu->ops->iommu_lock_release(1);

	/* Reset SW counters */
	iommu_pm_reset_counts(pmon);

	pmon->enabled = 1;

	iommu_pm_set_all_counters(pmon);

	iommu->ops->iommu_lock_acquire(1);

	/* enable all counter group */
	for (i = 0; i < pmon->num_groups; ++i)
		iommu->hw_ops->grp_enable(iommu, i);

	/* enable global counters */
	iommu->hw_ops->enable_pm(iommu);
	iommu->ops->iommu_lock_release(1);

	pr_info("%s: TLB performance monitoring turned ON\n",
		pmon->iommu.iommu_name);
}

static void iommu_pm_off(struct iommu_pmon *pmon)
{
	unsigned int i;
	struct iommu_info *iommu = &pmon->iommu;
	struct msm_iommu_drvdata *iommu_drvdata =
					dev_get_drvdata(iommu->iommu_dev);

	pmon->enabled = 0;

	iommu->ops->iommu_lock_acquire(1);

	/* disable global counters */
	iommu->hw_ops->disable_pm(iommu);

	/* Check if we overflowed just before turning off pmon */
	iommu->hw_ops->check_for_overflow(pmon);

	/* disable all counter group */
	for (i = 0; i < pmon->num_groups; ++i)
		iommu->hw_ops->grp_disable(iommu, i);

	/* Update cached copy of counters before turning off power */
	iommu_pm_read_all_counters(pmon);

	iommu->ops->iommu_lock_release(1);
	iommu->ops->iommu_clk_off(iommu_drvdata);
	iommu->ops->iommu_bus_vote(iommu_drvdata, 0);
	iommu->ops->iommu_power_off(iommu_drvdata);

	pr_info("%s: TLB performance monitoring turned OFF\n",
		pmon->iommu.iommu_name);
}

static int iommu_pm_debug_open(struct inode *inode, struct file *file)
{
	file->private_data = inode->i_private;
	return 0;
}

static ssize_t iommu_pm_count_value_read(struct file *fp,
					 char __user *user_buff,
					 size_t count, loff_t *pos)
{
	size_t rd_cnt;
	unsigned long long full_count;

	struct iommu_pmon_counter *counter = fp->private_data;
	struct iommu_pmon *pmon = counter->cnt_group->pmon;
	struct iommu_info *iommu = &pmon->iommu;
	char buf[50];
	size_t len;

	mutex_lock(&pmon->lock);

	if (iommu->hw_ops->is_hw_access_OK(pmon)) {
		iommu->ops->iommu_lock_acquire(1);
		counter->value = iommu->hw_ops->read_counter(counter);
		iommu->ops->iommu_lock_release(1);
	}
	full_count = (unsigned long long) counter->value +
		     ((unsigned long long)counter->overflow_count *
			0x100000000ULL);

	len = snprintf(buf, 50, "%llu\n", full_count);
	rd_cnt = simple_read_from_buffer(user_buff, count, pos, buf, len);
	mutex_unlock(&pmon->lock);

	return rd_cnt;
}

static const struct file_operations cnt_value_file_ops = {
	.open = iommu_pm_debug_open,
	.read = iommu_pm_count_value_read,
};

static ssize_t iommu_pm_event_class_read(struct file *fp,
					 char __user *user_buff,
					 size_t count, loff_t *pos)
{
	size_t rd_cnt;
	struct iommu_pmon_counter *counter = fp->private_data;
	struct iommu_pmon *pmon = counter->cnt_group->pmon;
	char buf[50];
	const char *event_class_name;
	size_t len;

	mutex_lock(&pmon->lock);
	event_class_name = iommu_pm_find_event_class_name(
						counter->current_event_class);
	len = snprintf(buf, 50, "%s\n", event_class_name);

	rd_cnt = simple_read_from_buffer(user_buff, count, pos, buf, len);
	mutex_unlock(&pmon->lock);
	return rd_cnt;
}

static ssize_t iommu_pm_event_class_write(struct file *fp,
					  const char __user *user_buff,
					  size_t count, loff_t *pos)
{
	size_t wr_cnt;
	char buf[50];
	size_t buf_size = sizeof(buf);
	struct iommu_pmon_counter *counter = fp->private_data;
	struct iommu_pmon *pmon = counter->cnt_group->pmon;
	int current_event_class;

	if ((count + *pos) >= buf_size)
		return -EINVAL;

	mutex_lock(&pmon->lock);
	current_event_class = counter->current_event_class;
	wr_cnt = simple_write_to_buffer(buf, buf_size, pos, user_buff, count);
	if (wr_cnt >= 1) {
		int rv;
		long value;
		buf[wr_cnt-1] = '\0';
		rv = kstrtol(buf, 10, &value);
		if (!rv) {
			counter->current_event_class =
				iommu_pm_find_event_class(pmon,
					iommu_pm_find_event_class_name(value));
		} else {
			counter->current_event_class =
					iommu_pm_find_event_class(pmon, buf);
	}	}

	if (current_event_class != counter->current_event_class)
		iommu_pm_set_event_type(pmon, counter);

	mutex_unlock(&pmon->lock);
	return wr_cnt;
}

static const struct file_operations event_class_file_ops = {
	.open = iommu_pm_debug_open,
	.read = iommu_pm_event_class_read,
	.write = iommu_pm_event_class_write,
};

static ssize_t iommu_reset_counters_write(struct file *fp,
				    const char __user *user_buff,
				    size_t count, loff_t *pos)
{
	size_t wr_cnt;
	char buf[10];
	size_t buf_size = sizeof(buf);
	struct iommu_pmon *pmon = fp->private_data;
	struct iommu_info *iommu = &pmon->iommu;

	if ((count + *pos) >= buf_size)
		return -EINVAL;

	mutex_lock(&pmon->lock);
	wr_cnt = simple_write_to_buffer(buf, buf_size, pos, user_buff, count);
	if (wr_cnt >= 1) {
		unsigned long cmd = 0;
		int rv;
		buf[wr_cnt-1] = '\0';
		rv = kstrtoul(buf, 10, &cmd);
		if (!rv && (cmd == 1)) {
			if (iommu->hw_ops->is_hw_access_OK(pmon)) {
				iommu->ops->iommu_lock_acquire(1);
				iommu->hw_ops->reset_counters(&pmon->iommu);
				iommu->ops->iommu_lock_release(1);
			}
			iommu_pm_reset_counts(pmon);
			pr_info("TLB performance counters reset\n");
		} else {
			pr_err("Unknown performance monitor command: %lu\n",
				cmd);
		}
	}
	mutex_unlock(&pmon->lock);
	return wr_cnt;
}

static const struct file_operations reset_file_ops = {
	.open = iommu_pm_debug_open,
	.write = iommu_reset_counters_write,
};

static ssize_t iommu_pm_enable_counters_read(struct file *fp,
					     char __user *user_buff,
					     size_t count, loff_t *pos)
{
	size_t rd_cnt;
	char buf[5];
	size_t len;
	struct iommu_pmon *pmon = fp->private_data;

	mutex_lock(&pmon->lock);
	len = snprintf(buf, 5, "%u\n", pmon->enabled);
	rd_cnt = simple_read_from_buffer(user_buff, count, pos, buf, len);
	mutex_unlock(&pmon->lock);
	return rd_cnt;
}

static ssize_t iommu_pm_enable_counters_write(struct file *fp,
				     const char __user *user_buff,
				     size_t count, loff_t *pos)
{
	size_t wr_cnt;
	char buf[10];
	size_t buf_size = sizeof(buf);
	struct iommu_pmon *pmon = fp->private_data;

	if ((count + *pos) >= buf_size)
		return -EINVAL;

	mutex_lock(&pmon->lock);
	wr_cnt = simple_write_to_buffer(buf, buf_size, pos, user_buff, count);
	if (wr_cnt >= 1) {
		unsigned long cmd;
		int rv;
		buf[wr_cnt-1] = '\0';
		rv = kstrtoul(buf, 10, &cmd);
		if (!rv && (cmd < 2)) {
			if (pmon->enabled == 1 && cmd == 0) {
				if (pmon->iommu.always_on ||
				    pmon->iommu_attach_count > 0)
					iommu_pm_off(pmon);
			} else if (pmon->enabled == 0 && cmd == 1) {
				/* We can only turn on perf. monitoring if
				 * iommu is attached (if not always on).
				 * Delay turning on perf. monitoring until
				 * we are attached.
				 */
				if (pmon->iommu.always_on ||
				    pmon->iommu_attach_count > 0)
					iommu_pm_on(pmon);
				else
					pmon->enabled = 1;
			}
		} else {
			pr_err("Unknown performance monitor command: %lu\n",
				cmd);
		}
	}
	mutex_unlock(&pmon->lock);
	return wr_cnt;
}

static const struct file_operations event_enable_file_ops = {
	.open = iommu_pm_debug_open,
	.read = iommu_pm_enable_counters_read,
	.write = iommu_pm_enable_counters_write,
};

static ssize_t iommu_pm_avail_event_cls_read(struct file *fp,
					     char __user *user_buff,
					     size_t count, loff_t *pos)
{
	size_t rd_cnt = 0;
	struct iommu_pmon *pmon = fp->private_data;
	char *buf;
	size_t len;

	mutex_lock(&pmon->lock);

	len = iommu_pm_create_sup_cls_str(&buf, pmon);
	if (buf) {
		rd_cnt = simple_read_from_buffer(user_buff, count, pos,
						 buf, len);
		kfree(buf);
	}
	mutex_unlock(&pmon->lock);
	return rd_cnt;
}

static const struct file_operations available_event_cls_file_ops = {
	.open = iommu_pm_debug_open,
	.read = iommu_pm_avail_event_cls_read,
};



static int iommu_pm_create_grp_debugfs_counters_hierarchy(
					struct iommu_pmon_cnt_group *cnt_grp,
					unsigned int *abs_counter_no)
{
	int ret = 0;
	int j;
	char name[20];

	for (j = 0; j < cnt_grp->num_counters; ++j) {
		struct dentry *grp_dir = cnt_grp->group_dir;
		struct dentry *counter_dir;
		cnt_grp->counters[j].cnt_group = cnt_grp;
		cnt_grp->counters[j].counter_no = j;
		cnt_grp->counters[j].absolute_counter_no = *abs_counter_no;
		(*abs_counter_no)++;
		cnt_grp->counters[j].value = 0;
		cnt_grp->counters[j].overflow_count = 0;
		cnt_grp->counters[j].current_event_class =
						MSM_IOMMU_PMU_NO_EVENT_CLASS;

		snprintf(name, 20, "counter%u", j);

		counter_dir = debugfs_create_dir(name, grp_dir);

		if (IS_ERR_OR_NULL(counter_dir)) {
			pr_err("unable to create counter debugfs dir %s\n",
				name);
			ret = -ENOMEM;
			goto out;
		}

		cnt_grp->counters[j].counter_dir = counter_dir;

		if (!debugfs_create_file("value", 0644, counter_dir,
					 &cnt_grp->counters[j],
					 &cnt_value_file_ops)) {
			ret = -EIO;
			goto out;
		}

		if (!debugfs_create_file("current_event_class", 0644,
				counter_dir, &cnt_grp->counters[j],
				&event_class_file_ops)) {
			ret = -EIO;
			goto out;
		}
	}
out:
	return ret;
}

static int iommu_pm_create_group_debugfs_hierarchy(struct iommu_info *iommu,
				   struct iommu_pmon *pmon_entry)
{
	int i;
	int ret = 0;
	char name[20];
	unsigned int abs_counter_no = 0;

	for (i = 0; i < pmon_entry->num_groups; ++i) {
		pmon_entry->cnt_grp[i].pmon = pmon_entry;
		pmon_entry->cnt_grp[i].grp_no = i;
		pmon_entry->cnt_grp[i].num_counters = pmon_entry->num_counters;
		pmon_entry->cnt_grp[i].counters =
			kzalloc(sizeof(*pmon_entry->cnt_grp[i].counters)
			* pmon_entry->cnt_grp[i].num_counters, GFP_KERNEL);

		if (!pmon_entry->cnt_grp[i].counters) {
			pr_err("Unable to allocate memory for counters\n");
			ret = -ENOMEM;
			goto out;
		}
		snprintf(name, 20, "group%u", i);
		pmon_entry->cnt_grp[i].group_dir = debugfs_create_dir(name,
							pmon_entry->iommu_dir);
		if (IS_ERR_OR_NULL(pmon_entry->cnt_grp[i].group_dir)) {
			pr_err("unable to create group debugfs dir %s\n", name);
			ret = -ENOMEM;
			goto out;
		}

		ret = iommu_pm_create_grp_debugfs_counters_hierarchy(
						&pmon_entry->cnt_grp[i],
						&abs_counter_no);
		if (ret)
			goto out;
	}
out:
	return ret;
}

int msm_iommu_pm_iommu_register(struct iommu_pmon *pmon_entry)
{
	int ret = 0;
	struct iommu_info *iommu = &pmon_entry->iommu;
	int i;

	if (!iommu->ops || !iommu->iommu_name || !iommu->base
					|| !iommu->iommu_dev) {
		ret = -EINVAL;
		goto out;
	}

	if (!msm_iommu_root_debugfs_dir) {
		msm_iommu_root_debugfs_dir = debugfs_create_dir("iommu", NULL);
		if (IS_ERR_OR_NULL(msm_iommu_root_debugfs_dir)) {
			pr_err("Failed creating iommu debugfs dir \"iommu\"\n");
			ret = -EIO;
			goto out;
		}
	}

	pmon_entry->cnt_grp = kzalloc(sizeof(*pmon_entry->cnt_grp)
				      * pmon_entry->num_groups, GFP_KERNEL);
	if (!pmon_entry->cnt_grp) {
		pr_err("Unable to allocate memory for counter groups\n");
		ret = -ENOMEM;
		goto file_err;
	}
	pmon_entry->iommu_dir = debugfs_create_dir(iommu->iommu_name,
						   msm_iommu_root_debugfs_dir);
	if (IS_ERR_OR_NULL(pmon_entry->iommu_dir)) {
		pr_err("unable to create iommu debugfs dir %s\n",
							iommu->iommu_name);
		ret = -ENOMEM;
		goto free_mem;
	}

	if (!debugfs_create_file("reset_counters", 0644,
			pmon_entry->iommu_dir, pmon_entry, &reset_file_ops)) {
		ret = -EIO;
		goto free_mem;
	}

	if (!debugfs_create_file("enable_counters", 0644,
		pmon_entry->iommu_dir, pmon_entry, &event_enable_file_ops)) {
		ret = -EIO;
		goto free_mem;
	}

	if (!debugfs_create_file("available_event_classes", 0644,
			pmon_entry->iommu_dir, pmon_entry,
			&available_event_cls_file_ops)) {
		ret = -EIO;
		goto free_mem;
	}

	ret = iommu_pm_create_group_debugfs_hierarchy(iommu, pmon_entry);
	if (ret)
		goto free_mem;

	iommu->hw_ops->initialize_hw(pmon_entry);

	if (iommu->evt_irq > 0) {
		ret = request_threaded_irq(iommu->evt_irq, NULL,
				iommu->hw_ops->evt_ovfl_int_handler,
				IRQF_ONESHOT | IRQF_SHARED,
				"msm_iommu_pmon_nonsecure_irq", pmon_entry);
		if (ret) {
			pr_err("Request IRQ %d failed with ret=%d\n",
								iommu->evt_irq,
								ret);
			goto free_mem;
		}
	} else {
		pr_info("%s: Overflow interrupt not available\n", __func__);
	}

	dev_dbg(iommu->iommu_dev, "%s iommu registered\n", iommu->iommu_name);

	goto out;
free_mem:
	if (pmon_entry->cnt_grp) {
		for (i = 0; i < pmon_entry->num_groups; ++i) {
			kfree(pmon_entry->cnt_grp[i].counters);
			pmon_entry->cnt_grp[i].counters = 0;
		}
	}
	kfree(pmon_entry->cnt_grp);
	pmon_entry->cnt_grp = 0;
file_err:
	debugfs_remove_recursive(msm_iommu_root_debugfs_dir);
out:
	return ret;
}
EXPORT_SYMBOL(msm_iommu_pm_iommu_register);

void msm_iommu_pm_iommu_unregister(struct device *dev)
{
	int i;
	struct iommu_pmon *pmon_entry = iommu_pm_get_pm_by_dev(dev);

	if (!pmon_entry)
		return;

	free_irq(pmon_entry->iommu.evt_irq, pmon_entry->iommu.iommu_dev);

	if (!pmon_entry)
		goto remove_debugfs;

	if (pmon_entry->cnt_grp) {
		for (i = 0; i < pmon_entry->num_groups; ++i)
			kfree(pmon_entry->cnt_grp[i].counters);
	}

	kfree(pmon_entry->cnt_grp);

remove_debugfs:
	debugfs_remove_recursive(msm_iommu_root_debugfs_dir);

	return;
}
EXPORT_SYMBOL(msm_iommu_pm_iommu_unregister);

struct iommu_pmon *msm_iommu_pm_alloc(struct device *dev)
{
	struct iommu_pmon *pmon_entry;
	struct iommu_info *info;
	pmon_entry = devm_kzalloc(dev, sizeof(*pmon_entry), GFP_KERNEL);
	if (!pmon_entry)
		return NULL;
	info = &pmon_entry->iommu;
	info->iommu_dev = dev;
	mutex_init(&pmon_entry->lock);
	iommu_pm_add_to_iommu_list(pmon_entry);
	return pmon_entry;
}
EXPORT_SYMBOL(msm_iommu_pm_alloc);

void msm_iommu_pm_free(struct device *dev)
{
	struct iommu_pmon *pmon = iommu_pm_get_pm_by_dev(dev);
	if (pmon)
		iommu_pm_del_from_iommu_list(pmon);
}
EXPORT_SYMBOL(msm_iommu_pm_free);

void msm_iommu_attached(struct device *dev)
{
	struct iommu_pmon *pmon = iommu_pm_get_pm_by_dev(dev);
	if (pmon) {
		mutex_lock(&pmon->lock);
		++pmon->iommu_attach_count;
		if (pmon->iommu_attach_count == 1) {
			/* If perf. mon was enabled before we attached we do
			 * the actual enabling after we attach.
			 */
			if (pmon->enabled && !pmon->iommu.always_on)
				iommu_pm_on(pmon);
		}
		mutex_unlock(&pmon->lock);
	}
}
EXPORT_SYMBOL(msm_iommu_attached);

void msm_iommu_detached(struct device *dev)
{
	struct iommu_pmon *pmon = iommu_pm_get_pm_by_dev(dev);
	if (pmon) {
		mutex_lock(&pmon->lock);
		if (pmon->iommu_attach_count == 1) {
			/* If perf. mon is still enabled we have to disable
			 * before we do the detach if iommu is not always on.
			 */
			if (pmon->enabled && !pmon->iommu.always_on)
				iommu_pm_off(pmon);
		}
		BUG_ON(pmon->iommu_attach_count == 0);
		--pmon->iommu_attach_count;
		mutex_unlock(&pmon->lock);
	}
}
EXPORT_SYMBOL(msm_iommu_detached);

