@ -150,6 +150,8 @@ static int aic5_set_type(struct irq_data *d, unsigned type)
}
# ifdef CONFIG_PM
static u32 * smr_cache ;
static void aic5_suspend ( struct irq_data * d )
{
struct irq_domain * domain = d - > domain ;
@ -159,6 +161,12 @@ static void aic5_suspend(struct irq_data *d)
int i ;
u32 mask ;
if ( smr_cache )
for ( i = 0 ; i < domain - > revmap_size ; i + + ) {
irq_reg_writel ( bgc , i , AT91_AIC5_SSR ) ;
smr_cache [ i ] = irq_reg_readl ( bgc , AT91_AIC5_SMR ) ;
}
irq_gc_lock ( bgc ) ;
for ( i = 0 ; i < dgc - > irqs_per_chip ; i + + ) {
mask = 1 < < i ;
@ -184,9 +192,21 @@ static void aic5_resume(struct irq_data *d)
u32 mask ;
irq_gc_lock ( bgc ) ;
if ( smr_cache ) {
irq_reg_writel ( bgc , 0xffffffff , AT91_AIC5_SPU ) ;
for ( i = 0 ; i < domain - > revmap_size ; i + + ) {
irq_reg_writel ( bgc , i , AT91_AIC5_SSR ) ;
irq_reg_writel ( bgc , i , AT91_AIC5_SVR ) ;
irq_reg_writel ( bgc , smr_cache [ i ] , AT91_AIC5_SMR ) ;
}
}
for ( i = 0 ; i < dgc - > irqs_per_chip ; i + + ) {
mask = 1 < < i ;
if ( ( mask & gc - > mask_cache ) = = ( mask & gc - > wake_active ) )
if ( ! smr_cache & &
( ( mask & gc - > mask_cache ) = = ( mask & gc - > wake_active ) ) )
continue ;
irq_reg_writel ( bgc , i + gc - > irq_base , AT91_AIC5_SSR ) ;
@ -342,6 +362,13 @@ static int __init aic5_of_init(struct device_node *node,
static int __init sama5d2_aic5_of_init ( struct device_node * node ,
struct device_node * parent )
{
# ifdef CONFIG_PM
smr_cache = kcalloc ( DIV_ROUND_UP ( NR_SAMA5D2_IRQS , 32 ) * 32 ,
sizeof ( * smr_cache ) , GFP_KERNEL ) ;
if ( ! smr_cache )
return - ENOMEM ;
# endif
return aic5_of_init ( node , parent , NR_SAMA5D2_IRQS ) ;
}
IRQCHIP_DECLARE ( sama5d2_aic5 , " atmel,sama5d2-aic " , sama5d2_aic5_of_init ) ;