hc
2023-12-11 d2ccde1c8e90d38cee87a1b0309ad2827f3fd30d
kernel/kernel/irq/chip.c
....@@ -282,7 +282,7 @@
282282 }
283283 }
284284 if (resend)
285
- check_irq_resend(desc);
285
+ check_irq_resend(desc, false);
286286
287287 return ret;
288288 }
....@@ -674,16 +674,6 @@
674674 }
675675 EXPORT_SYMBOL_GPL(handle_level_irq);
676676
677
-#ifdef CONFIG_IRQ_PREFLOW_FASTEOI
678
-static inline void preflow_handler(struct irq_desc *desc)
679
-{
680
- if (desc->preflow_handler)
681
- desc->preflow_handler(&desc->irq_data);
682
-}
683
-#else
684
-static inline void preflow_handler(struct irq_desc *desc) { }
685
-#endif
686
-
687677 static void cond_unmask_eoi_irq(struct irq_desc *desc, struct irq_chip *chip)
688678 {
689679 if (!(desc->istate & IRQS_ONESHOT)) {
....@@ -739,7 +729,6 @@
739729 if (desc->istate & IRQS_ONESHOT)
740730 mask_irq(desc);
741731
742
- preflow_handler(desc);
743732 handle_irq_event(desc);
744733
745734 cond_unmask_eoi_irq(desc, chip);
....@@ -752,6 +741,39 @@
752741 raw_spin_unlock(&desc->lock);
753742 }
754743 EXPORT_SYMBOL_GPL(handle_fasteoi_irq);
744
+
745
+/**
746
+ * handle_fasteoi_nmi - irq handler for NMI interrupt lines
747
+ * @desc: the interrupt description structure for this irq
748
+ *
749
+ * A simple NMI-safe handler, considering the restrictions
750
+ * from request_nmi.
751
+ *
752
+ * Only a single callback will be issued to the chip: an ->eoi()
753
+ * call when the interrupt has been serviced. This enables support
754
+ * for modern forms of interrupt handlers, which handle the flow
755
+ * details in hardware, transparently.
756
+ */
757
+void handle_fasteoi_nmi(struct irq_desc *desc)
758
+{
759
+ struct irq_chip *chip = irq_desc_get_chip(desc);
760
+ struct irqaction *action = desc->action;
761
+ unsigned int irq = irq_desc_get_irq(desc);
762
+ irqreturn_t res;
763
+
764
+ __kstat_incr_irqs_this_cpu(desc);
765
+
766
+ trace_irq_handler_entry(irq, action);
767
+ /*
768
+ * NMIs cannot be shared, there is only one action.
769
+ */
770
+ res = action->handler(irq, action->dev_id);
771
+ trace_irq_handler_exit(irq, action, res);
772
+
773
+ if (chip->irq_eoi)
774
+ chip->irq_eoi(&desc->irq_data);
775
+}
776
+EXPORT_SYMBOL_GPL(handle_fasteoi_nmi);
755777
756778 /**
757779 * handle_edge_irq - edge type IRQ handler
....@@ -940,6 +962,58 @@
940962 chip->irq_eoi(&desc->irq_data);
941963 }
942964
965
+/**
966
+ * handle_percpu_devid_fasteoi_ipi - Per CPU local IPI handler with per cpu
967
+ * dev ids
968
+ * @desc: the interrupt description structure for this irq
969
+ *
970
+ * The biggest difference with the IRQ version is that the interrupt is
971
+ * EOIed early, as the IPI could result in a context switch, and we need to
972
+ * make sure the IPI can fire again. We also assume that the arch code has
973
+ * registered an action. If not, we are positively doomed.
974
+ */
975
+void handle_percpu_devid_fasteoi_ipi(struct irq_desc *desc)
976
+{
977
+ struct irq_chip *chip = irq_desc_get_chip(desc);
978
+ struct irqaction *action = desc->action;
979
+ unsigned int irq = irq_desc_get_irq(desc);
980
+ irqreturn_t res;
981
+
982
+ __kstat_incr_irqs_this_cpu(desc);
983
+
984
+ if (chip->irq_eoi)
985
+ chip->irq_eoi(&desc->irq_data);
986
+
987
+ trace_irq_handler_entry(irq, action);
988
+ res = action->handler(irq, raw_cpu_ptr(action->percpu_dev_id));
989
+ trace_irq_handler_exit(irq, action, res);
990
+}
991
+
992
+/**
993
+ * handle_percpu_devid_fasteoi_nmi - Per CPU local NMI handler with per cpu
994
+ * dev ids
995
+ * @desc: the interrupt description structure for this irq
996
+ *
997
+ * Similar to handle_fasteoi_nmi, but handling the dev_id cookie
998
+ * as a percpu pointer.
999
+ */
1000
+void handle_percpu_devid_fasteoi_nmi(struct irq_desc *desc)
1001
+{
1002
+ struct irq_chip *chip = irq_desc_get_chip(desc);
1003
+ struct irqaction *action = desc->action;
1004
+ unsigned int irq = irq_desc_get_irq(desc);
1005
+ irqreturn_t res;
1006
+
1007
+ __kstat_incr_irqs_this_cpu(desc);
1008
+
1009
+ trace_irq_handler_entry(irq, action);
1010
+ res = action->handler(irq, raw_cpu_ptr(action->percpu_dev_id));
1011
+ trace_irq_handler_exit(irq, action, res);
1012
+
1013
+ if (chip->irq_eoi)
1014
+ chip->irq_eoi(&desc->irq_data);
1015
+}
1016
+
9431017 static void
9441018 __irq_do_set_handler(struct irq_desc *desc, irq_flow_handler_t handle,
9451019 int is_chained, const char *name)
....@@ -961,7 +1035,7 @@
9611035 break;
9621036 /*
9631037 * Bail out if the outer chip is not set up
964
- * and the interrrupt supposed to be started
1038
+ * and the interrupt supposed to be started
9651039 * right away.
9661040 */
9671041 if (WARN_ON(is_chained))
....@@ -1051,7 +1125,8 @@
10511125 }
10521126 EXPORT_SYMBOL_GPL(irq_set_chip_and_handler_name);
10531127
1054
-void irq_modify_status(unsigned int irq, unsigned long clr, unsigned long set)
1128
+void __irq_modify_status(unsigned int irq, unsigned long clr,
1129
+ unsigned long set, unsigned long mask)
10551130 {
10561131 unsigned long flags, trigger, tmp;
10571132 struct irq_desc *desc = irq_get_desc_lock(irq, &flags, 0);
....@@ -1065,7 +1140,9 @@
10651140 */
10661141 WARN_ON_ONCE(!desc->depth && (set & _IRQ_NOAUTOEN));
10671142
1068
- irq_settings_clr_and_set(desc, clr, set);
1143
+ /* Warn when trying to clear or set a bit disallowed by the mask */
1144
+ WARN_ON((clr | set) & ~mask);
1145
+ __irq_settings_clr_and_set(desc, clr, set, mask);
10691146
10701147 trigger = irqd_get_trigger_type(&desc->irq_data);
10711148
....@@ -1087,6 +1164,11 @@
10871164 irqd_set(&desc->irq_data, trigger);
10881165
10891166 irq_put_desc_unlock(desc, flags);
1167
+}
1168
+
1169
+void irq_modify_status(unsigned int irq, unsigned long clr, unsigned long set)
1170
+{
1171
+ __irq_modify_status(irq, clr, set, _IRQF_MODIFY_MASK);
10901172 }
10911173 EXPORT_SYMBOL_GPL(irq_modify_status);
10921174
....@@ -1191,7 +1273,6 @@
11911273 /* Start handling the irq */
11921274 desc->irq_data.chip->irq_ack(&desc->irq_data);
11931275
1194
- preflow_handler(desc);
11951276 handle_irq_event(desc);
11961277
11971278 cond_unmask_eoi_irq(desc, chip);
....@@ -1241,7 +1322,6 @@
12411322 if (desc->istate & IRQS_ONESHOT)
12421323 mask_irq(desc);
12431324
1244
- preflow_handler(desc);
12451325 handle_irq_event(desc);
12461326
12471327 cond_unmask_eoi_irq(desc, chip);
....@@ -1258,48 +1338,48 @@
12581338 #endif /* CONFIG_IRQ_FASTEOI_HIERARCHY_HANDLERS */
12591339
12601340 /**
1261
- * irq_chip_set_parent_state - set the state of a parent interrupt.
1262
- * @data: Pointer to interrupt specific data
1263
- * @which: State to be restored (one of IRQCHIP_STATE_*)
1264
- * @val: Value corresponding to @which
1341
+ * irq_chip_set_parent_state - set the state of a parent interrupt.
12651342 *
1343
+ * @data: Pointer to interrupt specific data
1344
+ * @which: State to be restored (one of IRQCHIP_STATE_*)
1345
+ * @val: Value corresponding to @which
1346
+ *
1347
+ * Conditional success, if the underlying irqchip does not implement it.
12661348 */
12671349 int irq_chip_set_parent_state(struct irq_data *data,
12681350 enum irqchip_irq_state which,
12691351 bool val)
12701352 {
12711353 data = data->parent_data;
1272
- if (!data)
1354
+
1355
+ if (!data || !data->chip->irq_set_irqchip_state)
12731356 return 0;
12741357
1275
- if (data->chip->irq_set_irqchip_state)
1276
- return data->chip->irq_set_irqchip_state(data, which, val);
1277
-
1278
- return 0;
1358
+ return data->chip->irq_set_irqchip_state(data, which, val);
12791359 }
1280
-EXPORT_SYMBOL(irq_chip_set_parent_state);
1360
+EXPORT_SYMBOL_GPL(irq_chip_set_parent_state);
12811361
12821362 /**
1283
- * irq_chip_get_parent_state - get the state of a parent interrupt.
1284
- * @data: Pointer to interrupt specific data
1285
- * @which: one of IRQCHIP_STATE_* the caller wants to know
1286
- * @state: a pointer to a boolean where the state is to be stored
1363
+ * irq_chip_get_parent_state - get the state of a parent interrupt.
12871364 *
1365
+ * @data: Pointer to interrupt specific data
1366
+ * @which: one of IRQCHIP_STATE_* the caller wants to know
1367
+ * @state: a pointer to a boolean where the state is to be stored
1368
+ *
1369
+ * Conditional success, if the underlying irqchip does not implement it.
12881370 */
12891371 int irq_chip_get_parent_state(struct irq_data *data,
12901372 enum irqchip_irq_state which,
12911373 bool *state)
12921374 {
12931375 data = data->parent_data;
1294
- if (!data)
1376
+
1377
+ if (!data || !data->chip->irq_get_irqchip_state)
12951378 return 0;
12961379
1297
- if (data->chip->irq_get_irqchip_state)
1298
- return data->chip->irq_get_irqchip_state(data, which, state);
1299
-
1300
- return 0;
1380
+ return data->chip->irq_get_irqchip_state(data, which, state);
13011381 }
1302
-EXPORT_SYMBOL(irq_chip_get_parent_state);
1382
+EXPORT_SYMBOL_GPL(irq_chip_get_parent_state);
13031383
13041384 /**
13051385 * irq_chip_enable_parent - Enable the parent interrupt (defaults to unmask if
....@@ -1352,6 +1432,17 @@
13521432 data->chip->irq_mask(data);
13531433 }
13541434 EXPORT_SYMBOL_GPL(irq_chip_mask_parent);
1435
+
1436
+/**
1437
+ * irq_chip_mask_ack_parent - Mask and acknowledge the parent interrupt
1438
+ * @data: Pointer to interrupt specific data
1439
+ */
1440
+void irq_chip_mask_ack_parent(struct irq_data *data)
1441
+{
1442
+ data = data->parent_data;
1443
+ data->chip->irq_mask_ack(data);
1444
+}
1445
+EXPORT_SYMBOL_GPL(irq_chip_mask_ack_parent);
13551446
13561447 /**
13571448 * irq_chip_unmask_parent - Unmask the parent interrupt
....@@ -1443,7 +1534,6 @@
14431534 return -ENOSYS;
14441535 }
14451536 EXPORT_SYMBOL_GPL(irq_chip_set_vcpu_affinity_parent);
1446
-
14471537 /**
14481538 * irq_chip_set_wake_parent - Set/reset wake-up on the parent interrupt
14491539 * @data: Pointer to interrupt specific data
....@@ -1464,6 +1554,34 @@
14641554 return -ENOSYS;
14651555 }
14661556 EXPORT_SYMBOL_GPL(irq_chip_set_wake_parent);
1557
+
1558
+/**
1559
+ * irq_chip_request_resources_parent - Request resources on the parent interrupt
1560
+ * @data: Pointer to interrupt specific data
1561
+ */
1562
+int irq_chip_request_resources_parent(struct irq_data *data)
1563
+{
1564
+ data = data->parent_data;
1565
+
1566
+ if (data->chip->irq_request_resources)
1567
+ return data->chip->irq_request_resources(data);
1568
+
1569
+ /* no error on missing optional irq_chip::irq_request_resources */
1570
+ return 0;
1571
+}
1572
+EXPORT_SYMBOL_GPL(irq_chip_request_resources_parent);
1573
+
1574
+/**
1575
+ * irq_chip_release_resources_parent - Release resources on the parent interrupt
1576
+ * @data: Pointer to interrupt specific data
1577
+ */
1578
+void irq_chip_release_resources_parent(struct irq_data *data)
1579
+{
1580
+ data = data->parent_data;
1581
+ if (data->chip->irq_release_resources)
1582
+ data->chip->irq_release_resources(data);
1583
+}
1584
+EXPORT_SYMBOL_GPL(irq_chip_release_resources_parent);
14671585 #endif
14681586
14691587 /**
....@@ -1477,18 +1595,17 @@
14771595 */
14781596 int irq_chip_compose_msi_msg(struct irq_data *data, struct msi_msg *msg)
14791597 {
1480
- struct irq_data *pos = NULL;
1598
+ struct irq_data *pos;
14811599
1482
-#ifdef CONFIG_IRQ_DOMAIN_HIERARCHY
1483
- for (; data; data = data->parent_data)
1484
-#endif
1600
+ for (pos = NULL; !pos && data; data = irqd_get_parent_data(data)) {
14851601 if (data->chip && data->chip->irq_compose_msi_msg)
14861602 pos = data;
1603
+ }
1604
+
14871605 if (!pos)
14881606 return -ENOSYS;
14891607
14901608 pos->chip->irq_compose_msi_msg(pos, msg);
1491
-
14921609 return 0;
14931610 }
14941611