aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm
diff options
context:
space:
mode:
authorRichard Purdie <rpurdie@rpsys.net>2005-10-10 05:20:06 -0400
committerRussell King <rmk+kernel@arm.linux.org.uk>2005-10-10 05:20:06 -0400
commit7c3989885cfd37d237eca97832b712a7ffbbf40c (patch)
tree268bf1aeb7026eeceb7d70fb9c68d5d8de185c30 /arch/arm
parent1036260e93a907a0143efa31bf05be1f3271eb90 (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>
Diffstat (limited to 'arch/arm')
-rw-r--r--arch/arm/common/scoop.c20
1 files changed, 18 insertions, 2 deletions
diff --git a/arch/arm/common/scoop.c b/arch/arm/common/scoop.c
index d3a04c2a2c85..9e5245c702de 100644
--- a/arch/arm/common/scoop.c
+++ b/arch/arm/common/scoop.c
@@ -26,6 +26,8 @@ struct scoop_pcmcia_dev *scoop_devs;
26struct scoop_dev { 26struct scoop_dev {
27 void *base; 27 void *base;
28 spinlock_t scoop_lock; 28 spinlock_t scoop_lock;
29 unsigned short suspend_clr;
30 unsigned short suspend_set;
29 u32 scoop_gpwr; 31 u32 scoop_gpwr;
30}; 32};
31 33
@@ -90,14 +92,24 @@ EXPORT_SYMBOL(reset_scoop);
90EXPORT_SYMBOL(read_scoop_reg); 92EXPORT_SYMBOL(read_scoop_reg);
91EXPORT_SYMBOL(write_scoop_reg); 93EXPORT_SYMBOL(write_scoop_reg);
92 94
95static void check_scoop_reg(struct scoop_dev *sdev)
96{
97 unsigned short mcr;
98
99 mcr = SCOOP_REG(sdev->base, SCOOP_MCR);
100 if ((mcr & 0x100) == 0)
101 SCOOP_REG(sdev->base, SCOOP_MCR) = 0x0101;
102}
103
93#ifdef CONFIG_PM 104#ifdef CONFIG_PM
94static int scoop_suspend(struct device *dev, pm_message_t state, uint32_t level) 105static int scoop_suspend(struct device *dev, pm_message_t state, uint32_t level)
95{ 106{
96 if (level == SUSPEND_POWER_DOWN) { 107 if (level == SUSPEND_POWER_DOWN) {
97 struct scoop_dev *sdev = dev_get_drvdata(dev); 108 struct scoop_dev *sdev = dev_get_drvdata(dev);
98 109
99 sdev->scoop_gpwr = SCOOP_REG(sdev->base,SCOOP_GPWR); 110 check_scoop_reg(sdev);
100 SCOOP_REG(sdev->base,SCOOP_GPWR) = 0; 111 sdev->scoop_gpwr = SCOOP_REG(sdev->base, SCOOP_GPWR);
112 SCOOP_REG(sdev->base, SCOOP_GPWR) = (sdev->scoop_gpwr & ~sdev->suspend_clr) | sdev->suspend_set;
101 } 113 }
102 return 0; 114 return 0;
103} 115}
@@ -107,6 +119,7 @@ static int scoop_resume(struct device *dev, uint32_t level)
107 if (level == RESUME_POWER_ON) { 119 if (level == RESUME_POWER_ON) {
108 struct scoop_dev *sdev = dev_get_drvdata(dev); 120 struct scoop_dev *sdev = dev_get_drvdata(dev);
109 121
122 check_scoop_reg(sdev);
110 SCOOP_REG(sdev->base,SCOOP_GPWR) = sdev->scoop_gpwr; 123 SCOOP_REG(sdev->base,SCOOP_GPWR) = sdev->scoop_gpwr;
111 } 124 }
112 return 0; 125 return 0;
@@ -151,6 +164,9 @@ int __init scoop_probe(struct device *dev)
151 SCOOP_REG(devptr->base, SCOOP_GPCR) = inf->io_dir & 0xffff; 164 SCOOP_REG(devptr->base, SCOOP_GPCR) = inf->io_dir & 0xffff;
152 SCOOP_REG(devptr->base, SCOOP_GPWR) = inf->io_out & 0xffff; 165 SCOOP_REG(devptr->base, SCOOP_GPWR) = inf->io_out & 0xffff;
153 166
167 devptr->suspend_clr = inf->suspend_clr;
168 devptr->suspend_set = inf->suspend_set;
169
154 return 0; 170 return 0;
155} 171}
156 172