diff options
author | Damian Hobson-Garcia <dhobsong@igel.co.jp> | 2011-06-22 01:49:51 -0400 |
---|---|---|
committer | Laurent Pinchart <laurent.pinchart@ideasonboard.com> | 2011-08-19 02:11:18 -0400 |
commit | 0b3bb77c3a07a94d878fd3219302c46209f7d71c (patch) | |
tree | 4e5e443ce64fc8321c44cc7900694bdd8696dbd9 | |
parent | 0aa492be88b10b7b7621101df5fbf79f9236aecb (diff) |
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>
-rw-r--r-- | drivers/video/sh_mobile_meram.c | 71 |
1 files changed, 71 insertions, 0 deletions
diff --git a/drivers/video/sh_mobile_meram.c b/drivers/video/sh_mobile_meram.c index cfa1a78328aa..39f28a1aa074 100644 --- a/drivers/video/sh_mobile_meram.c +++ b/drivers/video/sh_mobile_meram.c | |||
@@ -37,12 +37,31 @@ | |||
37 | #define MEQSEL1 0x40 | 37 | #define MEQSEL1 0x40 |
38 | #define MEQSEL2 0x44 | 38 | #define MEQSEL2 0x44 |
39 | 39 | ||
40 | static unsigned long common_regs[] = { | ||
41 | MEVCR1, | ||
42 | MEQSEL1, | ||
43 | MEQSEL2, | ||
44 | }; | ||
45 | #define CMN_REGS_SIZE ARRAY_SIZE(common_regs) | ||
46 | |||
47 | static unsigned long icb_regs[] = { | ||
48 | MExxCTL, | ||
49 | MExxBSIZE, | ||
50 | MExxMNCF, | ||
51 | MExxSARA, | ||
52 | MExxSARB, | ||
53 | MExxSBSIZE, | ||
54 | }; | ||
55 | #define ICB_REGS_SIZE ARRAY_SIZE(icb_regs) | ||
56 | |||
40 | struct sh_mobile_meram_priv { | 57 | struct sh_mobile_meram_priv { |
41 | void __iomem *base; | 58 | void __iomem *base; |
42 | struct mutex lock; | 59 | struct mutex lock; |
43 | unsigned long used_icb; | 60 | unsigned long used_icb; |
44 | int used_meram_cache_regions; | 61 | int used_meram_cache_regions; |
45 | unsigned long used_meram_cache[SH_MOBILE_MERAM_ICB_NUM]; | 62 | unsigned long used_meram_cache[SH_MOBILE_MERAM_ICB_NUM]; |
63 | unsigned long cmn_saved_regs[CMN_REGS_SIZE]; | ||
64 | unsigned long icb_saved_regs[ICB_REGS_SIZE * SH_MOBILE_MERAM_ICB_NUM]; | ||
46 | }; | 65 | }; |
47 | 66 | ||
48 | /* settings */ | 67 | /* settings */ |
@@ -469,6 +488,57 @@ static int sh_mobile_meram_update(struct sh_mobile_meram_info *pdata, | |||
469 | return 0; | 488 | return 0; |
470 | } | 489 | } |
471 | 490 | ||
491 | static int sh_mobile_meram_runtime_suspend(struct device *dev) | ||
492 | { | ||
493 | struct platform_device *pdev = to_platform_device(dev); | ||
494 | struct sh_mobile_meram_priv *priv = platform_get_drvdata(pdev); | ||
495 | int k, j; | ||
496 | |||
497 | for (k = 0; k < CMN_REGS_SIZE; k++) | ||
498 | priv->cmn_saved_regs[k] = meram_read_reg(priv->base, | ||
499 | common_regs[k]); | ||
500 | |||
501 | for (j = 0; j < 32; j++) { | ||
502 | if (!test_bit(j, &priv->used_icb)) | ||
503 | continue; | ||
504 | for (k = 0; k < ICB_REGS_SIZE; k++) { | ||
505 | priv->icb_saved_regs[j * ICB_REGS_SIZE + k] = | ||
506 | meram_read_icb(priv->base, j, icb_regs[k]); | ||
507 | /* Reset ICB on resume */ | ||
508 | if (icb_regs[k] == MExxCTL) | ||
509 | priv->icb_saved_regs[j * ICB_REGS_SIZE + k] = | ||
510 | 0x70; | ||
511 | } | ||
512 | } | ||
513 | return 0; | ||
514 | } | ||
515 | |||
516 | static int sh_mobile_meram_runtime_resume(struct device *dev) | ||
517 | { | ||
518 | struct platform_device *pdev = to_platform_device(dev); | ||
519 | struct sh_mobile_meram_priv *priv = platform_get_drvdata(pdev); | ||
520 | int k, j; | ||
521 | |||
522 | for (j = 0; j < 32; j++) { | ||
523 | if (!test_bit(j, &priv->used_icb)) | ||
524 | continue; | ||
525 | for (k = 0; k < ICB_REGS_SIZE; k++) { | ||
526 | meram_write_icb(priv->base, j, icb_regs[k], | ||
527 | priv->icb_saved_regs[j * ICB_REGS_SIZE + k]); | ||
528 | } | ||
529 | } | ||
530 | |||
531 | for (k = 0; k < CMN_REGS_SIZE; k++) | ||
532 | meram_write_reg(priv->base, common_regs[k], | ||
533 | priv->cmn_saved_regs[k]); | ||
534 | return 0; | ||
535 | } | ||
536 | |||
537 | static const struct dev_pm_ops sh_mobile_meram_dev_pm_ops = { | ||
538 | .runtime_suspend = sh_mobile_meram_runtime_suspend, | ||
539 | .runtime_resume = sh_mobile_meram_runtime_resume, | ||
540 | }; | ||
541 | |||
472 | static struct sh_mobile_meram_ops sh_mobile_meram_ops = { | 542 | static struct sh_mobile_meram_ops sh_mobile_meram_ops = { |
473 | .module = THIS_MODULE, | 543 | .module = THIS_MODULE, |
474 | .meram_register = sh_mobile_meram_register, | 544 | .meram_register = sh_mobile_meram_register, |
@@ -557,6 +627,7 @@ static struct platform_driver sh_mobile_meram_driver = { | |||
557 | .driver = { | 627 | .driver = { |
558 | .name = "sh_mobile_meram", | 628 | .name = "sh_mobile_meram", |
559 | .owner = THIS_MODULE, | 629 | .owner = THIS_MODULE, |
630 | .pm = &sh_mobile_meram_dev_pm_ops, | ||
560 | }, | 631 | }, |
561 | .probe = sh_mobile_meram_probe, | 632 | .probe = sh_mobile_meram_probe, |
562 | .remove = sh_mobile_meram_remove, | 633 | .remove = sh_mobile_meram_remove, |