Commit 7c398988 authored by Richard Purdie's avatar Richard Purdie Committed by Russell King

[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: default avatarRichard Purdie <rpurdie@rpsys.net>
Signed-off-by: default avatarRussell King <rmk+kernel@arm.linux.org.uk>
parent 1036260e
...@@ -26,6 +26,8 @@ struct scoop_pcmcia_dev *scoop_devs; ...@@ -26,6 +26,8 @@ struct scoop_pcmcia_dev *scoop_devs;
struct scoop_dev { struct scoop_dev {
void *base; void *base;
spinlock_t scoop_lock; spinlock_t scoop_lock;
unsigned short suspend_clr;
unsigned short suspend_set;
u32 scoop_gpwr; u32 scoop_gpwr;
}; };
...@@ -90,14 +92,24 @@ EXPORT_SYMBOL(reset_scoop); ...@@ -90,14 +92,24 @@ EXPORT_SYMBOL(reset_scoop);
EXPORT_SYMBOL(read_scoop_reg); EXPORT_SYMBOL(read_scoop_reg);
EXPORT_SYMBOL(write_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 #ifdef CONFIG_PM
static int scoop_suspend(struct device *dev, pm_message_t state, uint32_t level) static int scoop_suspend(struct device *dev, pm_message_t state, uint32_t level)
{ {
if (level == SUSPEND_POWER_DOWN) { if (level == SUSPEND_POWER_DOWN) {
struct scoop_dev *sdev = dev_get_drvdata(dev); struct scoop_dev *sdev = dev_get_drvdata(dev);
sdev->scoop_gpwr = SCOOP_REG(sdev->base,SCOOP_GPWR); check_scoop_reg(sdev);
SCOOP_REG(sdev->base,SCOOP_GPWR) = 0; 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; return 0;
} }
...@@ -107,6 +119,7 @@ static int scoop_resume(struct device *dev, uint32_t level) ...@@ -107,6 +119,7 @@ static int scoop_resume(struct device *dev, uint32_t level)
if (level == RESUME_POWER_ON) { if (level == RESUME_POWER_ON) {
struct scoop_dev *sdev = dev_get_drvdata(dev); struct scoop_dev *sdev = dev_get_drvdata(dev);
check_scoop_reg(sdev);
SCOOP_REG(sdev->base,SCOOP_GPWR) = sdev->scoop_gpwr; SCOOP_REG(sdev->base,SCOOP_GPWR) = sdev->scoop_gpwr;
} }
return 0; return 0;
...@@ -151,6 +164,9 @@ int __init scoop_probe(struct device *dev) ...@@ -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_GPCR) = inf->io_dir & 0xffff;
SCOOP_REG(devptr->base, SCOOP_GPWR) = inf->io_out & 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; return 0;
} }
......
...@@ -38,6 +38,8 @@ ...@@ -38,6 +38,8 @@
struct scoop_config { struct scoop_config {
unsigned short io_out; unsigned short io_out;
unsigned short io_dir; unsigned short io_dir;
unsigned short suspend_clr;
unsigned short suspend_set;
}; };
/* Structure for linking scoop devices to PCMCIA sockets */ /* Structure for linking scoop devices to PCMCIA sockets */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment