@@ -146,6 +146,10 @@ struct irq_domain *__irq_domain_add(struct fwnode_handle *fwnode, int size,
146146
147147 static atomic_t unknown_domains ;
148148
149+ if (WARN_ON ((size && direct_max ) ||
150+ (!IS_ENABLED (CONFIG_IRQ_DOMAIN_NOMAP ) && direct_max )))
151+ return NULL ;
152+
149153 domain = kzalloc_node (sizeof (* domain ) + (sizeof (unsigned int ) * size ),
150154 GFP_KERNEL , of_node_to_nid (to_of_node (fwnode )));
151155 if (!domain )
@@ -213,8 +217,14 @@ struct irq_domain *__irq_domain_add(struct fwnode_handle *fwnode, int size,
213217 domain -> ops = ops ;
214218 domain -> host_data = host_data ;
215219 domain -> hwirq_max = hwirq_max ;
220+
221+ if (direct_max ) {
222+ size = direct_max ;
223+ domain -> flags |= IRQ_DOMAIN_FLAG_NO_MAP ;
224+ }
225+
216226 domain -> revmap_size = size ;
217- domain -> revmap_direct_max_irq = direct_max ;
227+
218228 irq_domain_check_hierarchy (domain );
219229
220230 mutex_lock (& irq_domain_mutex );
@@ -482,9 +492,18 @@ struct irq_domain *irq_get_default_host(void)
482492 return irq_default_domain ;
483493}
484494
495+ static bool irq_domain_is_nomap (struct irq_domain * domain )
496+ {
497+ return IS_ENABLED (CONFIG_IRQ_DOMAIN_NOMAP ) &&
498+ (domain -> flags & IRQ_DOMAIN_FLAG_NO_MAP );
499+ }
500+
485501static void irq_domain_clear_mapping (struct irq_domain * domain ,
486502 irq_hw_number_t hwirq )
487503{
504+ if (irq_domain_is_nomap (domain ))
505+ return ;
506+
488507 if (hwirq < domain -> revmap_size ) {
489508 domain -> revmap [hwirq ] = 0 ;
490509 } else {
@@ -498,6 +517,9 @@ static void irq_domain_set_mapping(struct irq_domain *domain,
498517 irq_hw_number_t hwirq ,
499518 struct irq_data * irq_data )
500519{
520+ if (irq_domain_is_nomap (domain ))
521+ return ;
522+
501523 if (hwirq < domain -> revmap_size ) {
502524 domain -> revmap [hwirq ] = irq_data -> irq ;
503525 } else {
@@ -629,9 +651,9 @@ unsigned int irq_create_direct_mapping(struct irq_domain *domain)
629651 pr_debug ("create_direct virq allocation failed\n" );
630652 return 0 ;
631653 }
632- if (virq >= domain -> revmap_direct_max_irq ) {
654+ if (virq >= domain -> revmap_size ) {
633655 pr_err ("ERROR: no free irqs available below %i maximum\n" ,
634- domain -> revmap_direct_max_irq );
656+ domain -> revmap_size );
635657 irq_free_desc (virq );
636658 return 0 ;
637659 }
@@ -879,10 +901,14 @@ unsigned int irq_find_mapping(struct irq_domain *domain,
879901 if (domain == NULL )
880902 return 0 ;
881903
882- if (hwirq < domain -> revmap_direct_max_irq ) {
883- data = irq_domain_get_irq_data (domain , hwirq );
884- if (data && data -> hwirq == hwirq )
885- return hwirq ;
904+ if (irq_domain_is_nomap (domain )) {
905+ if (hwirq < domain -> revmap_size ) {
906+ data = irq_domain_get_irq_data (domain , hwirq );
907+ if (data && data -> hwirq == hwirq )
908+ return hwirq ;
909+ }
910+
911+ return 0 ;
886912 }
887913
888914 /* Check if the hwirq is in the linear revmap. */
@@ -1470,7 +1496,7 @@ static void irq_domain_fix_revmap(struct irq_data *d)
14701496{
14711497 void __rcu * * slot ;
14721498
1473- if (d -> hwirq < d -> domain -> revmap_size )
1499+ if (irq_domain_is_nomap ( d -> domain ) || d -> hwirq < d -> domain -> revmap_size )
14741500 return ; /* Not using radix tree. */
14751501
14761502 /* Fix up the revmap. */
@@ -1830,8 +1856,7 @@ static void
18301856irq_domain_debug_show_one (struct seq_file * m , struct irq_domain * d , int ind )
18311857{
18321858 seq_printf (m , "%*sname: %s\n" , ind , "" , d -> name );
1833- seq_printf (m , "%*ssize: %u\n" , ind + 1 , "" ,
1834- d -> revmap_size + d -> revmap_direct_max_irq );
1859+ seq_printf (m , "%*ssize: %u\n" , ind + 1 , "" , d -> revmap_size );
18351860 seq_printf (m , "%*smapped: %u\n" , ind + 1 , "" , d -> mapcount );
18361861 seq_printf (m , "%*sflags: 0x%08x\n" , ind + 1 , "" , d -> flags );
18371862 if (d -> ops && d -> ops -> debug_show )
0 commit comments