summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRichard Purdie <rpurdie@rpsys.net>2006-01-05 21:44:57 +0100
committerRussell King <rmk+kernel@arm.linux.org.uk>2006-01-05 21:44:57 +0100
commit945b957972844881002ab4f68534581f4427a30b (patch)
tree0b9a1deb5094b847ce943b8f101386f373f472c6
parent[ARM] 3229/1: Remove uneeded ARM apm dependency on PM_LEGACY (diff)
downloadlinux-945b957972844881002ab4f68534581f4427a30b.tar.xz
linux-945b957972844881002ab4f68534581f4427a30b.zip
[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.c2
-rw-r--r--arch/arm/mach-pxa/spitz.c4
-rw-r--r--drivers/pcmcia/pxa2xx_sharpsl.c24
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)
SCOOP_REG(sdev->base,SCOOP_MCR) = 0x0100; // 00
SCOOP_REG(sdev->base,SCOOP_CDR) = 0x0000; // 04
- SCOOP_REG(sdev->base,SCOOP_CPR) = 0x0000; // 0C
SCOOP_REG(sdev->base,SCOOP_CCR) = 0x0000; // 10
SCOOP_REG(sdev->base,SCOOP_IMR) = 0x0000; // 18
SCOOP_REG(sdev->base,SCOOP_IRM) = 0x00FF; // 14
@@ -154,6 +153,7 @@ int __init scoop_probe(struct platform_device *pdev)
SCOOP_REG(devptr->base, SCOOP_MCR) = 0x0140;
reset_scoop(&pdev->dev);
+ SCOOP_REG(devptr->base, SCOOP_CPR) = 0x0000;
SCOOP_REG(devptr->base, SCOOP_GPCR) = inf->io_dir & 0xffff;
SCOOP_REG(devptr->base, SCOOP_GPWR) = inf->io_out & 0xffff;
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)
cpr &= ~0x0002;
if (device == SPITZ_PWR_SD)
cpr &= ~0x0004;
- write_scoop_reg(&spitzscoop_device.dev, SCOOP_CPR, cpr | new_cpr);
if (!(cpr & 0x0002) && !(cpr & 0x0004)) {
+ write_scoop_reg(&spitzscoop_device.dev, SCOOP_CPR, 0x0000);
mdelay(1);
reset_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_CF_POWER);
+ } else {
+ write_scoop_reg(&spitzscoop_device.dev, SCOOP_CPR, cpr | new_cpr);
}
}
}
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 @@
struct scoop_pcmcia_config *platform_scoop_config;
#define SCOOP_DEV platform_scoop_config->devs
-static void sharpsl_pcmcia_init_reset(struct scoop_pcmcia_dev *scoopdev)
+static void sharpsl_pcmcia_init_reset(struct soc_pcmcia_socket *skt)
{
+ struct scoop_pcmcia_dev *scoopdev = &SCOOP_DEV[skt->nr];
+
reset_scoop(scoopdev->dev);
+
+ /* Shared power controls need to be handled carefully */
+ if (platform_scoop_config->power_ctrl)
+ platform_scoop_config->power_ctrl(scoopdev->dev, 0x0000, skt->nr);
+ else
+ write_scoop_reg(scoopdev->dev, SCOOP_CPR, 0x0000);
+
scoopdev->keep_vs = NO_KEEP_VS;
scoopdev->keep_rd = 0;
}
@@ -208,26 +217,17 @@ static int sharpsl_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
static void sharpsl_pcmcia_socket_init(struct soc_pcmcia_socket *skt)
{
- sharpsl_pcmcia_init_reset(&SCOOP_DEV[skt->nr]);
+ sharpsl_pcmcia_init_reset(skt);
/* Enable interrupt */
write_scoop_reg(SCOOP_DEV[skt->nr].dev, SCOOP_IMR, 0x00C0);
write_scoop_reg(SCOOP_DEV[skt->nr].dev, SCOOP_MCR, 0x0101);
SCOOP_DEV[skt->nr].keep_vs = NO_KEEP_VS;
-
- if (machine_is_collie())
- /* We need to disable SS_OUTPUT_ENA here. */
- write_scoop_reg(SCOOP_DEV[skt->nr].dev, SCOOP_CPR, read_scoop_reg(SCOOP_DEV[skt->nr].dev, SCOOP_CPR) & ~0x0080);
}
static void sharpsl_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt)
{
- /* CF_BUS_OFF */
- sharpsl_pcmcia_init_reset(&SCOOP_DEV[skt->nr]);
-
- if (machine_is_collie())
- /* We need to disable SS_OUTPUT_ENA here. */
- write_scoop_reg(SCOOP_DEV[skt->nr].dev, SCOOP_CPR, read_scoop_reg(SCOOP_DEV[skt->nr].dev, SCOOP_CPR) & ~0x0080);
+ sharpsl_pcmcia_init_reset(skt);
}
static struct pcmcia_low_level sharpsl_pcmcia_ops = {