/*
 *
 * MNH PWR APIs
 * Copyright (c) 2016, Intel Corporation.
 *
 * 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.
 *
 */

/* #define DEBUG */

#include <linux/clk.h>
#include <linux/device.h>
#include <linux/gpio/consumer.h>
#include <linux/gpio/machine.h>
#include <linux/interrupt.h>
#include <linux/msm_pcie.h>
#include <linux/regulator/consumer.h>

#include "mnh-pcie.h"
#include "mnh-pwr.h"
#include "mnh-sm.h"

#define MNH_PCIE_RC_INDEX 0
#define MNH_PCIE_VENDOR_ID  0x8086
#define MNH_PCIE_DEVICE_ID  0x3140
#define DISABLE_PCIE_L1_MASK  0xFFFFFFFD
#define PCIE20_CAP_LINKCTRLSTATUS  0x80

#define PM_OPT_SUSPEND MSM_PCIE_CONFIG_LINKDOWN
#define PM_OPT_RESUME MSM_PCIE_CONFIG_NO_CFG_FREE

struct mnh_pwr_data {
	struct platform_device *pdev;
	struct device *dev;

	/* regulators */
	struct regulator *asr_supply;
	struct regulator *sdsr_supply;
	struct regulator *sdldo_supply;
	struct regulator *ioldo_supply;
	struct notifier_block asr_nb;
	struct notifier_block sdsr_nb;
	struct notifier_block ioldo_nb;
	struct notifier_block sdldo_nb;

	/* clocks */
	struct clk *ref_clk;
	struct clk *sleep_clk;
	bool ref_clk_enabled;
	bool sleep_clk_enabled;

	/* pins */
	struct gpio_desc *soc_pwr_good_pin;

	/* pcie device */
	struct pci_dev *pcidev;
	struct pci_saved_state *pristine_state;
	struct msm_pcie_register_event pci_link_event;

	struct work_struct shutdown_work;

	bool pcie_failure;

	enum mnh_pwr_state state;

	struct mutex lock;
};

static struct mnh_pwr_data *mnh_pwr;

static void mnh_pwr_shutdown_work(struct work_struct *data)
{
	dev_err(mnh_pwr->dev, "%s: begin emergency power down\n", __func__);

	mnh_pwr_set_state(MNH_PWR_S4);
	mnh_sm_pwr_error_cb();
}

static int mnh_pwr_asr_notifier_cb(struct notifier_block *nb,
				   unsigned long event, void *cookie)
{
	dev_dbg(mnh_pwr->dev, "%s: received event %ld\n", __func__, event);

	mnh_pwr->pcie_failure = true;

	/* force emergency shutdown if regulator output has failed */
	if (event == REGULATOR_EVENT_FAIL) {
		dev_err(mnh_pwr->dev,
			"%s: asr supply has failed, forcing shutdown\n",
			__func__);

		if (mnh_pwr->state != MNH_PWR_S4)
			schedule_work(&mnh_pwr->shutdown_work);
	}

	return 0;
}

static int mnh_pwr_sdsr_notifier_cb(struct notifier_block *nb,
				   unsigned long event, void *cookie)
{
	dev_dbg(mnh_pwr->dev, "%s: received event %ld\n", __func__, event);

	mnh_pwr->pcie_failure = true;

	/* force emergency shutdown if regulator output has failed */
	if (event == REGULATOR_EVENT_FAIL) {
		dev_err(mnh_pwr->dev,
			"%s: sdsr supply has failed, forcing shutdown\n",
			__func__);

		if (mnh_pwr->state != MNH_PWR_S4)
			schedule_work(&mnh_pwr->shutdown_work);
	}

	return 0;
}

static int mnh_pwr_ioldo_notifier_cb(struct notifier_block *nb,
				   unsigned long event, void *cookie)
{
	dev_dbg(mnh_pwr->dev, "%s: received event %ld\n", __func__, event);

	mnh_pwr->pcie_failure = true;

	/* force emergency shutdown if regulator output has failed */
	if (event == REGULATOR_EVENT_FAIL) {
		dev_err(mnh_pwr->dev,
			"%s: ioldo supply has failed, forcing shutdown\n",
			__func__);

		if (mnh_pwr->state != MNH_PWR_S4)
			schedule_work(&mnh_pwr->shutdown_work);
	}

	return 0;
}

static int mnh_pwr_sdldo_notifier_cb(struct notifier_block *nb,
				   unsigned long event, void *cookie)
{
	dev_dbg(mnh_pwr->dev, "%s: received event %ld\n", __func__, event);

	mnh_pwr->pcie_failure = true;

	/* force emergency shutdown if regulator output has failed */
	if (event == REGULATOR_EVENT_FAIL) {
		dev_err(mnh_pwr->dev,
			"%s: sdldo supply has failed, forcing shutdown\n",
			__func__);

		if (mnh_pwr->state != MNH_PWR_S4)
			schedule_work(&mnh_pwr->shutdown_work);
	}

	return 0;
}

void mnh_pwr_pcie_link_state_cb(struct msm_pcie_notify *notify)
{
	struct mnh_pwr_data *mnh_pwr = notify->data;

	switch (notify->event) {
	case MSM_PCIE_EVENT_LINKDOWN:
		dev_err(mnh_pwr->dev,
			"%s: PCIe link is down, forcing power down\n",
			__func__);

		mnh_pwr->pcie_failure = true;

		/* force emergency shutdown */
		schedule_work(&mnh_pwr->shutdown_work);
		break;
	default:
		dev_err(mnh_pwr->dev,
			"%s: received invalid pcie link state event (%d)\n",
			__func__, notify->event);
		break;
	}
}

static int mnh_pwr_pcie_enumerate(void)
{
	struct pci_dev *pcidev = NULL;
	int ret;

	/* enumerate PCIE */
	ret = msm_pcie_enumerate(MNH_PCIE_RC_INDEX);
	if (ret < 0) {
		dev_err(mnh_pwr->dev, "%s: pcie enumeration failed (%d)\n",
			__func__, ret);
		return ret;
	}

	/* search for PCIE device in our domain */
	do {
		pcidev = pci_get_device(MNH_PCIE_VENDOR_ID, MNH_PCIE_DEVICE_ID, pcidev);
		if (!pcidev)
			break;

		if (pci_domain_nr(pcidev->bus) == MNH_PCIE_RC_INDEX)
			break;
	} while (true);
	if (!pcidev) {
		dev_err(mnh_pwr->dev, "%s: could not find mnh device\n",
			__func__);
		return -ENODEV;
	}

	/* save current state in pcidev */
	ret = pci_save_state(pcidev);
	if (ret) {
		dev_err(mnh_pwr->dev, "%s: pci_save_state failed (%d)\n",
			__func__, ret);
		pci_dev_put(pcidev);
		return ret;
	}

	/* store saved state so we can recall it after resume */
	mnh_pwr->pristine_state = pci_store_saved_state(pcidev);
	if (!mnh_pwr->pristine_state) {
		dev_err(mnh_pwr->dev,
			"%s: pci_store_saved_state failed\n",
			__func__);
		pci_dev_put(pcidev);
		return ret;
	}

	/* save device to driver struct */
	mnh_pwr->pcidev = pcidev;

	return 0;
}

static int mnh_pwr_pcie_suspend(void)
{
	struct pci_dev *pcidev = mnh_pwr->pcidev;
	int ret;

	if (!pcidev)
		return -ENODEV;

	/* suspend the driver state */
	ret = mnh_pci_suspend();
	if (ret) {
		dev_err(mnh_pwr->dev, "%s: mnh_pci_suspend failed (%d)\n",
			__func__, ret);
	}

	if (mnh_pwr->pcie_failure) {
		/* call the platform driver to update link status */
		ret = msm_pcie_pm_control(MSM_PCIE_SUSPEND, pcidev->bus->number,
			pcidev, NULL,
			PM_OPT_SUSPEND | MSM_PCIE_CONFIG_NO_CFG_RESTORE);
		if (ret) {
			dev_err(mnh_pwr->dev,
				"%s: msm_pcie_pm_control(suspend) failed (%d)\n",
				__func__, ret);
			return ret;
		}

		mnh_pwr->pcie_failure = false;
	} else {
		/* prepare the root complex and endpoint for going to suspend */
		ret = pci_prepare_to_sleep(pcidev);
		if (ret) {
			dev_err(mnh_pwr->dev,
				"%s: pci_prepare_to_sleep failed (%d)\n",
				__func__, ret);
		}

		/* call the platform driver to suspend PCIe link */
		ret = msm_pcie_pm_control(MSM_PCIE_SUSPEND, pcidev->bus->number,
					  pcidev, NULL, PM_OPT_SUSPEND);
		if (ret) {
			dev_err(mnh_pwr->dev,
				"%s: msm_pcie_pm_control(suspend) failed (%d)\n",
				__func__, ret);
			return ret;
		}
	}

	return 0;
}

static int mnh_pwr_pcie_resume(void)
{
	struct pci_dev *pcidev = mnh_pwr->pcidev;
	int ret;

	/* check for valid pcidev */
	if (!pcidev) {
		/* enumerate pci device */
		ret = mnh_pwr_pcie_enumerate();
		if (ret) {
			dev_err(mnh_pwr->dev,
				"%s: mnh_pwr_pcie_enumerate failed (%d)\n",
				__func__, ret);
			return ret;
		}

		/* save the newly enumerated device to the local copy */
		pcidev = mnh_pwr->pcidev;

		/* register for link down events so we can handle them */
		mnh_pwr->pci_link_event.events = MSM_PCIE_EVENT_LINKDOWN;
		mnh_pwr->pci_link_event.user = pcidev;
		mnh_pwr->pci_link_event.callback = mnh_pwr_pcie_link_state_cb;
		mnh_pwr->pci_link_event.notify.data = mnh_pwr;
		ret = msm_pcie_register_event(&mnh_pwr->pci_link_event);
		if (ret) {
			dev_err(mnh_pwr->dev,
				"%s: msm_pcie_register_event failed (%d)\n",
				__func__, ret);
		}
	} else {
		ret = msm_pcie_pm_control(MSM_PCIE_RESUME, pcidev->bus->number,
					  pcidev, NULL, PM_OPT_RESUME);
		if (ret) {
			dev_err(mnh_pwr->dev,
				"%s: msm_pcie_pm_control(resume) failed (%d)\n",
				__func__, ret);
			return ret;
		}

		/* prepare the root complex and endpoint */
		ret = pci_back_from_sleep(pcidev);
		if (ret) {
			dev_err(mnh_pwr->dev,
				"%s: pci_back_from_sleep failed (%d)\n",
				__func__, ret);
			goto fail_pcie_resume_awake;
		}

		/* load the saved state in the device buffer */
		ret = pci_load_saved_state(pcidev, mnh_pwr->pristine_state);
		if (ret) {
			dev_err(mnh_pwr->dev,
				"%s: pci_load_saved_state failed (%d)\n",
				__func__, ret);
			goto fail_pcie_resume_load_state;
		}

		/* apply the saved state to the device */
		pci_restore_state(pcidev);

		/* resume the driver state */
		ret = mnh_pci_resume();
		if (ret) {
			dev_err(mnh_pwr->dev, "%s: mnh_pci_resume failed (%d)\n",
				__func__, ret);
			goto fail_pcie_resume_mnh_init;
		}
	}

	mnh_pwr->pcie_failure = false;

	return 0;

fail_pcie_resume_mnh_init:
fail_pcie_resume_load_state:
	pci_prepare_to_sleep(pcidev);
fail_pcie_resume_awake:
	msm_pcie_pm_control(MSM_PCIE_SUSPEND, pcidev->bus->number, pcidev,
			     NULL, PM_OPT_SUSPEND);

	return ret;
}

static int mnh_pwr_down(void)
{
	int ret;

	if ((mnh_pwr->state != MNH_PWR_S3) &&
	    (mnh_sm_get_boot_mode() == MNH_BOOT_MODE_PCIE)) {
		/* suspend pcie link */
		ret = mnh_pwr_pcie_suspend();
		if (ret) {
			dev_err(mnh_pwr->dev, "%s: failed to suspend pcie link (%d)\n",
				__func__, ret);
			goto fail_pwr_down_pcie;
		}
	} else {
		/* assert reset */
		msm_pcie_set_reset(MNH_PCIE_RC_INDEX, true);
	}

	/* deassert soc_pwr_good */
	gpiod_set_value_cansleep(mnh_pwr->soc_pwr_good_pin, 0);

	/* disable clocks */
	if (mnh_pwr->ref_clk_enabled) {
		clk_disable_unprepare(mnh_pwr->ref_clk);
		mnh_pwr->ref_clk_enabled = false;
	}
	if (mnh_pwr->sleep_clk_enabled) {
		clk_disable_unprepare(mnh_pwr->sleep_clk);
		mnh_pwr->sleep_clk_enabled = false;
	}

	/* disable supplies: sdsr -> asr -> ioldo -> sdldo */
	if (regulator_is_enabled(mnh_pwr->sdsr_supply)) {
		ret = regulator_disable(mnh_pwr->sdsr_supply);
		if (ret) {
			dev_err(mnh_pwr->dev, "%s: failed to disable sdsr (%d)\n",
				__func__, ret);
			goto fail_pwr_down_sdsr;
		}
	}

	if (regulator_is_enabled(mnh_pwr->asr_supply)) {
		ret = regulator_disable(mnh_pwr->asr_supply);
		if (ret) {
			dev_err(mnh_pwr->dev, "%s: failed to disable asr (%d)\n",
				__func__, ret);
			goto fail_pwr_down_asr;
		}
	}

	if (regulator_is_enabled(mnh_pwr->ioldo_supply)) {
		ret = regulator_disable(mnh_pwr->ioldo_supply);
		if (ret) {
			dev_err(mnh_pwr->dev, "%s: failed to disable ioldo (%d)\n",
				__func__, ret);
			goto fail_pwr_down_ioldo;
		}
	}

	if (regulator_is_enabled(mnh_pwr->sdldo_supply)) {
		ret = regulator_disable(mnh_pwr->sdldo_supply);
		if (ret) {
			dev_err(mnh_pwr->dev, "%s: failed to disable sdldo (%d)\n",
				__func__, ret);
			goto fail_pwr_down_sdldo;
		}
	}

	mnh_pwr->state = MNH_PWR_S4;

	return 0;

fail_pwr_down_pcie:
	gpiod_set_value_cansleep(mnh_pwr->soc_pwr_good_pin, 0);
	if (mnh_pwr->sleep_clk_enabled) {
		clk_disable_unprepare(mnh_pwr->sleep_clk);
		mnh_pwr->sleep_clk_enabled = false;
	}
	if (mnh_pwr->ref_clk_enabled) {
		clk_disable_unprepare(mnh_pwr->ref_clk);
		mnh_pwr->ref_clk_enabled = false;
	}
	if (regulator_is_enabled(mnh_pwr->sdsr_supply))
		regulator_disable(mnh_pwr->sdsr_supply);
fail_pwr_down_sdsr:
	if (regulator_is_enabled(mnh_pwr->asr_supply))
		regulator_disable(mnh_pwr->asr_supply);
fail_pwr_down_asr:
	if (regulator_is_enabled(mnh_pwr->ioldo_supply))
		regulator_disable(mnh_pwr->ioldo_supply);
fail_pwr_down_ioldo:
	if (regulator_is_enabled(mnh_pwr->sdldo_supply))
		regulator_disable(mnh_pwr->sdldo_supply);
fail_pwr_down_sdldo:

	dev_err(mnh_pwr->dev,
		"%s: force shutdown because of powerdown failure (%d)\n",
		__func__, ret);

	mnh_pwr->state = MNH_PWR_S4;

	return ret;
}

static int mnh_pwr_suspend(void)
{
	int ret;

	if (mnh_sm_get_boot_mode() == MNH_BOOT_MODE_PCIE) {
		/* suspend pcie link */
		ret = mnh_pwr_pcie_suspend();
		if (ret) {
			dev_err(mnh_pwr->dev, "%s: failed to suspend pcie link (%d)\n",
				__func__, ret);
			goto fail_pwr_suspend_pcie;
		}
	} else {
		/* assert reset */
		msm_pcie_set_reset(MNH_PCIE_RC_INDEX, true);
	}

	/* deassert soc_pwr_good */
	gpiod_set_value_cansleep(mnh_pwr->soc_pwr_good_pin, 0);

	/* disable clocks */
	if (mnh_pwr->ref_clk_enabled) {
		clk_disable_unprepare(mnh_pwr->ref_clk);
		mnh_pwr->ref_clk_enabled = false;
	}
	if (mnh_pwr->sleep_clk_enabled) {
		clk_disable_unprepare(mnh_pwr->sleep_clk);
		mnh_pwr->sleep_clk_enabled = false;
	}

	/* disable core supplies */
	ret = regulator_disable(mnh_pwr->asr_supply);
	if (ret) {
		dev_err(mnh_pwr->dev,
			"%s: failed to disable asr (%d)\n", __func__, ret);
		goto fail_pwr_suspend_regulators;
	}

	regulator_disable(mnh_pwr->ioldo_supply);
	if (ret) {
		dev_err(mnh_pwr->dev,
			"%s: failed to disable ioldo (%d)\n", __func__, ret);
		goto fail_pwr_suspend_regulators;
	}

	mnh_pwr->state = MNH_PWR_S3;

	return 0;

fail_pwr_suspend_pcie:
	gpiod_set_value_cansleep(mnh_pwr->soc_pwr_good_pin, 0);
	if (mnh_pwr->sleep_clk_enabled) {
		clk_disable_unprepare(mnh_pwr->sleep_clk);
		mnh_pwr->sleep_clk_enabled = false;
	}
	if (mnh_pwr->ref_clk_enabled) {
		clk_disable_unprepare(mnh_pwr->ref_clk);
		mnh_pwr->ref_clk_enabled = false;
	}
fail_pwr_suspend_regulators:
	if (regulator_is_enabled(mnh_pwr->sdsr_supply))
		regulator_disable(mnh_pwr->sdsr_supply);
	if (regulator_is_enabled(mnh_pwr->asr_supply))
		regulator_disable(mnh_pwr->asr_supply);
	if (regulator_is_enabled(mnh_pwr->ioldo_supply))
		regulator_disable(mnh_pwr->ioldo_supply);
	if (regulator_is_enabled(mnh_pwr->sdldo_supply))
		regulator_disable(mnh_pwr->sdldo_supply);

	dev_err(mnh_pwr->dev,
		"%s: force shutdown because of suspend failure (%d)\n",
		__func__, ret);

	mnh_pwr->state = MNH_PWR_S4;

	return ret;
}

static int mnh_pwr_partial(void)
{
	int ret;

	/* disable DRAM core supply */
	if (regulator_is_enabled(mnh_pwr->sdsr_supply)) {
		ret = regulator_disable(mnh_pwr->sdsr_supply);
		if (ret) {
			dev_err(mnh_pwr->dev, "%s: failed to disable sdsr (%d)\n",
				__func__, ret);
		}
	}

	/* disable DRAM I/O supply */
	if (regulator_is_enabled(mnh_pwr->sdldo_supply)) {
		ret = regulator_disable(mnh_pwr->sdldo_supply);
		if (ret) {
			dev_err(mnh_pwr->dev, "%s: failed to disable sdldo (%d)\n",
				__func__, ret);
		}
	}

	mnh_pwr->state = MNH_PWR_S1;

	return 0;
}

static int mnh_pwr_up(enum mnh_pwr_state next_state)
{
	int ret;

	/* enable supplies */
	/* sdldo -> ioldo -> asr -> sdsr */
	if (mnh_pwr->state == MNH_PWR_S4) {
		ret = regulator_enable(mnh_pwr->sdldo_supply);
		if (ret) {
			dev_err(mnh_pwr->dev,
				"%s: failed to enable sdldo (%d)\n",
				__func__, ret);
			goto fail_pwr_up_regulators;
		}
	}

	ret = regulator_enable(mnh_pwr->ioldo_supply);
	if (ret) {
		dev_err(mnh_pwr->dev, "%s: failed to enable ioldo (%d)\n",
			__func__, ret);
		goto fail_pwr_up_regulators;
	}

	ret = regulator_enable(mnh_pwr->asr_supply);
	if (ret) {
		dev_err(mnh_pwr->dev, "%s: failed to enable ioldo (%d)\n",
			__func__, ret);
		goto fail_pwr_up_regulators;
	}

	if (mnh_pwr->state == MNH_PWR_S4) {
		ret = regulator_enable(mnh_pwr->sdsr_supply);
		if (ret) {
			dev_err(mnh_pwr->dev,
				"%s: failed to enable sdsr (%d)\n",
				__func__, ret);
			goto fail_pwr_up_regulators;
		}
	}

	/* turn on clocks */
	if (!mnh_pwr->ref_clk_enabled) {
		ret = clk_prepare_enable(mnh_pwr->ref_clk);
		if (ret) {
			dev_err(mnh_pwr->dev,
				"%s: failed to enable ref clk (%d)\n",
				__func__, ret);
			goto fail_pwr_up_ref_clk;
		}
		mnh_pwr->ref_clk_enabled = true;
	}

	if (!mnh_pwr->sleep_clk_enabled) {
		ret = clk_prepare_enable(mnh_pwr->sleep_clk);
		if (ret) {
			dev_err(mnh_pwr->dev,
				"%s: failed to enable sleep clk (%d)\n",
				__func__, ret);
			goto fail_pwr_up_sleep_clk;
		}
		mnh_pwr->sleep_clk_enabled = true;
	}

	/* assert soc_pwr_good */
	gpiod_set_value_cansleep(mnh_pwr->soc_pwr_good_pin, 1);

	/* give the PLLs some time to initialize */
	udelay(60);

	if (mnh_sm_get_boot_mode() == MNH_BOOT_MODE_PCIE) {
		/* resume pcie link */
		ret = mnh_pwr_pcie_resume();
		if (ret) {
			dev_err(mnh_pwr->dev, "%s: failed to resume pcie link (%d)\n",
				__func__, ret);
			goto fail_pwr_up_pcie;
		}
	} else {
		/* deassert reset */
		msm_pcie_set_reset(MNH_PCIE_RC_INDEX, false);
	}

	mnh_pwr->state = next_state;

	return 0;

fail_pwr_up_pcie:
	gpiod_set_value_cansleep(mnh_pwr->soc_pwr_good_pin, 0);
	if (mnh_pwr->sleep_clk_enabled) {
		clk_disable_unprepare(mnh_pwr->sleep_clk);
		mnh_pwr->sleep_clk_enabled = false;
	}
fail_pwr_up_sleep_clk:
	if (mnh_pwr->ref_clk_enabled) {
		clk_disable_unprepare(mnh_pwr->ref_clk);
		mnh_pwr->ref_clk_enabled = false;
	}
fail_pwr_up_ref_clk:
fail_pwr_up_regulators:
	if (regulator_is_enabled(mnh_pwr->sdsr_supply))
		regulator_disable(mnh_pwr->sdsr_supply);
	if (regulator_is_enabled(mnh_pwr->asr_supply))
		regulator_disable(mnh_pwr->asr_supply);
	if (regulator_is_enabled(mnh_pwr->ioldo_supply))
		regulator_disable(mnh_pwr->ioldo_supply);
	if (regulator_is_enabled(mnh_pwr->sdldo_supply))
		regulator_disable(mnh_pwr->sdldo_supply);

	dev_err(mnh_pwr->dev,
		"%s: force shutdown because of power up failure (%d)\n",
		__func__, ret);

	mnh_pwr->state = MNH_PWR_S4;

	return ret;
}

static int mnh_pwr_get_resources(void)
{
	struct platform_device *pdev = mnh_pwr->pdev;
	struct device *dev = mnh_pwr->dev;
	int ret;

	/* request supplies */
	mnh_pwr->asr_supply = devm_regulator_get(&pdev->dev, "bcm15602_asr");
	if (IS_ERR(mnh_pwr->asr_supply)) {
		dev_err(dev, "%s: failed to get asr supply (%ld)\n",
			__func__, PTR_ERR(mnh_pwr->asr_supply));
		return PTR_ERR(mnh_pwr->asr_supply);
	}

	mnh_pwr->sdsr_supply = devm_regulator_get(&pdev->dev, "bcm15602_sdsr");
	if (IS_ERR(mnh_pwr->sdsr_supply)) {
		dev_err(dev, "%s: failed to get sdsr supply (%ld)\n",
			__func__, PTR_ERR(mnh_pwr->sdsr_supply));
		return PTR_ERR(mnh_pwr->sdsr_supply);
	}

	mnh_pwr->ioldo_supply = devm_regulator_get(&pdev->dev,
						   "bcm15602_ioldo");
	if (IS_ERR(mnh_pwr->ioldo_supply)) {
		dev_err(dev, "%s: failed to get ioldo supply (%ld)\n",
			__func__, PTR_ERR(mnh_pwr->ioldo_supply));
		return PTR_ERR(mnh_pwr->ioldo_supply);
	}

	mnh_pwr->sdldo_supply = devm_regulator_get(&pdev->dev,
						   "bcm15602_sdldo");
	if (IS_ERR(mnh_pwr->sdldo_supply)) {
		dev_err(dev, "%s: failed to get sdldo supply (%ld)\n",
			__func__, PTR_ERR(mnh_pwr->sdldo_supply));
		return PTR_ERR(mnh_pwr->sdldo_supply);
	}

	/* register the notifier for each of the supplies */
	mnh_pwr->asr_nb.notifier_call = mnh_pwr_asr_notifier_cb;
	ret = devm_regulator_register_notifier(mnh_pwr->asr_supply,
					       &mnh_pwr->asr_nb);
	if (ret) {
		dev_err(dev,
			"%s: failed to register notifier block for asr supply (%d)\n",
			__func__, ret);
		return ret;
	}

	mnh_pwr->sdsr_nb.notifier_call = mnh_pwr_sdsr_notifier_cb;
	ret = devm_regulator_register_notifier(mnh_pwr->sdsr_supply,
					       &mnh_pwr->sdsr_nb);
	if (ret) {
		dev_err(dev,
			"%s: failed to register notifier block for sdsr supply (%d)\n",
			__func__, ret);
		return ret;
	}

	mnh_pwr->ioldo_nb.notifier_call = mnh_pwr_ioldo_notifier_cb;
	ret = devm_regulator_register_notifier(mnh_pwr->ioldo_supply,
					       &mnh_pwr->ioldo_nb);
	if (ret) {
		dev_err(dev,
			"%s: failed to register notifier block for ioldo supply (%d)\n",
			__func__, ret);
		return ret;
	}

	mnh_pwr->sdldo_nb.notifier_call = mnh_pwr_sdldo_notifier_cb;
	ret = devm_regulator_register_notifier(mnh_pwr->sdldo_supply,
					       &mnh_pwr->sdldo_nb);
	if (ret) {
		dev_err(dev,
			"%s: failed to register notifier block for sdldo supply (%d)\n",
			__func__, ret);
		return ret;
	}

	/* request gpio descriptors */
	mnh_pwr->soc_pwr_good_pin = devm_gpiod_get(&pdev->dev, "soc-pwr-good",
						   GPIOD_OUT_LOW);
	if (IS_ERR(mnh_pwr->soc_pwr_good_pin)) {
		dev_err(dev, "%s: could not get soc_pwr_good gpio (%ld)\n",
			__func__, PTR_ERR(mnh_pwr->soc_pwr_good_pin));
		return PTR_ERR(mnh_pwr->soc_pwr_good_pin);
	}

	/* request clocks */
	mnh_pwr->ref_clk = devm_clk_get(&pdev->dev, "ref_clk");
	if (IS_ERR(mnh_pwr->ref_clk)) {
		dev_err(dev, "%s: could not get ref clk (%ld)\n", __func__,
			PTR_ERR(mnh_pwr->ref_clk));
		return PTR_ERR(mnh_pwr->ref_clk);
	}

	mnh_pwr->sleep_clk = devm_clk_get(&pdev->dev, "sleep_clk");
	if (IS_ERR(mnh_pwr->sleep_clk)) {
		dev_err(dev, "%s: could not get sleep clk (%ld)\n", __func__,
			PTR_ERR(mnh_pwr->sleep_clk));
		return PTR_ERR(mnh_pwr->sleep_clk);
	}

	return 0;
}

int mnh_pwr_set_state(enum mnh_pwr_state system_state)
{
	int ret = 0;
	enum mnh_pwr_state curr_state =  mnh_pwr_get_state();

	dev_dbg(mnh_pwr->dev, "%s req: %d, current: %d\n", __func__,
		system_state, curr_state);

	mutex_lock(&mnh_pwr->lock);

	if (system_state != mnh_pwr->state) {
		switch (system_state) {
		case MNH_PWR_S0:
			ret = mnh_pwr_up(system_state);
			break;
		case MNH_PWR_S1:
			ret = mnh_pwr_partial();
			break;
		case MNH_PWR_S3:
			ret = mnh_pwr_suspend();
			break;
		case MNH_PWR_S4:
			ret = mnh_pwr_down();
			break;
		default:
			dev_err(mnh_pwr->dev, "%s: invalid state %d\n",
				__func__, system_state);
			ret = -EINVAL;
			break;
		}

		if (ret)
			dev_err(mnh_pwr->dev,
				"%s: state transition failed (%d)\n",
				__func__, ret);
		else
			dev_dbg(mnh_pwr->dev, "%s done with state: %d\n",
				__func__, system_state);
	} else {
		dev_dbg(mnh_pwr->dev, "%s: no state change needed\n", __func__);
	}

	mutex_unlock(&mnh_pwr->lock);

	return ret;
}
EXPORT_SYMBOL_GPL(mnh_pwr_set_state);

enum mnh_pwr_state mnh_pwr_get_state(void)
{
	enum mnh_pwr_state curr_state;

	mutex_lock(&mnh_pwr->lock);
	curr_state = mnh_pwr->state;
	mutex_unlock(&mnh_pwr->lock);

	return curr_state;
}
EXPORT_SYMBOL_GPL(mnh_pwr_get_state);

int mnh_pwr_init(struct platform_device *pdev, struct device *dev)
{
	int ret;

	/* allocate memory for mnh_pwr_data struct */
	mnh_pwr = devm_kzalloc(dev, sizeof(struct mnh_pwr_data), GFP_KERNEL);
	if (!mnh_pwr)
		return -ENOMEM;

	/* save a local copy of the device struct */
	mnh_pwr->pdev = pdev;
	mnh_pwr->dev = dev;

	/* initialize power state to powered down */
	mnh_pwr->state = MNH_PWR_S4;

	/* get platform resources */
	ret = mnh_pwr_get_resources();
	if (ret) {
		dev_err(dev, "%s: failed to get platform resources (%d)\n",
			__func__, ret);
		return ret;
	}

	/* initialize some structures */
	INIT_WORK(&mnh_pwr->shutdown_work, mnh_pwr_shutdown_work);
	mutex_init(&mnh_pwr->lock);

	/* power on the device to enumerate PCIe */
	ret = mnh_pwr_up(MNH_PWR_S0);
	if (ret) {
		dev_err(dev, "%s: failed initial power up (%d)", __func__, ret);
		return ret;
	}

	/* power down the device */
	ret = mnh_pwr_down();
	if (ret) {
		dev_err(dev, "%s: failed initial power down (%d)", __func__,
			ret);
		return ret;
	}

	return 0;
}
EXPORT_SYMBOL(mnh_pwr_init);
