From a46a1ad097419aeea7350987dd95230f50d90392 Mon Sep 17 00:00:00 2001
From: hc <hc@nodka.com>
Date: Fri, 15 Nov 2024 08:53:41 +0000
Subject: [PATCH] 固定GMAC1 网卡名为 eth3
---
kernel/kernel/irq/manage.c | 89 ++++++++++++++++++++++++++++++++++++++------
1 files changed, 77 insertions(+), 12 deletions(-)
diff --git a/kernel/kernel/irq/manage.c b/kernel/kernel/irq/manage.c
index 76da8de..4b06f5a 100644
--- a/kernel/kernel/irq/manage.c
+++ b/kernel/kernel/irq/manage.c
@@ -10,6 +10,7 @@
#include <linux/irq.h>
#include <linux/kthread.h>
+#include <linux/kconfig.h>
#include <linux/module.h>
#include <linux/random.h>
#include <linux/interrupt.h>
@@ -829,6 +830,50 @@
}
EXPORT_SYMBOL(irq_set_irq_wake);
+#ifdef CONFIG_IRQ_PIPELINE
+
+/**
+ * irq_switch_oob - Control out-of-band setting for a registered IRQ descriptor
+ * @irq: interrupt to control
+ * @on: enable/disable pipelining
+ *
+ * Enable/disable out-of-band handling for an IRQ. At least one
+ * action must have been previously registered for such
+ * interrupt.
+ *
+ * The previously registered action(s) need(s) not bearing the
+ * IRQF_OOB flag for the IRQ to be switched to out-of-band
+ * handling. This call enables switching pre-installed IRQs from
+ * in-band to out-of-band handling.
+ *
+ * NOTE: This routine affects all action handlers sharing the
+ * IRQ.
+ */
+int irq_switch_oob(unsigned int irq, bool on)
+{
+ struct irq_desc *desc;
+ unsigned long flags;
+ int ret = 0;
+
+ desc = irq_get_desc_lock(irq, &flags, 0);
+ if (!desc)
+ return -EINVAL;
+
+ if (!desc->action)
+ ret = -EINVAL;
+ else if (on)
+ irq_settings_set_oob(desc);
+ else
+ irq_settings_clr_oob(desc);
+
+ irq_put_desc_unlock(desc, flags);
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(irq_switch_oob);
+
+#endif /* CONFIG_IRQ_PIPELINE */
+
/*
* Internal function that tells the architecture code whether a
* particular irq has been exclusively allocated or is available
@@ -845,7 +890,8 @@
if (irq_settings_can_request(desc)) {
if (!desc->action ||
- irqflags & desc->action->flags & IRQF_SHARED)
+ ((irqflags & desc->action->flags & IRQF_SHARED) &&
+ !((irqflags ^ desc->action->flags) & IRQF_OOB)))
canrequest = 1;
}
irq_put_desc_unlock(desc, flags);
@@ -1419,6 +1465,21 @@
new->irq = irq;
+ ret = -EINVAL;
+ /*
+ * Out-of-band interrupts can be shared but not threaded. We
+ * silently ignore the OOB setting if interrupt pipelining is
+ * disabled.
+ */
+ if (!irqs_pipelined())
+ new->flags &= ~IRQF_OOB;
+ else if (new->flags & IRQF_OOB) {
+ if (new->thread_fn)
+ goto out_mput;
+ new->flags |= IRQF_NO_THREAD;
+ new->flags &= ~IRQF_ONESHOT;
+ }
+
/*
* If the trigger type is not specified by the caller,
* then use the default for this interrupt.
@@ -1432,10 +1493,8 @@
*/
nested = irq_settings_is_nested_thread(desc);
if (nested) {
- if (!new->thread_fn) {
- ret = -EINVAL;
+ if (!new->thread_fn)
goto out_mput;
- }
/*
* Replace the primary handler which was provided from
* the driver for non nested interrupt handling by the
@@ -1519,7 +1578,7 @@
* the same type (level, edge, polarity). So both flag
* fields must have IRQF_SHARED set and the bits which
* set the trigger type must match. Also all must
- * agree on ONESHOT.
+ * agree on ONESHOT and OOB.
* Interrupt lines used for NMIs cannot be shared.
*/
unsigned int oldtype;
@@ -1544,7 +1603,7 @@
if (!((old->flags & new->flags) & IRQF_SHARED) ||
(oldtype != (new->flags & IRQF_TRIGGER_MASK)) ||
- ((old->flags ^ new->flags) & IRQF_ONESHOT))
+ ((old->flags ^ new->flags) & (IRQF_OOB|IRQF_ONESHOT)))
goto mismatch;
/* All handlers must agree on per-cpuness */
@@ -1661,6 +1720,9 @@
if (new->flags & IRQF_ONESHOT)
desc->istate |= IRQS_ONESHOT;
+
+ if (new->flags & IRQF_OOB)
+ irq_settings_set_oob(desc);
/* Exclude IRQ from balancing if requested */
if (new->flags & IRQF_NOBALANCING) {
@@ -1809,6 +1871,8 @@
irq_settings_clr_disable_unlazy(desc);
/* Only shutdown. Deactivate after synchronize_hardirq() */
irq_shutdown(desc);
+ /* Turn off OOB handling (after shutdown). */
+ irq_settings_clr_oob(desc);
}
#ifdef CONFIG_SMP
@@ -1845,14 +1909,15 @@
#ifdef CONFIG_DEBUG_SHIRQ
/*
- * It's a shared IRQ -- the driver ought to be prepared for an IRQ
- * event to happen even now it's being freed, so let's make sure that
- * is so by doing an extra call to the handler ....
+ * It's a shared IRQ (with in-band handler) -- the driver
+ * ought to be prepared for an IRQ event to happen even now
+ * it's being freed, so let's make sure that is so by doing an
+ * extra call to the handler ....
*
* ( We do this after actually deregistering it, to make sure that a
* 'real' IRQ doesn't run in parallel with our fake. )
*/
- if (action->flags & IRQF_SHARED) {
+ if ((action->flags & (IRQF_SHARED|IRQF_OOB)) == IRQF_SHARED) {
local_irq_save(flags);
action->handler(irq, dev_id);
local_irq_restore(flags);
@@ -2473,7 +2538,7 @@
* __request_percpu_irq - allocate a percpu interrupt line
* @irq: Interrupt line to allocate
* @handler: Function to be called when the IRQ occurs.
- * @flags: Interrupt type flags (IRQF_TIMER only)
+ * @flags: Interrupt type flags (IRQF_TIMER and/or IRQF_OOB only)
* @devname: An ascii name for the claiming device
* @dev_id: A percpu cookie passed back to the handler function
*
@@ -2502,7 +2567,7 @@
!irq_settings_is_per_cpu_devid(desc))
return -EINVAL;
- if (flags && flags != IRQF_TIMER)
+ if (flags & ~(IRQF_TIMER|IRQF_OOB))
return -EINVAL;
action = kzalloc(sizeof(struct irqaction), GFP_KERNEL);
--
Gitblit v1.6.2