/*
 * drivers/video/tegra/host/nvhost_acm.c
 *
 * Tegra Graphics Host Automatic Clock Management
 *
 * Copyright (c) 2010-2013, NVIDIA Corporation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms and conditions of the GNU General Public License,
 * version 2, as published by the Free Software Foundation.
 *
 * This program is distributed in the hope 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.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <linux/slab.h>
#include <linux/stat.h>
#include <linux/string.h>
#include <linux/sched.h>
#include <linux/err.h>
#include <linux/export.h>
#include <linux/device.h>
#include <linux/delay.h>
#include <linux/platform_device.h>
#include <linux/pm.h>
#include <linux/pm_runtime.h>
#include <linux/clk/tegra.h>
#include <trace/events/nvhost.h>

#include <mach/powergate.h>
#include <mach/hardware.h>
#include <mach/mc.h>
#include <mach/pm_domains.h>

#include "nvhost_acm.h"
#include "dev.h"
#include "bus_client.h"

#define ACM_SUSPEND_WAIT_FOR_IDLE_TIMEOUT	(2 * HZ)
#define POWERGATE_DELAY 			10
#define MAX_DEVID_LENGTH			16

#ifdef CONFIG_PM_GENERIC_DOMAINS
static int nvhost_module_power_on(struct generic_pm_domain *domain);
static int nvhost_module_power_off(struct generic_pm_domain *domain);
#endif

DEFINE_MUTEX(client_list_lock);

struct nvhost_module_client {
	struct list_head node;
	unsigned long rate[NVHOST_MODULE_MAX_CLOCKS];
	void *priv;
};

static void do_powergate_locked(int id)
{
	nvhost_dbg_fn("%d", id);
	if (id != -1 && tegra_powergate_is_powered(id))
		tegra_powergate_partition(id);
}

static void do_unpowergate_locked(int id)
{
	int ret = 0;
	if (id != -1) {
		ret = tegra_unpowergate_partition(id);
		if (ret)
			pr_err("%s: unpowergate failed: id = %d\n",
					__func__, id);
	}
}

static void do_module_reset_locked(struct platform_device *dev)
{
	struct nvhost_device_data *pdata = platform_get_drvdata(dev);

	/* assert module and mc client reset */
	if (pdata->powergate_ids[0] != -1)
		tegra_powergate_mc_flush(pdata->powergate_ids[0]);
	if (pdata->powergate_ids[0] != -1)
		tegra_powergate_mc_disable(pdata->powergate_ids[0]);
	if (pdata->clocks[0].reset)
		tegra_periph_reset_assert(pdata->clk[0]);

	if (pdata->powergate_ids[1] != -1)
		tegra_powergate_mc_flush(pdata->powergate_ids[1]);
	if (pdata->powergate_ids[1] != -1)
		tegra_powergate_mc_disable(pdata->powergate_ids[1]);
	if (pdata->clocks[1].reset)
		tegra_periph_reset_assert(pdata->clk[1]);

	udelay(POWERGATE_DELAY);

	/* deassert reset */
	if (pdata->clocks[0].reset)
		tegra_periph_reset_deassert(pdata->clk[0]);
	if (pdata->powergate_ids[0] != -1)
		tegra_powergate_mc_enable(pdata->powergate_ids[0]);
	if (pdata->powergate_ids[0] != -1)
		tegra_powergate_mc_flush_done(pdata->powergate_ids[0]);

	if (pdata->clocks[1].reset)
		tegra_periph_reset_deassert(pdata->clk[1]);
	if (pdata->powergate_ids[1] != -1)
		tegra_powergate_mc_enable(pdata->powergate_ids[1]);
	if (pdata->powergate_ids[1] != -1)
		tegra_powergate_mc_flush_done(pdata->powergate_ids[1]);
}

void nvhost_module_reset(struct platform_device *dev)
{
	struct nvhost_device_data *pdata = platform_get_drvdata(dev);

	dev_dbg(&dev->dev,
		"%s: asserting %s module reset (id %d, id2 %d)\n",
		__func__, dev_name(&dev->dev),
		pdata->powergate_ids[0], pdata->powergate_ids[1]);

	mutex_lock(&pdata->lock);
	do_module_reset_locked(dev);
	mutex_unlock(&pdata->lock);

	if (pdata->finalize_poweron)
		pdata->finalize_poweron(dev);

	dev_dbg(&dev->dev, "%s: module %s out of reset\n",
		__func__, dev_name(&dev->dev));
}

void nvhost_module_busy(struct platform_device *dev)
{
	struct nvhost_device_data *pdata = platform_get_drvdata(dev);

	/* Explicitly turn on the host1x clocks
	 * - This is needed as host1x driver sets ignore_children = true
	 * to cater the use case of display clock ON but host1x clock OFF
	 * in OS-Idle-Display-ON case
	 * - This was easily done in ACM as it only checked the ref count
	 * of host1x (or any device for that matter) to be zero before
	 * turning off its clock
	 * - However, runtime PM checks to see if *ANY* child of device is
	 * in ACTIVE state and if yes, it doesn't suspend the parent. As a
	 * result of this, display && host1x clocks remains ON during
	 * OS-Idle-Display-ON case
	 * - The code below fixes this use-case
	 */
	if (dev->dev.parent && (dev->dev.parent != &platform_bus))
		nvhost_module_busy(nvhost_get_parent(dev));

#ifdef CONFIG_PM_RUNTIME
	pm_runtime_get_sync(&dev->dev);
#endif

	if (pdata->busy)
		pdata->busy(dev);
}

void nvhost_module_idle_mult(struct platform_device *dev, int refs)
{
	int original_refs = refs;
	struct nvhost_device_data *pdata = platform_get_drvdata(dev);

#ifdef CONFIG_PM_RUNTIME
	if (atomic_read(&dev->dev.power.usage_count) == refs) {
		if (pdata->idle)
			pdata->idle(dev);
	}

	while (refs--) {
		pm_runtime_mark_last_busy(&dev->dev);
		if (pdata->clockgate_delay)
			pm_runtime_put_sync_autosuspend(&dev->dev);
		else
			pm_runtime_put(&dev->dev);
	}
#else
	if (pdata->idle)
		pdata->idle(dev);
#endif

	/* Explicitly turn off the host1x clocks */
	if (dev->dev.parent && (dev->dev.parent != &platform_bus))
		nvhost_module_idle_mult(nvhost_get_parent(dev), original_refs);
}

int nvhost_module_get_rate(struct platform_device *dev, unsigned long *rate,
		int index)
{
	struct clk *c;
	struct nvhost_device_data *pdata = platform_get_drvdata(dev);

	c = pdata->clk[index];
	if (!c)
		return -EINVAL;

	/* Need to enable client to get correct rate */
	nvhost_module_busy(dev);
	*rate = clk_get_rate(c);
	nvhost_module_idle(dev);
	return 0;
}

static int nvhost_module_update_rate(struct platform_device *dev, int index)
{
	unsigned long rate = 0;
	struct nvhost_module_client *m;
	unsigned long devfreq_rate, default_rate;
	struct nvhost_device_data *pdata = platform_get_drvdata(dev);
	int ret;

	if (!pdata->clk[index])
		return -EINVAL;

	/* If devfreq is on, use that clock rate, otherwise default */
	devfreq_rate = pdata->clocks[index].devfreq_rate;
	default_rate = devfreq_rate ?
		devfreq_rate : pdata->clocks[index].default_rate;
	default_rate = clk_round_rate(pdata->clk[index], default_rate);

	list_for_each_entry(m, &pdata->client_list, node) {
		unsigned long r = m->rate[index];
		if (!r)
			r = default_rate;
		rate = max(r, rate);
	}
	if (!rate)
		rate = default_rate;

	trace_nvhost_module_update_rate(dev->name,
			pdata->clocks[index].name, rate);

	ret = clk_set_rate(pdata->clk[index], rate);

	if (pdata->update_clk)
		pdata->update_clk(dev);

	return ret;

}

int nvhost_module_set_rate(struct platform_device *dev, void *priv,
		unsigned long rate, int index, int bBW)
{
	struct nvhost_module_client *m;
	int ret = 0;
	struct nvhost_device_data *pdata = platform_get_drvdata(dev);

	nvhost_dbg_fn("%s", dev->name);

	mutex_lock(&client_list_lock);
	list_for_each_entry(m, &pdata->client_list, node) {
		if (m->priv == priv) {
			if (bBW) {
				/*
				 * If client sets BW, then we need to
				 * convert it to freq.
				 * rate is Bps and input param of
				 * tegra_emc_bw_to_freq_req is KBps.
				 */
				unsigned int freq_khz =
				tegra_emc_bw_to_freq_req
					((unsigned long)(rate >> 10));

				m->rate[index] =
					clk_round_rate(pdata->clk[index],
					(unsigned long)(freq_khz << 10));
			} else
				m->rate[index] =
					clk_round_rate(pdata->clk[index], rate);
		}
	}

	ret = nvhost_module_update_rate(dev, index);
	mutex_unlock(&client_list_lock);
	return ret;
}

int nvhost_module_add_client(struct platform_device *dev, void *priv)
{
	struct nvhost_module_client *client;
	struct nvhost_device_data *pdata = platform_get_drvdata(dev);

	nvhost_dbg_fn("%s num_clks=%d priv=%p", dev->name,
		      pdata->num_clks, priv);

	client = kzalloc(sizeof(*client), GFP_KERNEL);
	if (!client)
		return -ENOMEM;

	INIT_LIST_HEAD(&client->node);
	client->priv = priv;

	mutex_lock(&client_list_lock);
	list_add_tail(&client->node, &pdata->client_list);
	mutex_unlock(&client_list_lock);

	return 0;
}

void nvhost_module_remove_client(struct platform_device *dev, void *priv)
{
	int i;
	struct nvhost_module_client *m;
	int found = 0;
	struct nvhost_device_data *pdata = platform_get_drvdata(dev);

	nvhost_dbg_fn("%s priv=%p", dev->name, priv);

	mutex_lock(&client_list_lock);
	list_for_each_entry(m, &pdata->client_list, node) {
		if (priv == m->priv) {
			list_del(&m->node);
			found = 1;
			break;
		}
	}
	if (found) {
		kfree(m);
		for (i = 0; i < pdata->num_clks; i++)
			nvhost_module_update_rate(dev, i);
	}
	mutex_unlock(&client_list_lock);
}

static ssize_t powergate_delay_store(struct kobject *kobj,
	struct kobj_attribute *attr, const char *buf, size_t count)
{
	int powergate_delay = 0, ret = 0;
	struct nvhost_device_power_attr *power_attribute =
		container_of(attr, struct nvhost_device_power_attr, \
			power_attr[NVHOST_POWER_SYSFS_ATTRIB_POWERGATE_DELAY]);
	struct platform_device *dev = power_attribute->ndev;
	struct nvhost_device_data *pdata = platform_get_drvdata(dev);

	if (!pdata->can_powergate) {
		dev_info(&dev->dev, "does not support power-gating\n");
		return count;
	}

	mutex_lock(&pdata->lock);
	ret = sscanf(buf, "%d", &powergate_delay);
	if (ret == 1 && powergate_delay >= 0) {
		struct generic_pm_domain *genpd =
			pd_to_genpd(dev->dev.pm_domain);
		pdata->powergate_delay = powergate_delay;
		pm_genpd_set_poweroff_delay(genpd, pdata->powergate_delay);
	}
	else
		dev_err(&dev->dev, "Invalid powergate delay\n");
	mutex_unlock(&pdata->lock);

	return count;
}

static ssize_t powergate_delay_show(struct kobject *kobj,
	struct kobj_attribute *attr, char *buf)
{
	int ret;
	struct nvhost_device_power_attr *power_attribute =
		container_of(attr, struct nvhost_device_power_attr, \
			power_attr[NVHOST_POWER_SYSFS_ATTRIB_POWERGATE_DELAY]);
	struct platform_device *dev = power_attribute->ndev;
	struct nvhost_device_data *pdata = platform_get_drvdata(dev);

	mutex_lock(&pdata->lock);
	ret = sprintf(buf, "%d\n", pdata->powergate_delay);
	mutex_unlock(&pdata->lock);

	return ret;
}

static ssize_t clockgate_delay_store(struct kobject *kobj,
	struct kobj_attribute *attr, const char *buf, size_t count)
{
	int clockgate_delay = 0, ret = 0;
	struct nvhost_device_power_attr *power_attribute =
		container_of(attr, struct nvhost_device_power_attr, \
			power_attr[NVHOST_POWER_SYSFS_ATTRIB_CLOCKGATE_DELAY]);
	struct platform_device *dev = power_attribute->ndev;
	struct nvhost_device_data *pdata = platform_get_drvdata(dev);

	mutex_lock(&pdata->lock);
	ret = sscanf(buf, "%d", &clockgate_delay);
	if (ret == 1 && clockgate_delay >= 0) {
		pdata->clockgate_delay = clockgate_delay;
		pm_runtime_set_autosuspend_delay(&dev->dev,
			pdata->clockgate_delay);
	}
	else
		dev_err(&dev->dev, "Invalid clockgate delay\n");
	mutex_unlock(&pdata->lock);

	return count;
}

static ssize_t clockgate_delay_show(struct kobject *kobj,
	struct kobj_attribute *attr, char *buf)
{
	int ret;
	struct nvhost_device_power_attr *power_attribute =
		container_of(attr, struct nvhost_device_power_attr, \
			power_attr[NVHOST_POWER_SYSFS_ATTRIB_CLOCKGATE_DELAY]);
	struct platform_device *dev = power_attribute->ndev;
	struct nvhost_device_data *pdata = platform_get_drvdata(dev);

	mutex_lock(&pdata->lock);
	ret = sprintf(buf, "%d\n", pdata->clockgate_delay);
	mutex_unlock(&pdata->lock);

	return ret;
}

int nvhost_module_set_devfreq_rate(struct platform_device *dev, int index,
		unsigned long rate)
{
	struct nvhost_device_data *pdata = platform_get_drvdata(dev);
	int ret;

	rate = clk_round_rate(pdata->clk[index], rate);
	pdata->clocks[index].devfreq_rate = rate;

	trace_nvhost_module_set_devfreq_rate(dev->name,
			pdata->clocks[index].name, rate);

	mutex_lock(&client_list_lock);
	ret = nvhost_module_update_rate(dev, index);
	mutex_unlock(&client_list_lock);

	return ret;
}

int nvhost_module_init(struct platform_device *dev)
{
	int i = 0, err = 0;
	struct kobj_attribute *attr = NULL;
	struct nvhost_device_data *pdata = platform_get_drvdata(dev);

	/* initialize clocks to known state (=enabled) */
	pdata->num_clks = 0;
	INIT_LIST_HEAD(&pdata->client_list);
	while (i < NVHOST_MODULE_MAX_CLOCKS && pdata->clocks[i].name) {
		char devname[MAX_DEVID_LENGTH];
		long rate = pdata->clocks[i].default_rate;
		struct clk *c;

		snprintf(devname, MAX_DEVID_LENGTH,
			 (dev->id <= 0) ? "tegra_%s" : "tegra_%s.%d",
			 dev->name, dev->id);
		c = clk_get_sys(devname, pdata->clocks[i].name);
		if (IS_ERR(c)) {
			dev_err(&dev->dev, "clk_get_sys failed for i=%d %s:%s",
				i, devname, pdata->clocks[i].name);
			/* arguably we should fail init here instead... */
			i++;
			continue;
		}
		nvhost_dbg_fn("%s->clk[%d] -> %s:%s:%p",
			      dev->name, pdata->num_clks,
			      devname, pdata->clocks[i].name,
			      c);
		rate = clk_round_rate(c, rate);
		clk_prepare_enable(c);
		clk_set_rate(c, rate);
		pdata->clk[pdata->num_clks++] = c;
		i++;
	}
	pdata->num_clks = i;

	/* reset the module */
	mutex_lock(&pdata->lock);
	do_module_reset_locked(dev);
	mutex_unlock(&pdata->lock);

	/* disable the clocks */
	for (i = 0; i < pdata->num_clks; ++i)
		clk_disable_unprepare(pdata->clk[i]);

	/* power gate units that we can power gate */
	if (pdata->can_powergate) {
		do_powergate_locked(pdata->powergate_ids[0]);
		do_powergate_locked(pdata->powergate_ids[1]);
	} else {
		do_unpowergate_locked(pdata->powergate_ids[0]);
		do_unpowergate_locked(pdata->powergate_ids[1]);
	}

	/* Init the power sysfs attributes for this device */
	pdata->power_attrib = devm_kzalloc(&dev->dev,
		sizeof(struct nvhost_device_power_attr), GFP_KERNEL);
	if (!pdata->power_attrib) {
		dev_err(&dev->dev, "Unable to allocate sysfs attributes\n");
		return -ENOMEM;
	}
	pdata->power_attrib->ndev = dev;

	pdata->power_kobj = kobject_create_and_add("acm", &dev->dev.kobj);
	if (!pdata->power_kobj) {
		dev_err(&dev->dev, "Could not add dir 'power'\n");
		err = -EIO;
		goto fail_attrib_alloc;
	}

	attr = &pdata->power_attrib->power_attr[NVHOST_POWER_SYSFS_ATTRIB_CLOCKGATE_DELAY];
	attr->attr.name = "clockgate_delay";
	attr->attr.mode = S_IWUSR | S_IRUGO;
	attr->show = clockgate_delay_show;
	attr->store = clockgate_delay_store;
	sysfs_attr_init(&attr->attr);
	if (sysfs_create_file(pdata->power_kobj, &attr->attr)) {
		dev_err(&dev->dev, "Could not create sysfs attribute clockgate_delay\n");
		err = -EIO;
		goto fail_clockdelay;
	}

	attr = &pdata->power_attrib->power_attr[NVHOST_POWER_SYSFS_ATTRIB_POWERGATE_DELAY];
	attr->attr.name = "powergate_delay";
	attr->attr.mode = S_IWUSR | S_IRUGO;
	attr->show = powergate_delay_show;
	attr->store = powergate_delay_store;
	sysfs_attr_init(&attr->attr);
	if (sysfs_create_file(pdata->power_kobj, &attr->attr)) {
		dev_err(&dev->dev, "Could not create sysfs attribute powergate_delay\n");
		err = -EIO;
		goto fail_powergatedelay;
	}

	if (pdata->clockgate_delay) {
		pm_runtime_set_autosuspend_delay(&dev->dev,
			pdata->clockgate_delay);
		pm_runtime_use_autosuspend(&dev->dev);
	}
	pm_runtime_enable(&dev->dev);
	if (!pm_runtime_enabled(&dev->dev))
		nvhost_module_enable_clk(&dev->dev);
	return 0;

fail_powergatedelay:
	attr = &pdata->power_attrib->power_attr[NVHOST_POWER_SYSFS_ATTRIB_CLOCKGATE_DELAY];
	sysfs_remove_file(pdata->power_kobj, &attr->attr);

fail_clockdelay:
	kobject_put(pdata->power_kobj);

fail_attrib_alloc:
	kfree(pdata->power_attrib);

	return err;
}
EXPORT_SYMBOL(nvhost_module_init);

int nvhost_module_suspend(struct device *dev)
{
	struct nvhost_device_data *pdata = dev_get_drvdata(dev);

	if (pm_runtime_suspended(dev))
		return 0;

	if (pm_runtime_barrier(dev))
		return -EBUSY;

	if (pdata->suspend_ndev)
		pdata->suspend_ndev(dev);

	return 0;
}

int nvhost_module_resume(struct device *dev)
{
	struct nvhost_device_data *pdata = dev_get_drvdata(dev);

	if (!pdata->can_powergate && pdata->finalize_poweron) {
		nvhost_module_enable_clk(dev);
		pdata->finalize_poweron(to_platform_device(dev));
		nvhost_module_disable_clk(dev);
	}

	return 0;
}

void nvhost_module_deinit(struct platform_device *dev)
{
	int i;
	struct kobj_attribute *attr = NULL;
	struct nvhost_device_data *pdata = platform_get_drvdata(dev);

	nvhost_module_suspend(&dev->dev);
	for (i = 0; i < pdata->num_clks; i++)
		clk_put(pdata->clk[i]);

	if (pdata->power_kobj) {
		for (i = 0; i < NVHOST_POWER_SYSFS_ATTRIB_MAX; i++) {
			attr = &pdata->power_attrib->power_attr[i];
			sysfs_remove_file(pdata->power_kobj, &attr->attr);
		}

		kobject_put(pdata->power_kobj);
	}

}

#ifdef CONFIG_PM
const struct dev_pm_ops nvhost_module_pm_ops = {
#if defined(CONFIG_PM_RUNTIME) && !defined(CONFIG_PM_GENERIC_DOMAINS)
	.runtime_suspend = nvhost_module_disable_clk,
	.runtime_resume = nvhost_module_enable_clk,
#endif
};
#endif

/* common runtime pm and power domain APIs */
int nvhost_module_add_domain(struct generic_pm_domain *domain,
	struct platform_device *pdev)
{
	int ret = 0;
	struct nvhost_device_data *pdata;
	struct dev_power_governor *pm_domain_gov = NULL;

	pdata = platform_get_drvdata(pdev);
	if (!pdata)
		return -EINVAL;

	if (!pdata->can_powergate)
#ifdef CONFIG_PM_GENERIC_DOMAINS
		pm_domain_gov = &pm_domain_always_on_gov;

	if (__pm_genpd_name_add_device(domain->name, &pdev->dev, NULL)) {
		pm_genpd_init(domain, pm_domain_gov, true);

		domain->power_off = nvhost_module_power_off;
		domain->power_on = nvhost_module_power_on;
		domain->dev_ops.start = nvhost_module_enable_clk;
		domain->dev_ops.stop = nvhost_module_disable_clk;
		domain->dev_ops.save_state = nvhost_module_prepare_poweroff;
		domain->dev_ops.restore_state = nvhost_module_finalize_poweron;
		/* overwrite save/restore fptrs set by pm_genpd_init */
		domain->domain.ops.suspend = nvhost_client_device_suspend;
		domain->domain.ops.resume = nvhost_client_device_resume;

		ret = pm_genpd_add_device(domain, &pdev->dev);
		if (pdata->powergate_delay)
			pm_genpd_set_poweroff_delay(domain,
					pdata->powergate_delay);
		tegra_pd_add_sd(domain);
	}
#endif

	return ret;
}
EXPORT_SYMBOL(nvhost_module_add_domain);

int nvhost_module_enable_clk(struct device *dev)
{
	int index = 0;
	struct nvhost_device_data *pdata;

	/* enable parent's clock if required */
	if (dev->parent && dev->parent != &platform_bus)
		nvhost_module_enable_clk(dev->parent);

	pdata = dev_get_drvdata(dev);
	if (!pdata)
		return -EINVAL;

	for (index = 0; index < pdata->num_clks; index++) {
		int err = clk_prepare_enable(pdata->clk[index]);
		if (err) {
			dev_err(dev, "Cannot turn on clock %s",
				pdata->clocks[index].name);
			return -EINVAL;
		}
	}

	return 0;
}
EXPORT_SYMBOL(nvhost_module_enable_clk);

int nvhost_module_disable_clk(struct device *dev)
{
	int index = 0;
	struct nvhost_device_data *pdata;

	pdata = dev_get_drvdata(dev);
	if (!pdata)
		return -EINVAL;

	for (index = 0; index < pdata->num_clks; index++)
		clk_disable_unprepare(pdata->clk[index]);

	/* disable parent's clock if required */
	if (dev->parent && dev->parent != &platform_bus)
		nvhost_module_disable_clk(dev->parent);

	return 0;
}
EXPORT_SYMBOL(nvhost_module_disable_clk);

#ifdef CONFIG_PM_GENERIC_DOMAINS
static int nvhost_module_power_on(struct generic_pm_domain *domain)
{
	struct nvhost_device_data *pdata;

	pdata = container_of(domain, struct nvhost_device_data, pd);

	mutex_lock(&pdata->lock);
	if (pdata->can_powergate) {
		do_unpowergate_locked(pdata->powergate_ids[0]);
		do_unpowergate_locked(pdata->powergate_ids[1]);
	}

	if (pdata->powerup_reset)
		do_module_reset_locked(pdata->pdev);
	mutex_unlock(&pdata->lock);

	return 0;
}

static int nvhost_module_power_off(struct generic_pm_domain *domain)
{
	struct nvhost_device_data *pdata;

	pdata = container_of(domain, struct nvhost_device_data, pd);

	mutex_lock(&pdata->lock);
	if (pdata->can_powergate) {
		do_powergate_locked(pdata->powergate_ids[0]);
		do_powergate_locked(pdata->powergate_ids[1]);
	}
	mutex_unlock(&pdata->lock);

	return 0;
}

int nvhost_module_prepare_poweroff(struct device *dev)
{
	struct nvhost_device_data *pdata;

	pdata = dev_get_drvdata(dev);
	if (!pdata)
		return -EINVAL;

	if (pdata->prepare_poweroff)
		pdata->prepare_poweroff(to_platform_device(dev));

	return 0;
}

int nvhost_module_finalize_poweron(struct device *dev)
{
	struct nvhost_device_data *pdata;

	pdata = dev_get_drvdata(dev);
	if (!pdata)
		return -EINVAL;

	if (pdata->finalize_poweron)
		pdata->finalize_poweron(to_platform_device(dev));

	return 0;
}
#endif

/* public host1x power management APIs */
bool nvhost_module_powered_ext(struct platform_device *dev)
{
	struct platform_device *pdev;

	if (!nvhost_get_parent(dev)) {
		dev_err(&dev->dev, "Module powered called with wrong dev\n");
		return 0;
	}

	/* get the parent */
	pdev = to_platform_device(dev->dev.parent);

	return nvhost_module_powered(pdev);
}

void nvhost_module_busy_ext(struct platform_device *dev)
{
	struct platform_device *pdev;

	if (!nvhost_get_parent(dev)) {
		dev_err(&dev->dev, "Module busy called with wrong dev\n");
		return;
	}

	/* get the parent */
	pdev = to_platform_device(dev->dev.parent);

	nvhost_module_busy(pdev);
}
EXPORT_SYMBOL(nvhost_module_busy_ext);

void nvhost_module_idle_ext(struct platform_device *dev)
{
	struct platform_device *pdev;

	if (!nvhost_get_parent(dev)) {
		dev_err(&dev->dev, "Module idle called with wrong dev\n");
		return;
	}

	/* get the parent */
	pdev = to_platform_device(dev->dev.parent);

	nvhost_module_idle(pdev);
}
EXPORT_SYMBOL(nvhost_module_idle_ext);
