aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/mips/alchemy/common/dbdma.c111
1 files changed, 56 insertions, 55 deletions
diff --git a/arch/mips/alchemy/common/dbdma.c b/arch/mips/alchemy/common/dbdma.c
index 493e5708f664..99ae84ce5af3 100644
--- a/arch/mips/alchemy/common/dbdma.c
+++ b/arch/mips/alchemy/common/dbdma.c
@@ -237,7 +237,7 @@ u32 au1xxx_dbdma_chan_alloc(u32 srcid, u32 destid,
237 void (*callback)(int, void *), void *callparam) 237 void (*callback)(int, void *), void *callparam)
238{ 238{
239 unsigned long flags; 239 unsigned long flags;
240 u32 used, chan, rv; 240 u32 used, chan;
241 u32 dcp; 241 u32 dcp;
242 int i; 242 int i;
243 dbdev_tab_t *stp, *dtp; 243 dbdev_tab_t *stp, *dtp;
@@ -260,7 +260,6 @@ u32 au1xxx_dbdma_chan_alloc(u32 srcid, u32 destid,
260 return 0; 260 return 0;
261 261
262 used = 0; 262 used = 0;
263 rv = 0;
264 263
265 /* Check to see if we can get both channels. */ 264 /* Check to see if we can get both channels. */
266 spin_lock_irqsave(&au1xxx_dbdma_spin_lock, flags); 265 spin_lock_irqsave(&au1xxx_dbdma_spin_lock, flags);
@@ -281,63 +280,65 @@ u32 au1xxx_dbdma_chan_alloc(u32 srcid, u32 destid,
281 used++; 280 used++;
282 spin_unlock_irqrestore(&au1xxx_dbdma_spin_lock, flags); 281 spin_unlock_irqrestore(&au1xxx_dbdma_spin_lock, flags);
283 282
284 if (!used) { 283 if (used)
285 /* Let's see if we can allocate a channel for it. */ 284 return 0;
286 ctp = NULL;
287 chan = 0;
288 spin_lock_irqsave(&au1xxx_dbdma_spin_lock, flags);
289 for (i = 0; i < NUM_DBDMA_CHANS; i++)
290 if (chan_tab_ptr[i] == NULL) {
291 /*
292 * If kmalloc fails, it is caught below same
293 * as a channel not available.
294 */
295 ctp = kmalloc(sizeof(chan_tab_t), GFP_ATOMIC);
296 chan_tab_ptr[i] = ctp;
297 break;
298 }
299 spin_unlock_irqrestore(&au1xxx_dbdma_spin_lock, flags);
300
301 if (ctp != NULL) {
302 memset(ctp, 0, sizeof(chan_tab_t));
303 ctp->chan_index = chan = i;
304 dcp = DDMA_CHANNEL_BASE;
305 dcp += (0x0100 * chan);
306 ctp->chan_ptr = (au1x_dma_chan_t *)dcp;
307 cp = (au1x_dma_chan_t *)dcp;
308 ctp->chan_src = stp;
309 ctp->chan_dest = dtp;
310 ctp->chan_callback = callback;
311 ctp->chan_callparam = callparam;
312
313 /* Initialize channel configuration. */
314 i = 0;
315 if (stp->dev_intlevel)
316 i |= DDMA_CFG_SED;
317 if (stp->dev_intpolarity)
318 i |= DDMA_CFG_SP;
319 if (dtp->dev_intlevel)
320 i |= DDMA_CFG_DED;
321 if (dtp->dev_intpolarity)
322 i |= DDMA_CFG_DP;
323 if ((stp->dev_flags & DEV_FLAGS_SYNC) ||
324 (dtp->dev_flags & DEV_FLAGS_SYNC))
325 i |= DDMA_CFG_SYNC;
326 cp->ddma_cfg = i;
327 au_sync();
328 285
329 /* Return a non-zero value that can be used to 286 /* Let's see if we can allocate a channel for it. */
330 * find the channel information in subsequent 287 ctp = NULL;
331 * operations. 288 chan = 0;
289 spin_lock_irqsave(&au1xxx_dbdma_spin_lock, flags);
290 for (i = 0; i < NUM_DBDMA_CHANS; i++)
291 if (chan_tab_ptr[i] == NULL) {
292 /*
293 * If kmalloc fails, it is caught below same
294 * as a channel not available.
332 */ 295 */
333 rv = (u32)(&chan_tab_ptr[chan]); 296 ctp = kmalloc(sizeof(chan_tab_t), GFP_ATOMIC);
334 } else { 297 chan_tab_ptr[i] = ctp;
335 /* Release devices */ 298 break;
336 stp->dev_flags &= ~DEV_FLAGS_INUSE;
337 dtp->dev_flags &= ~DEV_FLAGS_INUSE;
338 } 299 }
300 spin_unlock_irqrestore(&au1xxx_dbdma_spin_lock, flags);
301
302 if (ctp != NULL) {
303 memset(ctp, 0, sizeof(chan_tab_t));
304 ctp->chan_index = chan = i;
305 dcp = DDMA_CHANNEL_BASE;
306 dcp += (0x0100 * chan);
307 ctp->chan_ptr = (au1x_dma_chan_t *)dcp;
308 cp = (au1x_dma_chan_t *)dcp;
309 ctp->chan_src = stp;
310 ctp->chan_dest = dtp;
311 ctp->chan_callback = callback;
312 ctp->chan_callparam = callparam;
313
314 /* Initialize channel configuration. */
315 i = 0;
316 if (stp->dev_intlevel)
317 i |= DDMA_CFG_SED;
318 if (stp->dev_intpolarity)
319 i |= DDMA_CFG_SP;
320 if (dtp->dev_intlevel)
321 i |= DDMA_CFG_DED;
322 if (dtp->dev_intpolarity)
323 i |= DDMA_CFG_DP;
324 if ((stp->dev_flags & DEV_FLAGS_SYNC) ||
325 (dtp->dev_flags & DEV_FLAGS_SYNC))
326 i |= DDMA_CFG_SYNC;
327 cp->ddma_cfg = i;
328 au_sync();
329
330 /*
331 * Return a non-zero value that can be used to find the channel
332 * information in subsequent operations.
333 */
334 return (u32)(&chan_tab_ptr[chan]);
339 } 335 }
340 return rv; 336
337 /* Release devices */
338 stp->dev_flags &= ~DEV_FLAGS_INUSE;
339 dtp->dev_flags &= ~DEV_FLAGS_INUSE;
340
341 return 0;
341} 342}
342EXPORT_SYMBOL(au1xxx_dbdma_chan_alloc); 343EXPORT_SYMBOL(au1xxx_dbdma_chan_alloc);
343 344