@ -29,10 +29,11 @@ struct regmap_irq_chip_data {
int irq_base ;
struct irq_domain * domain ;
void * status_reg_buf ;
unsigned int * status_buf ;
unsigned int * mask_buf ;
unsigned int * mask_buf_def ;
unsigned int irq_reg_stride ;
} ;
static inline const
@ -62,7 +63,8 @@ static void regmap_irq_sync_unlock(struct irq_data *data)
*/
for ( i = 0 ; i < d - > chip - > num_regs ; i + + ) {
ret = regmap_update_bits ( d - > map , d - > chip - > mask_base +
( i * map - > reg_stride ) ,
( i * map - > reg_stride *
d - > irq_reg_stride ) ,
d - > mask_buf_def [ i ] , d - > mask_buf [ i ] ) ;
if ( ret ! = 0 )
dev_err ( d - > map - > dev , " Failed to sync masks in %x \n " ,
@ -104,18 +106,8 @@ static irqreturn_t regmap_irq_thread(int irq, void *d)
struct regmap_irq_chip * chip = data - > chip ;
struct regmap * map = data - > map ;
int ret , i ;
u8 * buf8 = data - > status_reg_buf ;
u16 * buf16 = data - > status_reg_buf ;
u32 * buf32 = data - > status_reg_buf ;
bool handled = false ;
ret = regmap_bulk_read ( map , chip - > status_base , data - > status_reg_buf ,
chip - > num_regs ) ;
if ( ret ! = 0 ) {
dev_err ( map - > dev , " Failed to read IRQ status: %d \n " , ret ) ;
return IRQ_NONE ;
}
/*
* Ignore masked IRQs and ack if we need to ; we ack early so
* there is no race between handling and acknowleding the
@ -124,18 +116,13 @@ static irqreturn_t regmap_irq_thread(int irq, void *d)
* doing a write per register .
*/
for ( i = 0 ; i < data - > chip - > num_regs ; i + + ) {
switch ( map - > format . val_bytes ) {
case 1 :
data - > status_buf [ i ] = buf8 [ i ] ;
break ;
case 2 :
data - > status_buf [ i ] = buf16 [ i ] ;
break ;
case 4 :
data - > status_buf [ i ] = buf32 [ i ] ;
break ;
default :
BUG ( ) ;
ret = regmap_read ( map , chip - > mask_base + ( i * map - > reg_stride
* data - > irq_reg_stride ) ,
& data - > status_buf [ i ] ) ;
if ( ret ! = 0 ) {
dev_err ( map - > dev , " Failed to read IRQ status: %d \n " ,
ret ) ;
return IRQ_NONE ;
}
@ -143,7 +130,8 @@ static irqreturn_t regmap_irq_thread(int irq, void *d)
if ( data - > status_buf [ i ] & & chip - > ack_base ) {
ret = regmap_write ( map , chip - > ack_base +
( i * map - > reg_stride ) ,
( i * map - > reg_stride *
data - > irq_reg_stride ) ,
data - > status_buf [ i ] ) ;
if ( ret ! = 0 )
dev_err ( map - > dev , " Failed to ack 0x%x: %d \n " ,
@ -242,11 +230,6 @@ int regmap_add_irq_chip(struct regmap *map, int irq, int irq_flags,
if ( ! d - > status_buf )
goto err_alloc ;
d - > status_reg_buf = kzalloc ( map - > format . val_bytes * chip - > num_regs ,
GFP_KERNEL ) ;
if ( ! d - > status_reg_buf )
goto err_alloc ;
d - > mask_buf = kzalloc ( sizeof ( unsigned int ) * chip - > num_regs ,
GFP_KERNEL ) ;
if ( ! d - > mask_buf )
@ -260,6 +243,12 @@ int regmap_add_irq_chip(struct regmap *map, int irq, int irq_flags,
d - > map = map ;
d - > chip = chip ;
d - > irq_base = irq_base ;
if ( chip - > irq_reg_stride )
d - > irq_reg_stride = chip - > irq_reg_stride ;
else
d - > irq_reg_stride = 1 ;
mutex_init ( & d - > lock ) ;
for ( i = 0 ; i < chip - > num_irqs ; i + + )
@ -269,7 +258,8 @@ int regmap_add_irq_chip(struct regmap *map, int irq, int irq_flags,
/* Mask all the interrupts by default */
for ( i = 0 ; i < chip - > num_regs ; i + + ) {
d - > mask_buf [ i ] = d - > mask_buf_def [ i ] ;
ret = regmap_write ( map , chip - > mask_base + ( i * map - > reg_stride ) ,
ret = regmap_write ( map , chip - > mask_base + ( i * map - > reg_stride
* d - > irq_reg_stride ) ,
d - > mask_buf [ i ] ) ;
if ( ret ! = 0 ) {
dev_err ( map - > dev , " Failed to set masks in 0x%x: %d \n " ,
@ -306,7 +296,6 @@ err_domain:
err_alloc :
kfree ( d - > mask_buf_def ) ;
kfree ( d - > mask_buf ) ;
kfree ( d - > status_reg_buf ) ;
kfree ( d - > status_buf ) ;
kfree ( d ) ;
return ret ;
@ -328,7 +317,6 @@ void regmap_del_irq_chip(int irq, struct regmap_irq_chip_data *d)
/* We should unmap the domain but... */
kfree ( d - > mask_buf_def ) ;
kfree ( d - > mask_buf ) ;
kfree ( d - > status_reg_buf ) ;
kfree ( d - > status_buf ) ;
kfree ( d ) ;
}