aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-pxa/ssp.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mach-pxa/ssp.c')
-rw-r--r--arch/arm/mach-pxa/ssp.c77
1 files changed, 49 insertions, 28 deletions
diff --git a/arch/arm/mach-pxa/ssp.c b/arch/arm/mach-pxa/ssp.c
index 0225ee016f2d..b6d37fa7b85f 100644
--- a/arch/arm/mach-pxa/ssp.c
+++ b/arch/arm/mach-pxa/ssp.c
@@ -48,9 +48,11 @@
48static irqreturn_t ssp_interrupt(int irq, void *dev_id) 48static irqreturn_t ssp_interrupt(int irq, void *dev_id)
49{ 49{
50 struct ssp_dev *dev = (struct ssp_dev*) dev_id; 50 struct ssp_dev *dev = (struct ssp_dev*) dev_id;
51 unsigned int status = SSSR_P(dev->port); 51 struct ssp_device *ssp = dev->ssp;
52 unsigned int status;
52 53
53 SSSR_P(dev->port) = status; /* clear status bits */ 54 status = __raw_readl(ssp->mmio_base + SSSR);
55 __raw_writel(status, ssp->mmio_base + SSSR);
54 56
55 if (status & SSSR_ROR) 57 if (status & SSSR_ROR)
56 printk(KERN_WARNING "SSP(%d): receiver overrun\n", dev->port); 58 printk(KERN_WARNING "SSP(%d): receiver overrun\n", dev->port);
@@ -79,15 +81,16 @@ static irqreturn_t ssp_interrupt(int irq, void *dev_id)
79 */ 81 */
80int ssp_write_word(struct ssp_dev *dev, u32 data) 82int ssp_write_word(struct ssp_dev *dev, u32 data)
81{ 83{
84 struct ssp_device *ssp = dev->ssp;
82 int timeout = TIMEOUT; 85 int timeout = TIMEOUT;
83 86
84 while (!(SSSR_P(dev->port) & SSSR_TNF)) { 87 while (!(__raw_readl(ssp->mmio_base + SSSR) & SSSR_TNF)) {
85 if (!--timeout) 88 if (!--timeout)
86 return -ETIMEDOUT; 89 return -ETIMEDOUT;
87 cpu_relax(); 90 cpu_relax();
88 } 91 }
89 92
90 SSDR_P(dev->port) = data; 93 __raw_writel(data, ssp->mmio_base + SSDR);
91 94
92 return 0; 95 return 0;
93} 96}
@@ -109,15 +112,16 @@ int ssp_write_word(struct ssp_dev *dev, u32 data)
109 */ 112 */
110int ssp_read_word(struct ssp_dev *dev, u32 *data) 113int ssp_read_word(struct ssp_dev *dev, u32 *data)
111{ 114{
115 struct ssp_device *ssp = dev->ssp;
112 int timeout = TIMEOUT; 116 int timeout = TIMEOUT;
113 117
114 while (!(SSSR_P(dev->port) & SSSR_RNE)) { 118 while (!(__raw_readl(ssp->mmio_base + SSSR) & SSSR_RNE)) {
115 if (!--timeout) 119 if (!--timeout)
116 return -ETIMEDOUT; 120 return -ETIMEDOUT;
117 cpu_relax(); 121 cpu_relax();
118 } 122 }
119 123
120 *data = SSDR_P(dev->port); 124 *data = __raw_readl(ssp->mmio_base + SSDR);
121 return 0; 125 return 0;
122} 126}
123 127
@@ -131,17 +135,18 @@ int ssp_read_word(struct ssp_dev *dev, u32 *data)
131 */ 135 */
132int ssp_flush(struct ssp_dev *dev) 136int ssp_flush(struct ssp_dev *dev)
133{ 137{
138 struct ssp_device *ssp = dev->ssp;
134 int timeout = TIMEOUT * 2; 139 int timeout = TIMEOUT * 2;
135 140
136 do { 141 do {
137 while (SSSR_P(dev->port) & SSSR_RNE) { 142 while (__raw_readl(ssp->mmio_base + SSSR) & SSSR_RNE) {
138 if (!--timeout) 143 if (!--timeout)
139 return -ETIMEDOUT; 144 return -ETIMEDOUT;
140 (void) SSDR_P(dev->port); 145 (void)__raw_readl(ssp->mmio_base + SSDR);
141 } 146 }
142 if (!--timeout) 147 if (!--timeout)
143 return -ETIMEDOUT; 148 return -ETIMEDOUT;
144 } while (SSSR_P(dev->port) & SSSR_BSY); 149 } while (__raw_readl(ssp->mmio_base + SSSR) & SSSR_BSY);
145 150
146 return 0; 151 return 0;
147} 152}
@@ -153,7 +158,12 @@ int ssp_flush(struct ssp_dev *dev)
153 */ 158 */
154void ssp_enable(struct ssp_dev *dev) 159void ssp_enable(struct ssp_dev *dev)
155{ 160{
156 SSCR0_P(dev->port) |= SSCR0_SSE; 161 struct ssp_device *ssp = dev->ssp;
162 uint32_t sscr0;
163
164 sscr0 = __raw_readl(ssp->mmio_base + SSCR0);
165 sscr0 |= SSCR0_SSE;
166 __raw_writel(sscr0, ssp->mmio_base + SSCR0);
157} 167}
158 168
159/** 169/**
@@ -163,7 +173,12 @@ void ssp_enable(struct ssp_dev *dev)
163 */ 173 */
164void ssp_disable(struct ssp_dev *dev) 174void ssp_disable(struct ssp_dev *dev)
165{ 175{
166 SSCR0_P(dev->port) &= ~SSCR0_SSE; 176 struct ssp_device *ssp = dev->ssp;
177 uint32_t sscr0;
178
179 sscr0 = __raw_readl(ssp->mmio_base + SSCR0);
180 sscr0 &= ~SSCR0_SSE;
181 __raw_writel(sscr0, ssp->mmio_base + SSCR0);
167} 182}
168 183
169/** 184/**
@@ -172,14 +187,16 @@ void ssp_disable(struct ssp_dev *dev)
172 * 187 *
173 * Save the configured SSP state for suspend. 188 * Save the configured SSP state for suspend.
174 */ 189 */
175void ssp_save_state(struct ssp_dev *dev, struct ssp_state *ssp) 190void ssp_save_state(struct ssp_dev *dev, struct ssp_state *state)
176{ 191{
177 ssp->cr0 = SSCR0_P(dev->port); 192 struct ssp_device *ssp = dev->ssp;
178 ssp->cr1 = SSCR1_P(dev->port); 193
179 ssp->to = SSTO_P(dev->port); 194 state->cr0 = __raw_readl(ssp->mmio_base + SSCR0);
180 ssp->psp = SSPSP_P(dev->port); 195 state->cr1 = __raw_readl(ssp->mmio_base + SSCR1);
196 state->to = __raw_readl(ssp->mmio_base + SSTO);
197 state->psp = __raw_readl(ssp->mmio_base + SSPSP);
181 198
182 SSCR0_P(dev->port) &= ~SSCR0_SSE; 199 ssp_disable(dev);
183} 200}
184 201
185/** 202/**
@@ -188,16 +205,18 @@ void ssp_save_state(struct ssp_dev *dev, struct ssp_state *ssp)
188 * 205 *
189 * Restore the SSP configuration saved previously by ssp_save_state. 206 * Restore the SSP configuration saved previously by ssp_save_state.
190 */ 207 */
191void ssp_restore_state(struct ssp_dev *dev, struct ssp_state *ssp) 208void ssp_restore_state(struct ssp_dev *dev, struct ssp_state *state)
192{ 209{
193 SSSR_P(dev->port) = SSSR_ROR | SSSR_TUR | SSSR_BCE; 210 struct ssp_device *ssp = dev->ssp;
211 uint32_t sssr = SSSR_ROR | SSSR_TUR | SSSR_BCE;
194 212
195 SSCR0_P(dev->port) = ssp->cr0 & ~SSCR0_SSE; 213 __raw_writel(sssr, ssp->mmio_base + SSSR);
196 SSCR1_P(dev->port) = ssp->cr1;
197 SSTO_P(dev->port) = ssp->to;
198 SSPSP_P(dev->port) = ssp->psp;
199 214
200 SSCR0_P(dev->port) = ssp->cr0; 215 __raw_writel(state->cr0 & ~SSCR0_SSE, ssp->mmio_base + SSCR0);
216 __raw_writel(state->cr1, ssp->mmio_base + SSCR1);
217 __raw_writel(state->to, ssp->mmio_base + SSTO);
218 __raw_writel(state->psp, ssp->mmio_base + SSPSP);
219 __raw_writel(state->cr0, ssp->mmio_base + SSCR0);
201} 220}
202 221
203/** 222/**
@@ -211,15 +230,17 @@ void ssp_restore_state(struct ssp_dev *dev, struct ssp_state *ssp)
211 */ 230 */
212int ssp_config(struct ssp_dev *dev, u32 mode, u32 flags, u32 psp_flags, u32 speed) 231int ssp_config(struct ssp_dev *dev, u32 mode, u32 flags, u32 psp_flags, u32 speed)
213{ 232{
233 struct ssp_device *ssp = dev->ssp;
234
214 dev->mode = mode; 235 dev->mode = mode;
215 dev->flags = flags; 236 dev->flags = flags;
216 dev->psp_flags = psp_flags; 237 dev->psp_flags = psp_flags;
217 dev->speed = speed; 238 dev->speed = speed;
218 239
219 /* set up port type, speed, port settings */ 240 /* set up port type, speed, port settings */
220 SSCR0_P(dev->port) = (dev->speed | dev->mode); 241 __raw_writel((dev->speed | dev->mode), ssp->mmio_base + SSCR0);
221 SSCR1_P(dev->port) = dev->flags; 242 __raw_writel(dev->flags, ssp->mmio_base + SSCR1);
222 SSPSP_P(dev->port) = dev->psp_flags; 243 __raw_writel(dev->psp_flags, ssp->mmio_base + SSPSP);
223 244
224 return 0; 245 return 0;
225} 246}
@@ -274,7 +295,7 @@ void ssp_exit(struct ssp_dev *dev)
274{ 295{
275 struct ssp_device *ssp = dev->ssp; 296 struct ssp_device *ssp = dev->ssp;
276 297
277 SSCR0_P(dev->port) &= ~SSCR0_SSE; 298 ssp_disable(dev);
278 free_irq(dev->irq, dev); 299 free_irq(dev->irq, dev);
279 clk_disable(ssp->clk); 300 clk_disable(ssp->clk);
280 ssp_free(ssp); 301 ssp_free(ssp);