2012-03-26 08:59:23 +04:00
/*
* arch / arm / plat - spear / pl080 . c
*
* DMAC pl080 definitions for SPEAr platform
*
* Copyright ( C ) 2012 ST Microelectronics
2012-06-20 23:53:02 +04:00
* Viresh Kumar < viresh . linux @ gmail . com >
2012-03-26 08:59:23 +04:00
*
* This file is licensed under the terms of the GNU General Public
* License version 2. This program is licensed " as is " without any
* warranty of any kind , whether express or implied .
*/
# include <linux/amba/pl08x.h>
# include <linux/amba/bus.h>
# include <linux/bug.h>
# include <linux/err.h>
# include <linux/io.h>
# include <linux/spinlock_types.h>
2012-04-11 21:30:11 +04:00
# include <mach/spear.h>
2012-03-26 08:59:23 +04:00
# include <mach/misc_regs.h>
static spinlock_t lock = __SPIN_LOCK_UNLOCKED ( x ) ;
struct {
unsigned char busy ;
unsigned char val ;
} signals [ 16 ] = { { 0 , 0 } , } ;
2012-06-08 12:46:23 +04:00
int pl080_get_signal ( const struct pl08x_channel_data * cd )
2012-03-26 08:59:23 +04:00
{
unsigned int signal = cd - > min_signal , val ;
unsigned long flags ;
spin_lock_irqsave ( & lock , flags ) ;
/* Return if signal is already acquired by somebody else */
if ( signals [ signal ] . busy & &
( signals [ signal ] . val ! = cd - > muxval ) ) {
spin_unlock_irqrestore ( & lock , flags ) ;
return - EBUSY ;
}
/* If acquiring for the first time, configure it */
if ( ! signals [ signal ] . busy ) {
val = readl ( DMA_CHN_CFG ) ;
/*
* Each request line has two bits in DMA_CHN_CFG register . To
* goto the bits of current request line , do left shift of
* value by 2 * signal number .
*/
val & = ~ ( 0x3 < < ( signal * 2 ) ) ;
val | = cd - > muxval < < ( signal * 2 ) ;
writel ( val , DMA_CHN_CFG ) ;
}
signals [ signal ] . busy + + ;
signals [ signal ] . val = cd - > muxval ;
spin_unlock_irqrestore ( & lock , flags ) ;
return signal ;
}
2012-06-08 12:46:23 +04:00
void pl080_put_signal ( const struct pl08x_channel_data * cd , int signal )
2012-03-26 08:59:23 +04:00
{
unsigned long flags ;
spin_lock_irqsave ( & lock , flags ) ;
/* if signal is not used */
2012-06-08 12:46:23 +04:00
if ( ! signals [ signal ] . busy )
2012-03-26 08:59:23 +04:00
BUG ( ) ;
2012-06-08 12:46:23 +04:00
signals [ signal ] . busy - - ;
2012-03-26 08:59:23 +04:00
spin_unlock_irqrestore ( & lock , flags ) ;
}