diff options
author | Richard Purdie <rpurdie@rpsys.net> | 2005-10-10 05:20:06 -0400 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2005-10-10 05:20:06 -0400 |
commit | 7c3989885cfd37d237eca97832b712a7ffbbf40c (patch) | |
tree | 268bf1aeb7026eeceb7d70fb9c68d5d8de185c30 /arch/arm/common/scoop.c | |
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>
Diffstat (limited to 'arch/arm/common/scoop.c')
-rw-r--r-- | arch/arm/common/scoop.c | 20 |
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; | |||
26 | struct scoop_dev { | 26 | struct 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); | |||
90 | EXPORT_SYMBOL(read_scoop_reg); | 92 | EXPORT_SYMBOL(read_scoop_reg); |
91 | EXPORT_SYMBOL(write_scoop_reg); | 93 | EXPORT_SYMBOL(write_scoop_reg); |
92 | 94 | ||
95 | static 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 |
94 | static int scoop_suspend(struct device *dev, pm_message_t state, uint32_t level) | 105 | static 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 | ||