@@ -730,6 +730,12 @@ static irqreturn_t irq_nested_primary_handler(int irq, void *dev_id)
730
730
return IRQ_NONE ;
731
731
}
732
732
733
+ static irqreturn_t irq_forced_secondary_handler (int irq , void * dev_id )
734
+ {
735
+ WARN (1 , "Secondary action handler called for irq %d\n" , irq );
736
+ return IRQ_NONE ;
737
+ }
738
+
733
739
static int irq_wait_for_interrupt (struct irqaction * action )
734
740
{
735
741
set_current_state (TASK_INTERRUPTIBLE );
@@ -756,7 +762,8 @@ static int irq_wait_for_interrupt(struct irqaction *action)
756
762
static void irq_finalize_oneshot (struct irq_desc * desc ,
757
763
struct irqaction * action )
758
764
{
759
- if (!(desc -> istate & IRQS_ONESHOT ))
765
+ if (!(desc -> istate & IRQS_ONESHOT ) ||
766
+ action -> handler == irq_forced_secondary_handler )
760
767
return ;
761
768
again :
762
769
chip_bus_lock (desc );
@@ -910,6 +917,18 @@ static void irq_thread_dtor(struct callback_head *unused)
910
917
irq_finalize_oneshot (desc , action );
911
918
}
912
919
920
+ static void irq_wake_secondary (struct irq_desc * desc , struct irqaction * action )
921
+ {
922
+ struct irqaction * secondary = action -> secondary ;
923
+
924
+ if (WARN_ON_ONCE (!secondary ))
925
+ return ;
926
+
927
+ raw_spin_lock_irq (& desc -> lock );
928
+ __irq_wake_thread (desc , secondary );
929
+ raw_spin_unlock_irq (& desc -> lock );
930
+ }
931
+
913
932
/*
914
933
* Interrupt handler thread
915
934
*/
@@ -940,6 +959,8 @@ static int irq_thread(void *data)
940
959
action_ret = handler_fn (desc , action );
941
960
if (action_ret == IRQ_HANDLED )
942
961
atomic_inc (& desc -> threads_handled );
962
+ if (action_ret == IRQ_WAKE_THREAD )
963
+ irq_wake_secondary (desc , action );
943
964
944
965
wake_threads_waitq (desc );
945
966
}
@@ -984,20 +1005,36 @@ void irq_wake_thread(unsigned int irq, void *dev_id)
984
1005
}
985
1006
EXPORT_SYMBOL_GPL (irq_wake_thread );
986
1007
987
- static void irq_setup_forced_threading (struct irqaction * new )
1008
+ static int irq_setup_forced_threading (struct irqaction * new )
988
1009
{
989
1010
if (!force_irqthreads )
990
- return ;
1011
+ return 0 ;
991
1012
if (new -> flags & (IRQF_NO_THREAD | IRQF_PERCPU | IRQF_ONESHOT ))
992
- return ;
1013
+ return 0 ;
993
1014
994
1015
new -> flags |= IRQF_ONESHOT ;
995
1016
996
- if (!new -> thread_fn ) {
997
- set_bit (IRQTF_FORCED_THREAD , & new -> thread_flags );
998
- new -> thread_fn = new -> handler ;
999
- new -> handler = irq_default_primary_handler ;
1017
+ /*
1018
+ * Handle the case where we have a real primary handler and a
1019
+ * thread handler. We force thread them as well by creating a
1020
+ * secondary action.
1021
+ */
1022
+ if (new -> handler != irq_default_primary_handler && new -> thread_fn ) {
1023
+ /* Allocate the secondary action */
1024
+ new -> secondary = kzalloc (sizeof (struct irqaction ), GFP_KERNEL );
1025
+ if (!new -> secondary )
1026
+ return - ENOMEM ;
1027
+ new -> secondary -> handler = irq_forced_secondary_handler ;
1028
+ new -> secondary -> thread_fn = new -> thread_fn ;
1029
+ new -> secondary -> dev_id = new -> dev_id ;
1030
+ new -> secondary -> irq = new -> irq ;
1031
+ new -> secondary -> name = new -> name ;
1000
1032
}
1033
+ /* Deal with the primary handler */
1034
+ set_bit (IRQTF_FORCED_THREAD , & new -> thread_flags );
1035
+ new -> thread_fn = new -> handler ;
1036
+ new -> handler = irq_default_primary_handler ;
1037
+ return 0 ;
1001
1038
}
1002
1039
1003
1040
static int irq_request_resources (struct irq_desc * desc )
@@ -1017,6 +1054,48 @@ static void irq_release_resources(struct irq_desc *desc)
1017
1054
c -> irq_release_resources (d );
1018
1055
}
1019
1056
1057
+ static int
1058
+ setup_irq_thread (struct irqaction * new , unsigned int irq , bool secondary )
1059
+ {
1060
+ struct task_struct * t ;
1061
+ struct sched_param param = {
1062
+ .sched_priority = MAX_USER_RT_PRIO /2 ,
1063
+ };
1064
+
1065
+ if (!secondary ) {
1066
+ t = kthread_create (irq_thread , new , "irq/%d-%s" , irq ,
1067
+ new -> name );
1068
+ } else {
1069
+ t = kthread_create (irq_thread , new , "irq/%d-s-%s" , irq ,
1070
+ new -> name );
1071
+ param .sched_priority -= 1 ;
1072
+ }
1073
+
1074
+ if (IS_ERR (t ))
1075
+ return PTR_ERR (t );
1076
+
1077
+ sched_setscheduler_nocheck (t , SCHED_FIFO , & param );
1078
+
1079
+ /*
1080
+ * We keep the reference to the task struct even if
1081
+ * the thread dies to avoid that the interrupt code
1082
+ * references an already freed task_struct.
1083
+ */
1084
+ get_task_struct (t );
1085
+ new -> thread = t ;
1086
+ /*
1087
+ * Tell the thread to set its affinity. This is
1088
+ * important for shared interrupt handlers as we do
1089
+ * not invoke setup_affinity() for the secondary
1090
+ * handlers as everything is already set up. Even for
1091
+ * interrupts marked with IRQF_NO_BALANCE this is
1092
+ * correct as we want the thread to move to the cpu(s)
1093
+ * on which the requesting code placed the interrupt.
1094
+ */
1095
+ set_bit (IRQTF_AFFINITY , & new -> thread_flags );
1096
+ return 0 ;
1097
+ }
1098
+
1020
1099
/*
1021
1100
* Internal function to register an irqaction - typically used to
1022
1101
* allocate special interrupts that are part of the architecture.
@@ -1037,6 +1116,8 @@ __setup_irq(unsigned int irq, struct irq_desc *desc, struct irqaction *new)
1037
1116
if (!try_module_get (desc -> owner ))
1038
1117
return - ENODEV ;
1039
1118
1119
+ new -> irq = irq ;
1120
+
1040
1121
/*
1041
1122
* Check whether the interrupt nests into another interrupt
1042
1123
* thread.
@@ -1054,8 +1135,11 @@ __setup_irq(unsigned int irq, struct irq_desc *desc, struct irqaction *new)
1054
1135
*/
1055
1136
new -> handler = irq_nested_primary_handler ;
1056
1137
} else {
1057
- if (irq_settings_can_thread (desc ))
1058
- irq_setup_forced_threading (new );
1138
+ if (irq_settings_can_thread (desc )) {
1139
+ ret = irq_setup_forced_threading (new );
1140
+ if (ret )
1141
+ goto out_mput ;
1142
+ }
1059
1143
}
1060
1144
1061
1145
/*
@@ -1064,37 +1148,14 @@ __setup_irq(unsigned int irq, struct irq_desc *desc, struct irqaction *new)
1064
1148
* thread.
1065
1149
*/
1066
1150
if (new -> thread_fn && !nested ) {
1067
- struct task_struct * t ;
1068
- static const struct sched_param param = {
1069
- .sched_priority = MAX_USER_RT_PRIO /2 ,
1070
- };
1071
-
1072
- t = kthread_create (irq_thread , new , "irq/%d-%s" , irq ,
1073
- new -> name );
1074
- if (IS_ERR (t )) {
1075
- ret = PTR_ERR (t );
1151
+ ret = setup_irq_thread (new , irq , false);
1152
+ if (ret )
1076
1153
goto out_mput ;
1154
+ if (new -> secondary ) {
1155
+ ret = setup_irq_thread (new -> secondary , irq , true);
1156
+ if (ret )
1157
+ goto out_thread ;
1077
1158
}
1078
-
1079
- sched_setscheduler_nocheck (t , SCHED_FIFO , & param );
1080
-
1081
- /*
1082
- * We keep the reference to the task struct even if
1083
- * the thread dies to avoid that the interrupt code
1084
- * references an already freed task_struct.
1085
- */
1086
- get_task_struct (t );
1087
- new -> thread = t ;
1088
- /*
1089
- * Tell the thread to set its affinity. This is
1090
- * important for shared interrupt handlers as we do
1091
- * not invoke setup_affinity() for the secondary
1092
- * handlers as everything is already set up. Even for
1093
- * interrupts marked with IRQF_NO_BALANCE this is
1094
- * correct as we want the thread to move to the cpu(s)
1095
- * on which the requesting code placed the interrupt.
1096
- */
1097
- set_bit (IRQTF_AFFINITY , & new -> thread_flags );
1098
1159
}
1099
1160
1100
1161
if (!alloc_cpumask_var (& mask , GFP_KERNEL )) {
@@ -1267,7 +1328,6 @@ __setup_irq(unsigned int irq, struct irq_desc *desc, struct irqaction *new)
1267
1328
irq , nmsk , omsk );
1268
1329
}
1269
1330
1270
- new -> irq = irq ;
1271
1331
* old_ptr = new ;
1272
1332
1273
1333
irq_pm_install_action (desc , new );
@@ -1293,6 +1353,8 @@ __setup_irq(unsigned int irq, struct irq_desc *desc, struct irqaction *new)
1293
1353
*/
1294
1354
if (new -> thread )
1295
1355
wake_up_process (new -> thread );
1356
+ if (new -> secondary )
1357
+ wake_up_process (new -> secondary -> thread );
1296
1358
1297
1359
register_irq_proc (irq , desc );
1298
1360
new -> dir = NULL ;
@@ -1323,6 +1385,13 @@ __setup_irq(unsigned int irq, struct irq_desc *desc, struct irqaction *new)
1323
1385
kthread_stop (t );
1324
1386
put_task_struct (t );
1325
1387
}
1388
+ if (new -> secondary && new -> secondary -> thread ) {
1389
+ struct task_struct * t = new -> secondary -> thread ;
1390
+
1391
+ new -> secondary -> thread = NULL ;
1392
+ kthread_stop (t );
1393
+ put_task_struct (t );
1394
+ }
1326
1395
out_mput :
1327
1396
module_put (desc -> owner );
1328
1397
return ret ;
@@ -1430,9 +1499,14 @@ static struct irqaction *__free_irq(unsigned int irq, void *dev_id)
1430
1499
if (action -> thread ) {
1431
1500
kthread_stop (action -> thread );
1432
1501
put_task_struct (action -> thread );
1502
+ if (action -> secondary && action -> secondary -> thread ) {
1503
+ kthread_stop (action -> secondary -> thread );
1504
+ put_task_struct (action -> secondary -> thread );
1505
+ }
1433
1506
}
1434
1507
1435
1508
module_put (desc -> owner );
1509
+ kfree (action -> secondary );
1436
1510
return action ;
1437
1511
}
1438
1512
@@ -1576,8 +1650,10 @@ int request_threaded_irq(unsigned int irq, irq_handler_t handler,
1576
1650
retval = __setup_irq (irq , desc , action );
1577
1651
chip_bus_sync_unlock (desc );
1578
1652
1579
- if (retval )
1653
+ if (retval ) {
1654
+ kfree (action -> secondary );
1580
1655
kfree (action );
1656
+ }
1581
1657
1582
1658
#ifdef CONFIG_DEBUG_SHIRQ_FIXME
1583
1659
if (!retval && (irqflags & IRQF_SHARED )) {
0 commit comments