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

Commit e4b2a96a authored by Robert Jarzmik's avatar Robert Jarzmik Committed by David Woodhouse
Browse files

mtd: docg3: add suspend and resume



Add functions to powerdown and powerup from suspend, in
order to save power.

Signed-off-by: default avatarRobert Jarzmik <robert.jarzmik@free.fr>
Reviewed-by: default avatarIvan Djelic <ivan.djelic@parrot.com>
Reviewed-by: default avatarMike Dunn <mikedunn@newsguy.com>
Signed-off-by: default avatarDavid Woodhouse <David.Woodhouse@intel.com>
parent d13d19ec
Loading
Loading
Loading
Loading
+74 −1
Original line number Diff line number Diff line
@@ -45,7 +45,6 @@
 * As no specification is available from M-Systems/Sandisk, this drivers lacks
 * several functions available on the chip, as :
 *  - IPL write
 *  - powerdown / powerup
 *
 * The bus data width (8bits versus 16bits) is not handled (if_cfg flag), and
 * the driver assumes a 16bits data bus.
@@ -1755,6 +1754,78 @@ static void doc_release_device(struct mtd_info *mtd)
	kfree(mtd);
}

/**
 * docg3_resume - Awakens docg3 floor
 * @pdev: platfrom device
 *
 * Returns 0 (always successfull)
 */
static int docg3_resume(struct platform_device *pdev)
{
	int i;
	struct mtd_info **docg3_floors, *mtd;
	struct docg3 *docg3;

	docg3_floors = platform_get_drvdata(pdev);
	mtd = docg3_floors[0];
	docg3 = mtd->priv;

	doc_dbg("docg3_resume()\n");
	for (i = 0; i < 12; i++)
		doc_readb(docg3, DOC_IOSPACE_IPL);
	return 0;
}

/**
 * docg3_suspend - Put in low power mode the docg3 floor
 * @pdev: platform device
 * @state: power state
 *
 * Shuts off most of docg3 circuitery to lower power consumption.
 *
 * Returns 0 if suspend succeeded, -EIO if chip refused suspend
 */
static int docg3_suspend(struct platform_device *pdev, pm_message_t state)
{
	int floor, i;
	struct mtd_info **docg3_floors, *mtd;
	struct docg3 *docg3;
	u8 ctrl, pwr_down;

	docg3_floors = platform_get_drvdata(pdev);
	for (floor = 0; floor < DOC_MAX_NBFLOORS; floor++) {
		mtd = docg3_floors[floor];
		if (!mtd)
			continue;
		docg3 = mtd->priv;

		doc_writeb(docg3, floor, DOC_DEVICESELECT);
		ctrl = doc_register_readb(docg3, DOC_FLASHCONTROL);
		ctrl &= ~DOC_CTRL_VIOLATION & ~DOC_CTRL_CE;
		doc_writeb(docg3, ctrl, DOC_FLASHCONTROL);

		for (i = 0; i < 10; i++) {
			usleep_range(3000, 4000);
			pwr_down = doc_register_readb(docg3, DOC_POWERMODE);
			if (pwr_down & DOC_POWERDOWN_READY)
				break;
		}
		if (pwr_down & DOC_POWERDOWN_READY) {
			doc_dbg("docg3_suspend(): floor %d powerdown ok\n",
				floor);
		} else {
			doc_err("docg3_suspend(): floor %d powerdown failed\n",
				floor);
			return -EIO;
		}
	}

	mtd = docg3_floors[0];
	docg3 = mtd->priv;
	doc_set_asic_mode(docg3, DOC_ASICMODE_POWERDOWN);
	return 0;
}

/**
 * doc_probe - Probe the IO space for a DiskOnChip G3 chip
 * @pdev: platform device
@@ -1860,6 +1931,8 @@ static struct platform_driver g3_driver = {
		.name	= "docg3",
		.owner	= THIS_MODULE,
	},
	.suspend	= docg3_suspend,
	.resume		= docg3_resume,
	.remove		= __exit_p(docg3_release),
};

+6 −0
Original line number Diff line number Diff line
@@ -127,6 +127,7 @@

#define DOC_ASICMODECONFIRM		0x1072
#define DOC_CHIPID_INV			0x1074
#define DOC_POWERMODE			0x107c

/*
 * Flash sequences
@@ -238,6 +239,11 @@
#define DOC_READADDR_ONE_BYTE		0x4000
#define DOC_READADDR_ADDR_MASK		0x1fff

/*
 * Flash register : DOC_POWERMODE
 */
#define DOC_POWERDOWN_READY		0x80

/*
 * Status of erase and write operation
 */