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/powerpc | |
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/powerpc')
-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 |