Skip to content

Commit

Permalink
mtd: docg3: add suspend and resume
Browse files Browse the repository at this point in the history
Add functions to powerdown and powerup from suspend, in
order to save power.

Signed-off-by: Robert Jarzmik <[email protected]>
Reviewed-by: Ivan Djelic <[email protected]>
Reviewed-by: Mike Dunn <[email protected]>
Signed-off-by: David Woodhouse <[email protected]>
  • Loading branch information
rjarzmik authored and David Woodhouse committed Jan 9, 2012
1 parent d13d19e commit e4b2a96
Show file tree
Hide file tree
Showing 2 changed files with 80 additions and 1 deletion.
75 changes: 74 additions & 1 deletion drivers/mtd/devices/docg3.c
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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),
};

Expand Down
6 changes: 6 additions & 0 deletions drivers/mtd/devices/docg3.h
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,7 @@

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

/*
* Flash sequences
Expand Down Expand Up @@ -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
*/
Expand Down

0 comments on commit e4b2a96

Please sign in to comment.