diff options
author | Richard Purdie <rpurdie@rpsys.net> | 2006-01-05 15:44:57 -0500 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2006-01-05 15:44:57 -0500 |
commit | 945b957972844881002ab4f68534581f4427a30b (patch) | |
tree | 0b9a1deb5094b847ce943b8f101386f373f472c6 | |
parent | 53b7c2b243bd31f857dddabd9339f2dd6ae3fb67 (diff) |
[ARM] 3230/1: Sharp Scoop: Fix Shared Power Control Issues
Patch from Richard Purdie
The SL-Cxx00 devices have a power control register in SCOOP that is
shared by both CF and MMC/SD card slots. The CF reset code was resetting
this register leading to various lockups as the MMC power was suddenly
lost. This patch handles the CPR register in a more sensitive manner.
It also removes some unneeded collie specific calls as the reset code
handles this.
Signed-off-by: Richard Purdie <rpurdie@rpsys.net>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
-rw-r--r-- | arch/arm/common/scoop.c | 2 | ||||
-rw-r--r-- | arch/arm/mach-pxa/spitz.c | 4 | ||||
-rw-r--r-- | drivers/pcmcia/pxa2xx_sharpsl.c | 24 |
3 files changed, 16 insertions, 14 deletions
diff --git a/arch/arm/common/scoop.c b/arch/arm/common/scoop.c index 0c3cbd9a388b..b6de43e73699 100644 --- a/arch/arm/common/scoop.c +++ b/arch/arm/common/scoop.c | |||
@@ -33,7 +33,6 @@ void reset_scoop(struct device *dev) | |||
33 | 33 | ||
34 | SCOOP_REG(sdev->base,SCOOP_MCR) = 0x0100; // 00 | 34 | SCOOP_REG(sdev->base,SCOOP_MCR) = 0x0100; // 00 |
35 | SCOOP_REG(sdev->base,SCOOP_CDR) = 0x0000; // 04 | 35 | SCOOP_REG(sdev->base,SCOOP_CDR) = 0x0000; // 04 |
36 | SCOOP_REG(sdev->base,SCOOP_CPR) = 0x0000; // 0C | ||
37 | SCOOP_REG(sdev->base,SCOOP_CCR) = 0x0000; // 10 | 36 | SCOOP_REG(sdev->base,SCOOP_CCR) = 0x0000; // 10 |
38 | SCOOP_REG(sdev->base,SCOOP_IMR) = 0x0000; // 18 | 37 | SCOOP_REG(sdev->base,SCOOP_IMR) = 0x0000; // 18 |
39 | SCOOP_REG(sdev->base,SCOOP_IRM) = 0x00FF; // 14 | 38 | SCOOP_REG(sdev->base,SCOOP_IRM) = 0x00FF; // 14 |
@@ -154,6 +153,7 @@ int __init scoop_probe(struct platform_device *pdev) | |||
154 | 153 | ||
155 | SCOOP_REG(devptr->base, SCOOP_MCR) = 0x0140; | 154 | SCOOP_REG(devptr->base, SCOOP_MCR) = 0x0140; |
156 | reset_scoop(&pdev->dev); | 155 | reset_scoop(&pdev->dev); |
156 | SCOOP_REG(devptr->base, SCOOP_CPR) = 0x0000; | ||
157 | SCOOP_REG(devptr->base, SCOOP_GPCR) = inf->io_dir & 0xffff; | 157 | SCOOP_REG(devptr->base, SCOOP_GPCR) = inf->io_dir & 0xffff; |
158 | SCOOP_REG(devptr->base, SCOOP_GPWR) = inf->io_out & 0xffff; | 158 | SCOOP_REG(devptr->base, SCOOP_GPWR) = inf->io_out & 0xffff; |
159 | 159 | ||
diff --git a/arch/arm/mach-pxa/spitz.c b/arch/arm/mach-pxa/spitz.c index 5d34abc64af7..f2007db0cda5 100644 --- a/arch/arm/mach-pxa/spitz.c +++ b/arch/arm/mach-pxa/spitz.c | |||
@@ -127,10 +127,12 @@ static void spitz_card_pwr_ctrl(int device, unsigned short new_cpr) | |||
127 | cpr &= ~0x0002; | 127 | cpr &= ~0x0002; |
128 | if (device == SPITZ_PWR_SD) | 128 | if (device == SPITZ_PWR_SD) |
129 | cpr &= ~0x0004; | 129 | cpr &= ~0x0004; |
130 | write_scoop_reg(&spitzscoop_device.dev, SCOOP_CPR, cpr | new_cpr); | ||
131 | if (!(cpr & 0x0002) && !(cpr & 0x0004)) { | 130 | if (!(cpr & 0x0002) && !(cpr & 0x0004)) { |
131 | write_scoop_reg(&spitzscoop_device.dev, SCOOP_CPR, 0x0000); | ||
132 | mdelay(1); | 132 | mdelay(1); |
133 | reset_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_CF_POWER); | 133 | reset_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_CF_POWER); |
134 | } else { | ||
135 | write_scoop_reg(&spitzscoop_device.dev, SCOOP_CPR, cpr | new_cpr); | ||
134 | } | 136 | } |
135 | } | 137 | } |
136 | } | 138 | } |
diff --git a/drivers/pcmcia/pxa2xx_sharpsl.c b/drivers/pcmcia/pxa2xx_sharpsl.c index 56c58831e80e..4fbd995360b0 100644 --- a/drivers/pcmcia/pxa2xx_sharpsl.c +++ b/drivers/pcmcia/pxa2xx_sharpsl.c | |||
@@ -36,9 +36,18 @@ | |||
36 | struct scoop_pcmcia_config *platform_scoop_config; | 36 | struct scoop_pcmcia_config *platform_scoop_config; |
37 | #define SCOOP_DEV platform_scoop_config->devs | 37 | #define SCOOP_DEV platform_scoop_config->devs |
38 | 38 | ||
39 | static void sharpsl_pcmcia_init_reset(struct scoop_pcmcia_dev *scoopdev) | 39 | static void sharpsl_pcmcia_init_reset(struct soc_pcmcia_socket *skt) |
40 | { | 40 | { |
41 | struct scoop_pcmcia_dev *scoopdev = &SCOOP_DEV[skt->nr]; | ||
42 | |||
41 | reset_scoop(scoopdev->dev); | 43 | reset_scoop(scoopdev->dev); |
44 | |||
45 | /* Shared power controls need to be handled carefully */ | ||
46 | if (platform_scoop_config->power_ctrl) | ||
47 | platform_scoop_config->power_ctrl(scoopdev->dev, 0x0000, skt->nr); | ||
48 | else | ||
49 | write_scoop_reg(scoopdev->dev, SCOOP_CPR, 0x0000); | ||
50 | |||
42 | scoopdev->keep_vs = NO_KEEP_VS; | 51 | scoopdev->keep_vs = NO_KEEP_VS; |
43 | scoopdev->keep_rd = 0; | 52 | scoopdev->keep_rd = 0; |
44 | } | 53 | } |
@@ -208,26 +217,17 @@ static int sharpsl_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, | |||
208 | 217 | ||
209 | static void sharpsl_pcmcia_socket_init(struct soc_pcmcia_socket *skt) | 218 | static void sharpsl_pcmcia_socket_init(struct soc_pcmcia_socket *skt) |
210 | { | 219 | { |
211 | sharpsl_pcmcia_init_reset(&SCOOP_DEV[skt->nr]); | 220 | sharpsl_pcmcia_init_reset(skt); |
212 | 221 | ||
213 | /* Enable interrupt */ | 222 | /* Enable interrupt */ |
214 | write_scoop_reg(SCOOP_DEV[skt->nr].dev, SCOOP_IMR, 0x00C0); | 223 | write_scoop_reg(SCOOP_DEV[skt->nr].dev, SCOOP_IMR, 0x00C0); |
215 | write_scoop_reg(SCOOP_DEV[skt->nr].dev, SCOOP_MCR, 0x0101); | 224 | write_scoop_reg(SCOOP_DEV[skt->nr].dev, SCOOP_MCR, 0x0101); |
216 | SCOOP_DEV[skt->nr].keep_vs = NO_KEEP_VS; | 225 | SCOOP_DEV[skt->nr].keep_vs = NO_KEEP_VS; |
217 | |||
218 | if (machine_is_collie()) | ||
219 | /* We need to disable SS_OUTPUT_ENA here. */ | ||
220 | write_scoop_reg(SCOOP_DEV[skt->nr].dev, SCOOP_CPR, read_scoop_reg(SCOOP_DEV[skt->nr].dev, SCOOP_CPR) & ~0x0080); | ||
221 | } | 226 | } |
222 | 227 | ||
223 | static void sharpsl_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt) | 228 | static void sharpsl_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt) |
224 | { | 229 | { |
225 | /* CF_BUS_OFF */ | 230 | sharpsl_pcmcia_init_reset(skt); |
226 | sharpsl_pcmcia_init_reset(&SCOOP_DEV[skt->nr]); | ||
227 | |||
228 | if (machine_is_collie()) | ||
229 | /* We need to disable SS_OUTPUT_ENA here. */ | ||
230 | write_scoop_reg(SCOOP_DEV[skt->nr].dev, SCOOP_CPR, read_scoop_reg(SCOOP_DEV[skt->nr].dev, SCOOP_CPR) & ~0x0080); | ||
231 | } | 231 | } |
232 | 232 | ||
233 | static struct pcmcia_low_level sharpsl_pcmcia_ops = { | 233 | static struct pcmcia_low_level sharpsl_pcmcia_ops = { |