diff options
| author | Tim Yamin <plasm@roo.me.uk> | 2008-06-17 04:33:14 -0400 |
|---|---|---|
| committer | Grant Likely <grant.likely@secretlab.ca> | 2008-07-01 18:08:24 -0400 |
| commit | 18d76ac9a47742558bca3bbc2f7c41870ac744c8 (patch) | |
| tree | 0073d1050be578b4f71f3f67f303f06cee1d4494 /arch | |
| parent | 1702b52092e9a6d05398d3f9581ddc050ef00d06 (diff) | |
powerpc/mpc5200: Fix lite5200b suspend/resume
Suspend/resume ("echo mem > /sys/power/state") does not work with
vanilla kernels -- the system does not suspend correctly and just
hangs. This patch fixes this so suspend/resume works:
1) of_iomap does not map the whole 0xC000 of the MPC5200 immr so
saving registers does not work.
2) PCI registers need to be saved and restored.
Signed-off-by: Tim Yamin <plasm@roo.me.uk>
Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
Diffstat (limited to 'arch')
| -rw-r--r-- | arch/powerpc/platforms/52xx/lite5200_pm.c | 14 |
1 files changed, 13 insertions, 1 deletions
diff --git a/arch/powerpc/platforms/52xx/lite5200_pm.c b/arch/powerpc/platforms/52xx/lite5200_pm.c index 41c7fd91e99e..fe92e65103ed 100644 --- a/arch/powerpc/platforms/52xx/lite5200_pm.c +++ b/arch/powerpc/platforms/52xx/lite5200_pm.c | |||
| @@ -14,6 +14,7 @@ static struct mpc52xx_sdma __iomem *bes; | |||
| 14 | static struct mpc52xx_xlb __iomem *xlb; | 14 | static struct mpc52xx_xlb __iomem *xlb; |
| 15 | static struct mpc52xx_gpio __iomem *gps; | 15 | static struct mpc52xx_gpio __iomem *gps; |
| 16 | static struct mpc52xx_gpio_wkup __iomem *gpw; | 16 | static struct mpc52xx_gpio_wkup __iomem *gpw; |
| 17 | static void __iomem *pci; | ||
| 17 | static void __iomem *sram; | 18 | static void __iomem *sram; |
| 18 | static const int sram_size = 0x4000; /* 16 kBytes */ | 19 | static const int sram_size = 0x4000; /* 16 kBytes */ |
| 19 | static void __iomem *mbar; | 20 | static void __iomem *mbar; |
| @@ -50,6 +51,8 @@ static int lite5200_pm_prepare(void) | |||
| 50 | { .type = "builtin", .compatible = "mpc5200", }, /* efika */ | 51 | { .type = "builtin", .compatible = "mpc5200", }, /* efika */ |
| 51 | {} | 52 | {} |
| 52 | }; | 53 | }; |
| 54 | u64 regaddr64 = 0; | ||
| 55 | const u32 *regaddr_p; | ||
| 53 | 56 | ||
| 54 | /* deep sleep? let mpc52xx code handle that */ | 57 | /* deep sleep? let mpc52xx code handle that */ |
| 55 | if (lite5200_pm_target_state == PM_SUSPEND_STANDBY) | 58 | if (lite5200_pm_target_state == PM_SUSPEND_STANDBY) |
| @@ -60,8 +63,12 @@ static int lite5200_pm_prepare(void) | |||
| 60 | 63 | ||
| 61 | /* map registers */ | 64 | /* map registers */ |
| 62 | np = of_find_matching_node(NULL, immr_ids); | 65 | np = of_find_matching_node(NULL, immr_ids); |
| 63 | mbar = of_iomap(np, 0); | 66 | regaddr_p = of_get_address(np, 0, NULL, NULL); |
| 67 | if (regaddr_p) | ||
| 68 | regaddr64 = of_translate_address(np, regaddr_p); | ||
| 64 | of_node_put(np); | 69 | of_node_put(np); |
| 70 | |||
| 71 | mbar = ioremap((u32) regaddr64, 0xC000); | ||
| 65 | if (!mbar) { | 72 | if (!mbar) { |
| 66 | printk(KERN_ERR "%s:%i Error mapping registers\n", __func__, __LINE__); | 73 | printk(KERN_ERR "%s:%i Error mapping registers\n", __func__, __LINE__); |
| 67 | return -ENOSYS; | 74 | return -ENOSYS; |
| @@ -71,6 +78,7 @@ static int lite5200_pm_prepare(void) | |||
| 71 | pic = mbar + 0x500; | 78 | pic = mbar + 0x500; |
| 72 | gps = mbar + 0xb00; | 79 | gps = mbar + 0xb00; |
| 73 | gpw = mbar + 0xc00; | 80 | gpw = mbar + 0xc00; |
| 81 | pci = mbar + 0xd00; | ||
| 74 | bes = mbar + 0x1200; | 82 | bes = mbar + 0x1200; |
| 75 | xlb = mbar + 0x1f00; | 83 | xlb = mbar + 0x1f00; |
| 76 | sram = mbar + 0x8000; | 84 | sram = mbar + 0x8000; |
| @@ -85,6 +93,7 @@ static struct mpc52xx_sdma sbes; | |||
| 85 | static struct mpc52xx_xlb sxlb; | 93 | static struct mpc52xx_xlb sxlb; |
| 86 | static struct mpc52xx_gpio sgps; | 94 | static struct mpc52xx_gpio sgps; |
| 87 | static struct mpc52xx_gpio_wkup sgpw; | 95 | static struct mpc52xx_gpio_wkup sgpw; |
| 96 | static char spci[0x200]; | ||
| 88 | 97 | ||
| 89 | static void lite5200_save_regs(void) | 98 | static void lite5200_save_regs(void) |
| 90 | { | 99 | { |
| @@ -94,6 +103,7 @@ static void lite5200_save_regs(void) | |||
| 94 | _memcpy_fromio(&sxlb, xlb, sizeof(*xlb)); | 103 | _memcpy_fromio(&sxlb, xlb, sizeof(*xlb)); |
| 95 | _memcpy_fromio(&sgps, gps, sizeof(*gps)); | 104 | _memcpy_fromio(&sgps, gps, sizeof(*gps)); |
| 96 | _memcpy_fromio(&sgpw, gpw, sizeof(*gpw)); | 105 | _memcpy_fromio(&sgpw, gpw, sizeof(*gpw)); |
| 106 | _memcpy_fromio(spci, pci, 0x200); | ||
| 97 | 107 | ||
| 98 | _memcpy_fromio(saved_sram, sram, sram_size); | 108 | _memcpy_fromio(saved_sram, sram, sram_size); |
| 99 | } | 109 | } |
| @@ -103,6 +113,8 @@ static void lite5200_restore_regs(void) | |||
| 103 | int i; | 113 | int i; |
| 104 | _memcpy_toio(sram, saved_sram, sram_size); | 114 | _memcpy_toio(sram, saved_sram, sram_size); |
| 105 | 115 | ||
| 116 | /* PCI Configuration */ | ||
| 117 | _memcpy_toio(pci, spci, 0x200); | ||
| 106 | 118 | ||
| 107 | /* | 119 | /* |
| 108 | * GPIOs. Interrupt Master Enable has higher address then other | 120 | * GPIOs. Interrupt Master Enable has higher address then other |
