diff options
author | Richard Purdie <rpurdie@rpsys.net> | 2005-10-10 10:20:06 +0100 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2005-10-10 10:20:06 +0100 |
commit | 7c3989885cfd37d237eca97832b712a7ffbbf40c (patch) | |
tree | 268bf1aeb7026eeceb7d70fb9c68d5d8de185c30 | |
parent | 1036260e93a907a0143efa31bf05be1f3271eb90 (diff) |
[ARM] 2962/1: scoop: Allow GPIO pin suspend state to be specified
Patch from Richard Purdie
Allow the GPIO pin suspend states to be specified for SCOOP devices.
This is needed for correct operation on the spitz platform.
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 | 20 | ||||
-rw-r--r-- | include/asm-arm/hardware/scoop.h | 2 |
2 files changed, 20 insertions, 2 deletions
diff --git a/arch/arm/common/scoop.c b/arch/arm/common/scoop.c index d3a04c2a2c8..9e5245c702d 100644 --- a/arch/arm/common/scoop.c +++ b/arch/arm/common/scoop.c @@ -26,6 +26,8 @@ struct scoop_pcmcia_dev *scoop_devs; struct scoop_dev { void *base; spinlock_t scoop_lock; + unsigned short suspend_clr; + unsigned short suspend_set; u32 scoop_gpwr; }; @@ -90,14 +92,24 @@ EXPORT_SYMBOL(reset_scoop); EXPORT_SYMBOL(read_scoop_reg); EXPORT_SYMBOL(write_scoop_reg); +static void check_scoop_reg(struct scoop_dev *sdev) +{ + unsigned short mcr; + + mcr = SCOOP_REG(sdev->base, SCOOP_MCR); + if ((mcr & 0x100) == 0) + SCOOP_REG(sdev->base, SCOOP_MCR) = 0x0101; +} + #ifdef CONFIG_PM static int scoop_suspend(struct device *dev, pm_message_t state, uint32_t level) { if (level == SUSPEND_POWER_DOWN) { struct scoop_dev *sdev = dev_get_drvdata(dev); - sdev->scoop_gpwr = SCOOP_REG(sdev->base,SCOOP_GPWR); - SCOOP_REG(sdev->base,SCOOP_GPWR) = 0; + check_scoop_reg(sdev); + sdev->scoop_gpwr = SCOOP_REG(sdev->base, SCOOP_GPWR); + SCOOP_REG(sdev->base, SCOOP_GPWR) = (sdev->scoop_gpwr & ~sdev->suspend_clr) | sdev->suspend_set; } return 0; } @@ -107,6 +119,7 @@ static int scoop_resume(struct device *dev, uint32_t level) if (level == RESUME_POWER_ON) { struct scoop_dev *sdev = dev_get_drvdata(dev); + check_scoop_reg(sdev); SCOOP_REG(sdev->base,SCOOP_GPWR) = sdev->scoop_gpwr; } return 0; @@ -151,6 +164,9 @@ int __init scoop_probe(struct device *dev) SCOOP_REG(devptr->base, SCOOP_GPCR) = inf->io_dir & 0xffff; SCOOP_REG(devptr->base, SCOOP_GPWR) = inf->io_out & 0xffff; + devptr->suspend_clr = inf->suspend_clr; + devptr->suspend_set = inf->suspend_set; + return 0; } diff --git a/include/asm-arm/hardware/scoop.h b/include/asm-arm/hardware/scoop.h index 527404b5a8d..a8f1013930e 100644 --- a/include/asm-arm/hardware/scoop.h +++ b/include/asm-arm/hardware/scoop.h @@ -38,6 +38,8 @@ struct scoop_config { unsigned short io_out; unsigned short io_dir; + unsigned short suspend_clr; + unsigned short suspend_set; }; /* Structure for linking scoop devices to PCMCIA sockets */ |