[xburst] jz-mmc: Fix deadlock which could occur if the card was removed while a
[openwrt.git] / target / linux / coldfire / patches / 033-m5445x_ssi_cleanup.patch
1 From 98e15babf1e25868d22c024dac6133cc29059d39 Mon Sep 17 00:00:00 2001
2 From: Kurt Mahan <kmahan@freescale.com>
3 Date: Sun, 9 Dec 2007 02:24:13 -0700
4 Subject: [PATCH] Fix DMA mode and cleanup driver.
5
6 LTIBName: m5445x-ssi-cleanup
7 Signed-off-by: Kurt Mahan <kmahan@freescale.com>
8 ---
9 drivers/spi/ssi_audio.c | 207 ++++++++++++++++++++++++-----------------------
10 1 files changed, 104 insertions(+), 103 deletions(-)
11
12 --- a/drivers/spi/ssi_audio.c
13 +++ b/drivers/spi/ssi_audio.c
14 @@ -2,7 +2,7 @@
15 * MCF5445x audio driver.
16 *
17 * Yaroslav Vinogradov yaroslav.vinogradov@freescale.com
18 - * Copyright Freescale Semiconductor, Inc. 2006
19 + * Copyright Freescale Semiconductor, Inc. 2006, 2007
20 *
21 * This program is free software; you can redistribute it and/or modify
22 * it under the terms of the GNU General Public License as published by
23 @@ -25,9 +25,11 @@
24
25 #include <asm/coldfire.h>
26 #include <asm/coldfire_edma.h>
27 +#ifdef CONFIG_M54455
28 #include <asm/mcf5445x_ssi.h>
29 #include <asm/mcf5445x_ccm.h>
30 #include <asm/mcf5445x_gpio.h>
31 +#endif
32
33 #define SOUND_DEVICE_NAME "sound"
34 #define DRIVER_NAME "ssi_audio"
35 @@ -47,8 +49,8 @@
36
37 /* TLV320DAC23 audio chip registers */
38
39 -#define CODEC_LEFT_IN_REG (0x00)
40 -#define CODEC_RIGHT_IN_REG (0x01)
41 +#define CODEC_LEFT_IN_REG (0x00)
42 +#define CODEC_RIGHT_IN_REG (0x01)
43 #define CODEC_LEFT_HP_VOL_REG (0x02)
44 #define CODEC_RIGHT_HP_VOL_REG (0x03)
45 #define CODEC_ANALOG_APATH_REG (0x04)
46 @@ -57,7 +59,7 @@
47 #define CODEC_DIGITAL_IF_FMT_REG (0x07)
48 #define CODEC_SAMPLE_RATE_REG (0x08)
49 #define CODEC_DIGITAL_IF_ACT_REG (0x09)
50 -#define CODEC_RESET_REG (0x0f)
51 +#define CODEC_RESET_REG (0x0f)
52
53 #define CODEC_SAMPLE_8KHZ (0x0C)
54 #define CODEC_SAMPLE_16KHZ (0x58)
55 @@ -71,21 +73,21 @@
56 /* DMA transfer size */
57 #define DMASIZE (16*1024)
58
59 -/* transmit eDMA channel for SSI channel 0 */
60 -#define DMA_TCD 10
61 -/* transmit eDMA channel for SSI channel 1 */
62 -#define DMA_TCD2 11
63 +/* eDMA channel for SSI channel 0 TX */
64 +#define DMA_TCD MCF_EDMA_CHAN_TIMER2
65 +/* eDMA channel for SSI channel 1 TX */
66 +#define DMA_TCD2 MCF_EDMA_CHAN_TIMER3
67
68 struct ssi_audio {
69 - struct spi_device *spi;
70 + struct spi_device *spi;
71 u32 speed;
72 u32 stereo;
73 u32 bits;
74 u32 format;
75 - u8 isopen;
76 - u8 dmaing;
77 - u8 ssi_enabled;
78 - u8 channel;
79 + u8 isopen;
80 + u8 dmaing;
81 + u8 ssi_enabled;
82 + u8 channel;
83 spinlock_t lock;
84 u8* audio_buf;
85 };
86 @@ -129,7 +131,8 @@ static void ssi_audio_setsamplesize(int
87 }
88
89 #ifdef AUDIO_DEBUG
90 - printk(DRIVER_NAME ":ssi_audio_setsamplesize %d %d\n", audio_device->format, audio_device->bits);
91 + printk(DRIVER_NAME ":ssi_audio_setsamplesize %d %d\n",
92 + audio_device->format, audio_device->bits);
93 #endif
94 }
95
96 @@ -157,62 +160,57 @@ void __inline__ ssi_audio_dmarun(void)
97 {
98 set_edma_params(DMA_TCD,
99 #ifdef USE_MMU
100 - virt_to_phys(&(audio_device->audio_buf[audio_start])),
101 + virt_to_phys(&(audio_device->audio_buf[audio_start])),
102 #else
103 - (u32)&(audio_device->audio_buf[audio_start]),
104 + (u32)&(audio_device->audio_buf[audio_start]),
105 #endif
106 - (u32)&MCF_SSI_TX0,
107 - MCF_EDMA_TCD_ATTR_SSIZE_32BIT | MCF_EDMA_TCD_ATTR_DSIZE_32BIT,
108 - 8,
109 - 4,
110 - 0,
111 - audio_count/8,
112 - audio_count/8,
113 - 0,
114 - 0,
115 - 0, // major_int
116 - 0 // disable_req
117 - );
118 + (u32)&MCF_SSI_TX0,
119 + MCF_EDMA_TCD_ATTR_SSIZE_32BIT | MCF_EDMA_TCD_ATTR_DSIZE_32BIT,
120 + 8,
121 + 4,
122 + 0,
123 + audio_count/8,
124 + audio_count/8,
125 + 0,
126 + 0,
127 + 0, // major_int
128 + 0 // disable_req
129 + );
130
131 set_edma_params(DMA_TCD2,
132 #ifdef USE_MMU
133 - virt_to_phys(&(audio_device->audio_buf[audio_start+4])),
134 + virt_to_phys(&(audio_device->audio_buf[audio_start+4])),
135 #else
136 - (u32)&(audio_device->audio_buf[audio_start+4]),
137 + (u32)&(audio_device->audio_buf[audio_start+4]),
138 #endif
139 - (u32)&MCF_SSI_TX1,
140 - MCF_EDMA_TCD_ATTR_SSIZE_32BIT | MCF_EDMA_TCD_ATTR_DSIZE_32BIT,
141 - 8,
142 - 4,
143 - 0,
144 - audio_count/8,
145 - audio_count/8,
146 - 0,
147 - 0,
148 - 1, // major_int
149 - 0 // disable_req
150 - );
151 + (u32)&MCF_SSI_TX1,
152 + MCF_EDMA_TCD_ATTR_SSIZE_32BIT | MCF_EDMA_TCD_ATTR_DSIZE_32BIT,
153 + 8,
154 + 4,
155 + 0,
156 + audio_count/8,
157 + audio_count/8,
158 + 0,
159 + 0,
160 + 1, // major_int
161 + 0 // disable_req
162 + );
163
164 audio_device->dmaing = 1;
165 audio_txbusy = 1;
166
167 start_edma_transfer(DMA_TCD);
168 start_edma_transfer(DMA_TCD2);
169 -#if 0
170 - MCF_EDMA_ERQ |= (1<<DMA_TCD) | (1<<DMA_TCD2);
171 - MCF_EDMA_SSRT = DMA_TCD;
172 - MCF_EDMA_SSRT = DMA_TCD2;
173 -#endif
174 -
175 }
176
177 -/*
178 - * Start DMA'ing a new buffer of data if any available.
179 +/**
180 + * ssi_audio_dmabuf - Start DMA'ing a new buffer of data if any available.
181 */
182 static void ssi_audio_dmabuf(void)
183 {
184 #ifdef AUDIO_DEBUG
185 - printk(DRIVER_NAME ":ssi_audio_dmabuf(): append=%x start=%x\n", audio_append, audio_appstart);
186 + printk(DRIVER_NAME ":ssi_audio_dmabuf(): append=%x start=%x\n",
187 + audio_append, audio_appstart);
188 #endif
189
190 /* If already running then nothing to do... */
191 @@ -241,7 +239,8 @@ static void ssi_audio_dmabuf(void)
192 }
193 }
194
195 -void __inline__ stop_dma(void) {
196 +void __inline__ stop_dma(void)
197 +{
198 stop_edma_transfer(DMA_TCD);
199 stop_edma_transfer(DMA_TCD2);
200 }
201 @@ -283,7 +282,6 @@ static void init_dma(void)
202
203 #endif /* CONFIG_SSIAUDIO_USE_EDMA */
204
205 -
206 /* Write CODEC register using SPI
207 * address - CODEC register address
208 * data - data to be written into register
209 @@ -296,7 +294,8 @@ static int codec_write(u8 addr, u16 data
210 return -ENODEV;
211
212 spi_word = ((addr & 0x7F)<<9)|(data & 0x1FF);
213 - return spi_write(audio_device->spi, (const u8*)&spi_word, sizeof(spi_word));
214 + return spi_write(audio_device->spi, (const u8*)&spi_word,
215 + sizeof(spi_word));
216 }
217
218 static inline void enable_ssi(void)
219 @@ -359,7 +358,7 @@ static void init_audio_codec(void)
220 codec_write(CODEC_DIGITAL_APATH_REG, 0x007); /* Set A path */
221
222 /* set sample rate */
223 - adjust_codec_speed();
224 + adjust_codec_speed();
225
226 codec_write(CODEC_LEFT_HP_VOL_REG, 0x075); /* set volume */
227 codec_write(CODEC_RIGHT_HP_VOL_REG, 0x075); /* set volume */
228 @@ -375,13 +374,12 @@ static void chip_init(void)
229 #endif
230
231 /* Enable the SSI pins */
232 - MCF_GPIO_PAR_SSI = ( 0
233 - | MCF_GPIO_PAR_SSI_MCLK
234 - | MCF_GPIO_PAR_SSI_STXD(3)
235 - | MCF_GPIO_PAR_SSI_SRXD(3)
236 - | MCF_GPIO_PAR_SSI_FS(3)
237 - | MCF_GPIO_PAR_SSI_BCLK(3) );
238 -
239 + MCF_GPIO_PAR_SSI = (0
240 + | MCF_GPIO_PAR_SSI_MCLK
241 + | MCF_GPIO_PAR_SSI_STXD(3)
242 + | MCF_GPIO_PAR_SSI_SRXD(3)
243 + | MCF_GPIO_PAR_SSI_FS(3)
244 + | MCF_GPIO_PAR_SSI_BCLK(3) );
245 }
246
247 static void init_ssi(void)
248 @@ -430,8 +428,8 @@ static void init_ssi(void)
249 ;
250
251 MCF_SSI_FCSR = 0
252 - | MCF_SSI_FCSR_TFWM0(0)
253 - | MCF_SSI_FCSR_TFWM1(0)
254 + | MCF_SSI_FCSR_TFWM0(2)
255 + | MCF_SSI_FCSR_TFWM1(2)
256 ;
257
258 MCF_SSI_IER = 0 // interrupts
259 @@ -459,9 +457,8 @@ static int ssi_audio_isr(int irq, void *
260 {
261 unsigned long *bp;
262
263 - if (audio_txbusy==0) {
264 + if (audio_txbusy==0)
265 return IRQ_HANDLED;
266 - }
267
268 spin_lock(&(audio_device->lock));
269
270 @@ -560,7 +557,8 @@ static int ssi_audio_close(struct inode
271 }
272
273 /* write to audio device */
274 -static ssize_t ssi_audio_write(struct file *filp, const char *buf, size_t count, loff_t *ppos)
275 +static ssize_t ssi_audio_write(struct file *filp, const char *buf,
276 + size_t count, loff_t *ppos)
277 {
278 unsigned long *dp, *buflp;
279 unsigned short *bufwp;
280 @@ -568,10 +566,12 @@ static ssize_t ssi_audio_write(struct fi
281 unsigned int slen, bufcnt, i, s, e;
282
283 #ifdef AUDIO_DEBUG
284 - printk(DRIVER_NAME ":ssi_audio_write(buf=%x,count=%d)\n", (int) buf, count);
285 + printk(DRIVER_NAME ":ssi_audio_write(buf=%x,count=%d)\n",
286 + (int)buf, count);
287 #endif
288
289 - if (audio_device==NULL) return (-ENODEV);
290 + if (audio_device==NULL)
291 + return (-ENODEV);
292
293 if (count <= 0)
294 return 0;
295 @@ -592,8 +592,8 @@ static ssize_t ssi_audio_write(struct fi
296
297 tryagain:
298 /*
299 - * Get a snapshot of buffer, so we can figure out how
300 - * much data we can fit in...
301 + * Get a snapshot of buffer, so we can figure out how
302 + * much data we can fit in...
303 */
304 s = audio_start;
305 e = audio_append;
306 @@ -613,11 +613,12 @@ tryagain:
307 goto tryagain;
308 }
309
310 - /* For DMA we need to have data as 32 bit
311 - values (since SSI TX register is 32 bit).
312 - So, the incomming 16 bit data must be put to buffer as 32 bit values.
313 - Also, the endianess is converted if needed
314 - */
315 + /*
316 + * For DMA we need to have data as 32 bit
317 + * values (since SSI TX register is 32 bit).
318 + * So, the incoming 16 bit data must be put to buffer as 32 bit values.
319 + * Also, the endianess is converted if needed
320 + */
321 if (audio_device->stereo) {
322 if (audio_device->bits == 16) {
323 if (audio_device->format==AFMT_S16_LE) {
324 @@ -678,16 +679,19 @@ tryagain:
325 }
326
327 /* ioctl: control the driver */
328 -static int ssi_audio_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg)
329 +static int ssi_audio_ioctl(struct inode *inode, struct file *filp,
330 + unsigned int cmd, unsigned long arg)
331 {
332 - long val;
333 - int rc = 0;
334 + long val;
335 + int rc = 0;
336
337 #ifdef AUDIO_DEBUG
338 - printk(DRIVER_NAME ":ssi_audio_ioctl(cmd=%x,arg=%x)\n", (int) cmd, (int) arg);
339 + printk(DRIVER_NAME ":ssi_audio_ioctl(cmd=%x,arg=%x)\n",
340 + (int)cmd, (int)arg);
341 #endif
342
343 - if (audio_device==NULL) return (-ENODEV);
344 + if (audio_device==NULL)
345 + return (-ENODEV);
346
347 switch (cmd) {
348
349 @@ -744,8 +748,6 @@ static int ssi_audio_ioctl(struct inode
350 return rc;
351 }
352
353 -/****************************************************************************/
354 -
355 struct file_operations ssi_audio_fops = {
356 open: ssi_audio_open, /* open */
357 release: ssi_audio_close, /* close */
358 @@ -756,8 +758,8 @@ struct file_operations ssi_audio_fops =
359 /* initialize audio driver */
360 static int __devinit ssi_audio_probe(struct spi_device *spi)
361 {
362 - struct ssi_audio *audio;
363 - int err;
364 + struct ssi_audio *audio;
365 + int err;
366
367 #ifdef AUDIO_DEBUG
368 printk(DRIVER_NAME": probe\n");
369 @@ -804,7 +806,7 @@ static int __devinit ssi_audio_probe(str
370 audio->spi = spi;
371
372 #ifndef CONFIG_SSIAUDIO_USE_EDMA
373 - if (request_irq(spi->irq, ssi_audio_isr, SA_INTERRUPT, spi->dev.bus_id, audio)) {
374 + if (request_irq(spi->irq, ssi_audio_isr, IRQF_DISABLED, spi->dev.bus_id, audio)) {
375 dev_dbg(&spi->dev, "irq %d busy?\n", spi->irq);
376 err = -EBUSY;
377 goto err_free_mem;
378 @@ -813,25 +815,21 @@ static int __devinit ssi_audio_probe(str
379 #else
380 /* request 2 eDMA channels since two channel output mode is used */
381 if (request_edma_channel(DMA_TCD,
382 - ssi_audio_dma_handler_empty,
383 - NULL,
384 - audio,
385 - &(audio_device->lock),
386 - DRIVER_NAME
387 - )!=0)
388 - {
389 + ssi_audio_dma_handler_empty,
390 + NULL,
391 + audio,
392 + &(audio_device->lock),
393 + DRIVER_NAME)!=0) {
394 dev_dbg(&spi->dev, "DMA channel %d busy?\n", DMA_TCD);
395 err = -EBUSY;
396 goto err_free_mem;
397 }
398 if (request_edma_channel(DMA_TCD2,
399 - ssi_audio_dma_handler,
400 - NULL,
401 - audio,
402 - &(audio_device->lock),
403 - DRIVER_NAME
404 - )!=0)
405 - {
406 + ssi_audio_dma_handler,
407 + NULL,
408 + audio,
409 + &(audio_device->lock),
410 + DRIVER_NAME)!=0) {
411 dev_dbg(&spi->dev, "DMA channel %d busy?\n", DMA_TCD2);
412 err = -EBUSY;
413 goto err_free_mem;
414 @@ -870,11 +868,13 @@ static int __devexit ssi_audio_remove(st
415 return 0;
416 }
417
418 -static int ssi_audio_suspend(struct spi_device *spi, pm_message_t message) {
419 +static int ssi_audio_suspend(struct spi_device *spi, pm_message_t message)
420 +{
421 return 0;
422 }
423
424 -static int ssi_audio_resume(struct spi_device *spi) {
425 +static int ssi_audio_resume(struct spi_device *spi)
426 +{
427 return 0;
428 }
429
430 @@ -902,5 +902,6 @@ static void __exit ssi_audio_exit(void)
431 }
432 module_exit(ssi_audio_exit);
433
434 -MODULE_DESCRIPTION("SSI/I2S Audio Driver");
435 MODULE_LICENSE("GPL");
436 +MODULE_AUTHOR("Freescale Semiconductor, Inc.");
437 +MODULE_DESCRIPTION("SSI/I2S Audio Driver");
This page took 0.069543 seconds and 5 git commands to generate.