mirror of
https://github.com/torvalds/linux
synced 2024-09-21 19:47:35 +00:00
fbdev: sh_mobile_meram: Backup/restore device registers on shutdown/resume
Save and reconfigure the MERAM registers when the MERAM is powered down and restored Signed-off-by: Damian Hobson-Garcia <dhobsong@igel.co.jp>
This commit is contained in:
parent
0aa492be88
commit
0b3bb77c3a
|
@ -37,12 +37,31 @@
|
||||||
#define MEQSEL1 0x40
|
#define MEQSEL1 0x40
|
||||||
#define MEQSEL2 0x44
|
#define MEQSEL2 0x44
|
||||||
|
|
||||||
|
static unsigned long common_regs[] = {
|
||||||
|
MEVCR1,
|
||||||
|
MEQSEL1,
|
||||||
|
MEQSEL2,
|
||||||
|
};
|
||||||
|
#define CMN_REGS_SIZE ARRAY_SIZE(common_regs)
|
||||||
|
|
||||||
|
static unsigned long icb_regs[] = {
|
||||||
|
MExxCTL,
|
||||||
|
MExxBSIZE,
|
||||||
|
MExxMNCF,
|
||||||
|
MExxSARA,
|
||||||
|
MExxSARB,
|
||||||
|
MExxSBSIZE,
|
||||||
|
};
|
||||||
|
#define ICB_REGS_SIZE ARRAY_SIZE(icb_regs)
|
||||||
|
|
||||||
struct sh_mobile_meram_priv {
|
struct sh_mobile_meram_priv {
|
||||||
void __iomem *base;
|
void __iomem *base;
|
||||||
struct mutex lock;
|
struct mutex lock;
|
||||||
unsigned long used_icb;
|
unsigned long used_icb;
|
||||||
int used_meram_cache_regions;
|
int used_meram_cache_regions;
|
||||||
unsigned long used_meram_cache[SH_MOBILE_MERAM_ICB_NUM];
|
unsigned long used_meram_cache[SH_MOBILE_MERAM_ICB_NUM];
|
||||||
|
unsigned long cmn_saved_regs[CMN_REGS_SIZE];
|
||||||
|
unsigned long icb_saved_regs[ICB_REGS_SIZE * SH_MOBILE_MERAM_ICB_NUM];
|
||||||
};
|
};
|
||||||
|
|
||||||
/* settings */
|
/* settings */
|
||||||
|
@ -469,6 +488,57 @@ static int sh_mobile_meram_update(struct sh_mobile_meram_info *pdata,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int sh_mobile_meram_runtime_suspend(struct device *dev)
|
||||||
|
{
|
||||||
|
struct platform_device *pdev = to_platform_device(dev);
|
||||||
|
struct sh_mobile_meram_priv *priv = platform_get_drvdata(pdev);
|
||||||
|
int k, j;
|
||||||
|
|
||||||
|
for (k = 0; k < CMN_REGS_SIZE; k++)
|
||||||
|
priv->cmn_saved_regs[k] = meram_read_reg(priv->base,
|
||||||
|
common_regs[k]);
|
||||||
|
|
||||||
|
for (j = 0; j < 32; j++) {
|
||||||
|
if (!test_bit(j, &priv->used_icb))
|
||||||
|
continue;
|
||||||
|
for (k = 0; k < ICB_REGS_SIZE; k++) {
|
||||||
|
priv->icb_saved_regs[j * ICB_REGS_SIZE + k] =
|
||||||
|
meram_read_icb(priv->base, j, icb_regs[k]);
|
||||||
|
/* Reset ICB on resume */
|
||||||
|
if (icb_regs[k] == MExxCTL)
|
||||||
|
priv->icb_saved_regs[j * ICB_REGS_SIZE + k] =
|
||||||
|
0x70;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int sh_mobile_meram_runtime_resume(struct device *dev)
|
||||||
|
{
|
||||||
|
struct platform_device *pdev = to_platform_device(dev);
|
||||||
|
struct sh_mobile_meram_priv *priv = platform_get_drvdata(pdev);
|
||||||
|
int k, j;
|
||||||
|
|
||||||
|
for (j = 0; j < 32; j++) {
|
||||||
|
if (!test_bit(j, &priv->used_icb))
|
||||||
|
continue;
|
||||||
|
for (k = 0; k < ICB_REGS_SIZE; k++) {
|
||||||
|
meram_write_icb(priv->base, j, icb_regs[k],
|
||||||
|
priv->icb_saved_regs[j * ICB_REGS_SIZE + k]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (k = 0; k < CMN_REGS_SIZE; k++)
|
||||||
|
meram_write_reg(priv->base, common_regs[k],
|
||||||
|
priv->cmn_saved_regs[k]);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct dev_pm_ops sh_mobile_meram_dev_pm_ops = {
|
||||||
|
.runtime_suspend = sh_mobile_meram_runtime_suspend,
|
||||||
|
.runtime_resume = sh_mobile_meram_runtime_resume,
|
||||||
|
};
|
||||||
|
|
||||||
static struct sh_mobile_meram_ops sh_mobile_meram_ops = {
|
static struct sh_mobile_meram_ops sh_mobile_meram_ops = {
|
||||||
.module = THIS_MODULE,
|
.module = THIS_MODULE,
|
||||||
.meram_register = sh_mobile_meram_register,
|
.meram_register = sh_mobile_meram_register,
|
||||||
|
@ -557,6 +627,7 @@ static struct platform_driver sh_mobile_meram_driver = {
|
||||||
.driver = {
|
.driver = {
|
||||||
.name = "sh_mobile_meram",
|
.name = "sh_mobile_meram",
|
||||||
.owner = THIS_MODULE,
|
.owner = THIS_MODULE,
|
||||||
|
.pm = &sh_mobile_meram_dev_pm_ops,
|
||||||
},
|
},
|
||||||
.probe = sh_mobile_meram_probe,
|
.probe = sh_mobile_meram_probe,
|
||||||
.remove = sh_mobile_meram_remove,
|
.remove = sh_mobile_meram_remove,
|
||||||
|
|
Loading…
Reference in a new issue