diff options
Diffstat (limited to 'arch')
-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 | ||