Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 026918e7 authored by Huang Shijie's avatar Huang Shijie Committed by Brian Norris
Browse files

mtd: nand: gpmi: add gpmi dsm supend/resume support



i.MX6SX supports deep sleep mode(DSM) that may turn off GPMI/BCH power
during suspend, add gpmi nand suspend/resume function to release DMA
channel in suspend function and re-init GPMI/BCH controller during
resume function.

Although it is not necessary to restore GPMI/BCH registers value for
i.MX6QDL, the code doesn't distinguish different platforms to keep the
code simple.

Signed-off-by: default avatarHuang Shijie <b32955@freescale.com>
Signed-off-by: default avatarHan Xu <han.xu@freescale.com>
Signed-off-by: default avatarBrian Norris <computersforpeace@gmail.com>
parent 36bcc0c9
Loading
Loading
Loading
Loading
+46 −1
Original line number Diff line number Diff line
/*
 * Freescale GPMI NAND Flash Driver
 *
 * Copyright (C) 2010-2011 Freescale Semiconductor, Inc.
 * Copyright (C) 2010-2015 Freescale Semiconductor, Inc.
 * Copyright (C) 2008 Embedded Alley Solutions, Inc.
 *
 * This program is free software; you can redistribute it and/or modify
@@ -2033,9 +2033,54 @@ static int gpmi_nand_remove(struct platform_device *pdev)
	return 0;
}

#ifdef CONFIG_PM_SLEEP
static int gpmi_pm_suspend(struct device *dev)
{
	struct gpmi_nand_data *this = dev_get_drvdata(dev);

	release_dma_channels(this);
	return 0;
}

static int gpmi_pm_resume(struct device *dev)
{
	struct gpmi_nand_data *this = dev_get_drvdata(dev);
	int ret;

	ret = acquire_dma_channels(this);
	if (ret < 0)
		return ret;

	/* re-init the GPMI registers */
	this->flags &= ~GPMI_TIMING_INIT_OK;
	ret = gpmi_init(this);
	if (ret) {
		dev_err(this->dev, "Error setting GPMI : %d\n", ret);
		return ret;
	}

	/* re-init the BCH registers */
	ret = bch_set_geometry(this);
	if (ret) {
		dev_err(this->dev, "Error setting BCH : %d\n", ret);
		return ret;
	}

	/* re-init others */
	gpmi_extra_init(this);

	return 0;
}
#endif /* CONFIG_PM_SLEEP */

static const struct dev_pm_ops gpmi_pm_ops = {
	SET_SYSTEM_SLEEP_PM_OPS(gpmi_pm_suspend, gpmi_pm_resume)
};

static struct platform_driver gpmi_nand_driver = {
	.driver = {
		.name = "gpmi-nand",
		.pm = &gpmi_pm_ops,
		.of_match_table = gpmi_nand_id_table,
	},
	.probe   = gpmi_nand_probe,