All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v5 0/2] add IRQF_NO_AUTOEN for request_irq
@ 2021-03-02 22:49 Barry Song
  2021-03-02 22:49 ` [PATCH v5 1/2] genirq: " Barry Song
  2021-03-02 22:49 ` [PATCH v5 2/2] Input: move to use request_irq by IRQF_NO_AUTOEN flag Barry Song
  0 siblings, 2 replies; 11+ messages in thread
From: Barry Song @ 2021-03-02 22:49 UTC (permalink / raw)
  To: tglx, dmitry.torokhov, linux-input, linux-kernel
  Cc: maz, gregkh, linuxarm, jonathan.cameron, Barry Song

-v5:
  * add the same check for IRQF_NO_AUTOEN in request_nmi()
  * combine a dozen of separate patches of input into one (hopefully
    this could easy the life of the maintainers)

-v4:
  * remove the irq_settings magic for NOAUTOEN with respect to
    Thomas's comment

Barry Song (2):
  genirq: add IRQF_NO_AUTOEN for request_irq
  Input: move to use request_irq by IRQF_NO_AUTOEN flag

 drivers/input/keyboard/tca6416-keypad.c  |  3 +--
 drivers/input/keyboard/tegra-kbc.c       |  5 ++---
 drivers/input/touchscreen/ar1021_i2c.c   |  5 +----
 drivers/input/touchscreen/atmel_mxt_ts.c |  5 ++---
 drivers/input/touchscreen/bu21029_ts.c   |  4 ++--
 drivers/input/touchscreen/cyttsp_core.c  |  5 ++---
 drivers/input/touchscreen/melfas_mip4.c  |  5 ++---
 drivers/input/touchscreen/mms114.c       |  4 ++--
 drivers/input/touchscreen/stmfts.c       |  3 +--
 drivers/input/touchscreen/wm831x-ts.c    |  3 +--
 drivers/input/touchscreen/zinitix.c      |  4 ++--
 include/linux/interrupt.h                |  4 ++++
 kernel/irq/manage.c                      | 11 +++++++++--
 13 files changed, 31 insertions(+), 30 deletions(-)

-- 
2.25.1


^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH v5 1/2] genirq: add IRQF_NO_AUTOEN for request_irq
  2021-03-02 22:49 [PATCH v5 0/2] add IRQF_NO_AUTOEN for request_irq Barry Song
@ 2021-03-02 22:49 ` Barry Song
  2021-03-04 10:53   ` [tip: irq/core] genirq: Add IRQF_NO_AUTOEN for request_irq/nmi() tip-bot2 for Barry Song
  2021-03-06 11:54   ` tip-bot2 for Barry Song
  2021-03-02 22:49 ` [PATCH v5 2/2] Input: move to use request_irq by IRQF_NO_AUTOEN flag Barry Song
  1 sibling, 2 replies; 11+ messages in thread
From: Barry Song @ 2021-03-02 22:49 UTC (permalink / raw)
  To: tglx, dmitry.torokhov, linux-input, linux-kernel
  Cc: maz, gregkh, linuxarm, jonathan.cameron, Barry Song

Many drivers don't want interrupts enabled automatically due to
request_irq(). So they are handling this issue by either way of
the below two:
(1)
irq_set_status_flags(irq, IRQ_NOAUTOEN);
request_irq(dev, irq...);
(2)
request_irq(dev, irq...);
disable_irq(irq);

The code in the second way is silly and unsafe. In the small time
gap between request_irq() and disable_irq(), interrupts can still
come.
The code in the first way is safe though we might be able to do it
in the generic irq code.

With this patch, drivers can request_irq with IRQF_NO_AUTOEN flag.
They will need neither irq_set_status_flags() nor disable_irq().

In the meantime, drivers using the below pattern for NMI
irq_set_status_flags(irq, IRQ_NOAUTOEN);
request_nmi(dev, irq...);

can also move to request_nmi() with IRQF_NO_AUTOEN flag.

Cc: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Signed-off-by: Barry Song <song.bao.hua@hisilicon.com>
---
-v5:
  * add the same check for IRQF_NO_AUTOEN in request_nmi()

 include/linux/interrupt.h |  4 ++++
 kernel/irq/manage.c       | 11 +++++++++--
 2 files changed, 13 insertions(+), 2 deletions(-)

diff --git a/include/linux/interrupt.h b/include/linux/interrupt.h
index 967e25767153..76f1161a441a 100644
--- a/include/linux/interrupt.h
+++ b/include/linux/interrupt.h
@@ -61,6 +61,9 @@
  *                interrupt handler after suspending interrupts. For system
  *                wakeup devices users need to implement wakeup detection in
  *                their interrupt handlers.
+ * IRQF_NO_AUTOEN - Don't enable IRQ or NMI automatically when users request it.
+ *                Users will enable it explicitly by enable_irq() or enable_nmi()
+ *                later.
  */
 #define IRQF_SHARED		0x00000080
 #define IRQF_PROBE_SHARED	0x00000100
@@ -74,6 +77,7 @@
 #define IRQF_NO_THREAD		0x00010000
 #define IRQF_EARLY_RESUME	0x00020000
 #define IRQF_COND_SUSPEND	0x00040000
+#define IRQF_NO_AUTOEN		0x00080000
 
 #define IRQF_TIMER		(__IRQF_TIMER | IRQF_NO_SUSPEND | IRQF_NO_THREAD)
 
diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c
index dec3f73e8db9..97c231a5644c 100644
--- a/kernel/irq/manage.c
+++ b/kernel/irq/manage.c
@@ -1693,7 +1693,8 @@ __setup_irq(unsigned int irq, struct irq_desc *desc, struct irqaction *new)
 			irqd_set(&desc->irq_data, IRQD_NO_BALANCING);
 		}
 
-		if (irq_settings_can_autoenable(desc)) {
+		if (!(new->flags & IRQF_NO_AUTOEN) &&
+		    irq_settings_can_autoenable(desc)) {
 			irq_startup(desc, IRQ_RESEND, IRQ_START_COND);
 		} else {
 			/*
@@ -2086,10 +2087,15 @@ int request_threaded_irq(unsigned int irq, irq_handler_t handler,
 	 * which interrupt is which (messes up the interrupt freeing
 	 * logic etc).
 	 *
+	 * Also shared interrupts do not go well with disabling auto enable.
+	 * The sharing interrupt might request it while it's still disabled
+	 * and then wait for interrupts forever.
+	 *
 	 * Also IRQF_COND_SUSPEND only makes sense for shared interrupts and
 	 * it cannot be set along with IRQF_NO_SUSPEND.
 	 */
 	if (((irqflags & IRQF_SHARED) && !dev_id) ||
+	    ((irqflags & IRQF_SHARED) && (irqflags & IRQF_NO_AUTOEN)) ||
 	    (!(irqflags & IRQF_SHARED) && (irqflags & IRQF_COND_SUSPEND)) ||
 	    ((irqflags & IRQF_NO_SUSPEND) && (irqflags & IRQF_COND_SUSPEND)))
 		return -EINVAL;
@@ -2245,7 +2251,8 @@ int request_nmi(unsigned int irq, irq_handler_t handler,
 
 	desc = irq_to_desc(irq);
 
-	if (!desc || irq_settings_can_autoenable(desc) ||
+	if (!desc || (irq_settings_can_autoenable(desc) &&
+	    !(irqflags & IRQF_NO_AUTOEN)) ||
 	    !irq_settings_can_request(desc) ||
 	    WARN_ON(irq_settings_is_per_cpu_devid(desc)) ||
 	    !irq_supports_nmi(desc))
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH v5 2/2] Input: move to use request_irq by IRQF_NO_AUTOEN flag
  2021-03-02 22:49 [PATCH v5 0/2] add IRQF_NO_AUTOEN for request_irq Barry Song
  2021-03-02 22:49 ` [PATCH v5 1/2] genirq: " Barry Song
@ 2021-03-02 22:49 ` Barry Song
  2021-03-25 22:31   ` Dmitry Torokhov
  1 sibling, 1 reply; 11+ messages in thread
From: Barry Song @ 2021-03-02 22:49 UTC (permalink / raw)
  To: tglx, dmitry.torokhov, linux-input, linux-kernel
  Cc: maz, gregkh, linuxarm, jonathan.cameron, Barry Song

disable_irq() after request_irq() still has a time gap in which
interrupts can come. request_irq() with IRQF_NO_AUTOEN flag will
disable IRQ auto-enable because of requesting.

On the other hand, request_irq() after setting IRQ_NOAUTOEN as
below
irq_set_status_flags(irq, IRQ_NOAUTOEN);
request_irq(dev, irq...);
can also be replaced by request_irq() with IRQF_NO_AUTOEN flag.

Signed-off-by: Barry Song <song.bao.hua@hisilicon.com>
---
 drivers/input/keyboard/tca6416-keypad.c  | 3 +--
 drivers/input/keyboard/tegra-kbc.c       | 5 ++---
 drivers/input/touchscreen/ar1021_i2c.c   | 5 +----
 drivers/input/touchscreen/atmel_mxt_ts.c | 5 ++---
 drivers/input/touchscreen/bu21029_ts.c   | 4 ++--
 drivers/input/touchscreen/cyttsp_core.c  | 5 ++---
 drivers/input/touchscreen/melfas_mip4.c  | 5 ++---
 drivers/input/touchscreen/mms114.c       | 4 ++--
 drivers/input/touchscreen/stmfts.c       | 3 +--
 drivers/input/touchscreen/wm831x-ts.c    | 3 +--
 drivers/input/touchscreen/zinitix.c      | 4 ++--
 11 files changed, 18 insertions(+), 28 deletions(-)

diff --git a/drivers/input/keyboard/tca6416-keypad.c b/drivers/input/keyboard/tca6416-keypad.c
index 9b0f9665dcb0..2a9755910065 100644
--- a/drivers/input/keyboard/tca6416-keypad.c
+++ b/drivers/input/keyboard/tca6416-keypad.c
@@ -274,7 +274,7 @@ static int tca6416_keypad_probe(struct i2c_client *client,
 		error = request_threaded_irq(chip->irqnum, NULL,
 					     tca6416_keys_isr,
 					     IRQF_TRIGGER_FALLING |
-						IRQF_ONESHOT,
+					     IRQF_ONESHOT | IRQF_NO_AUTOEN,
 					     "tca6416-keypad", chip);
 		if (error) {
 			dev_dbg(&client->dev,
@@ -282,7 +282,6 @@ static int tca6416_keypad_probe(struct i2c_client *client,
 				chip->irqnum, error);
 			goto fail1;
 		}
-		disable_irq(chip->irqnum);
 	}
 
 	error = input_register_device(input);
diff --git a/drivers/input/keyboard/tegra-kbc.c b/drivers/input/keyboard/tegra-kbc.c
index 9671842a082a..570fe18c0ce9 100644
--- a/drivers/input/keyboard/tegra-kbc.c
+++ b/drivers/input/keyboard/tegra-kbc.c
@@ -694,14 +694,13 @@ static int tegra_kbc_probe(struct platform_device *pdev)
 	input_set_drvdata(kbc->idev, kbc);
 
 	err = devm_request_irq(&pdev->dev, kbc->irq, tegra_kbc_isr,
-			       IRQF_TRIGGER_HIGH, pdev->name, kbc);
+			       IRQF_TRIGGER_HIGH | IRQF_NO_AUTOEN,
+			       pdev->name, kbc);
 	if (err) {
 		dev_err(&pdev->dev, "failed to request keyboard IRQ\n");
 		return err;
 	}
 
-	disable_irq(kbc->irq);
-
 	err = input_register_device(kbc->idev);
 	if (err) {
 		dev_err(&pdev->dev, "failed to register input device\n");
diff --git a/drivers/input/touchscreen/ar1021_i2c.c b/drivers/input/touchscreen/ar1021_i2c.c
index c0d5c2413356..dc6a85362a40 100644
--- a/drivers/input/touchscreen/ar1021_i2c.c
+++ b/drivers/input/touchscreen/ar1021_i2c.c
@@ -125,7 +125,7 @@ static int ar1021_i2c_probe(struct i2c_client *client,
 
 	error = devm_request_threaded_irq(&client->dev, client->irq,
 					  NULL, ar1021_i2c_irq,
-					  IRQF_ONESHOT,
+					  IRQF_ONESHOT | IRQF_NO_AUTOEN,
 					  "ar1021_i2c", ar1021);
 	if (error) {
 		dev_err(&client->dev,
@@ -133,9 +133,6 @@ static int ar1021_i2c_probe(struct i2c_client *client,
 		return error;
 	}
 
-	/* Disable the IRQ, we'll enable it in ar1021_i2c_open() */
-	disable_irq(client->irq);
-
 	error = input_register_device(ar1021->input);
 	if (error) {
 		dev_err(&client->dev,
diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c
index 383a848eb601..3c837c7b24b3 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -3156,15 +3156,14 @@ static int mxt_probe(struct i2c_client *client, const struct i2c_device_id *id)
 	}
 
 	error = devm_request_threaded_irq(&client->dev, client->irq,
-					  NULL, mxt_interrupt, IRQF_ONESHOT,
+					  NULL, mxt_interrupt,
+					  IRQF_ONESHOT | IRQF_NO_AUTOEN,
 					  client->name, data);
 	if (error) {
 		dev_err(&client->dev, "Failed to register interrupt\n");
 		return error;
 	}
 
-	disable_irq(client->irq);
-
 	error = regulator_bulk_enable(ARRAY_SIZE(data->regulators),
 				      data->regulators);
 	if (error) {
diff --git a/drivers/input/touchscreen/bu21029_ts.c b/drivers/input/touchscreen/bu21029_ts.c
index 341925edb8e6..392950aa7856 100644
--- a/drivers/input/touchscreen/bu21029_ts.c
+++ b/drivers/input/touchscreen/bu21029_ts.c
@@ -401,10 +401,10 @@ static int bu21029_probe(struct i2c_client *client,
 
 	input_set_drvdata(in_dev, bu21029);
 
-	irq_set_status_flags(client->irq, IRQ_NOAUTOEN);
 	error = devm_request_threaded_irq(&client->dev, client->irq,
 					  NULL, bu21029_touch_soft_irq,
-					  IRQF_ONESHOT, DRIVER_NAME, bu21029);
+					  IRQF_ONESHOT | IRQF_NO_AUTOEN,
+					  DRIVER_NAME, bu21029);
 	if (error) {
 		dev_err(&client->dev,
 			"unable to request touch irq: %d\n", error);
diff --git a/drivers/input/touchscreen/cyttsp_core.c b/drivers/input/touchscreen/cyttsp_core.c
index 73c854f35f33..d5c933604168 100644
--- a/drivers/input/touchscreen/cyttsp_core.c
+++ b/drivers/input/touchscreen/cyttsp_core.c
@@ -652,7 +652,8 @@ struct cyttsp *cyttsp_probe(const struct cyttsp_bus_ops *bus_ops,
 	}
 
 	error = devm_request_threaded_irq(dev, ts->irq, NULL, cyttsp_irq,
-					  IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
+					  IRQF_TRIGGER_FALLING | IRQF_ONESHOT |
+					  IRQF_NO_AUTOEN,
 					  "cyttsp", ts);
 	if (error) {
 		dev_err(ts->dev, "failed to request IRQ %d, err: %d\n",
@@ -660,8 +661,6 @@ struct cyttsp *cyttsp_probe(const struct cyttsp_bus_ops *bus_ops,
 		return ERR_PTR(error);
 	}
 
-	disable_irq(ts->irq);
-
 	cyttsp_hard_reset(ts);
 
 	error = cyttsp_power_on(ts);
diff --git a/drivers/input/touchscreen/melfas_mip4.c b/drivers/input/touchscreen/melfas_mip4.c
index 225796a3f546..2745bf1aee38 100644
--- a/drivers/input/touchscreen/melfas_mip4.c
+++ b/drivers/input/touchscreen/melfas_mip4.c
@@ -1502,7 +1502,8 @@ static int mip4_probe(struct i2c_client *client, const struct i2c_device_id *id)
 
 	error = devm_request_threaded_irq(&client->dev, client->irq,
 					  NULL, mip4_interrupt,
-					  IRQF_ONESHOT, MIP4_DEVICE_NAME, ts);
+					  IRQF_ONESHOT | IRQF_NO_AUTOEN,
+					  MIP4_DEVICE_NAME, ts);
 	if (error) {
 		dev_err(&client->dev,
 			"Failed to request interrupt %d: %d\n",
@@ -1510,8 +1511,6 @@ static int mip4_probe(struct i2c_client *client, const struct i2c_device_id *id)
 		return error;
 	}
 
-	disable_irq(client->irq);
-
 	error = input_register_device(input);
 	if (error) {
 		dev_err(&client->dev,
diff --git a/drivers/input/touchscreen/mms114.c b/drivers/input/touchscreen/mms114.c
index 16557f51b09d..7043f57ea2dd 100644
--- a/drivers/input/touchscreen/mms114.c
+++ b/drivers/input/touchscreen/mms114.c
@@ -530,13 +530,13 @@ static int mms114_probe(struct i2c_client *client,
 	}
 
 	error = devm_request_threaded_irq(&client->dev, client->irq,
-					  NULL, mms114_interrupt, IRQF_ONESHOT,
+					  NULL, mms114_interrupt,
+					  IRQF_ONESHOT | IRQF_NO_AUTOEN,
 					  dev_name(&client->dev), data);
 	if (error) {
 		dev_err(&client->dev, "Failed to register interrupt\n");
 		return error;
 	}
-	disable_irq(client->irq);
 
 	error = input_register_device(data->input_dev);
 	if (error) {
diff --git a/drivers/input/touchscreen/stmfts.c b/drivers/input/touchscreen/stmfts.c
index 9a64e1dbc04a..bc11203c9cf7 100644
--- a/drivers/input/touchscreen/stmfts.c
+++ b/drivers/input/touchscreen/stmfts.c
@@ -691,10 +691,9 @@ static int stmfts_probe(struct i2c_client *client,
 	 * interrupts. To be on the safe side it's better to not enable
 	 * the interrupts during their request.
 	 */
-	irq_set_status_flags(client->irq, IRQ_NOAUTOEN);
 	err = devm_request_threaded_irq(&client->dev, client->irq,
 					NULL, stmfts_irq_handler,
-					IRQF_ONESHOT,
+					IRQF_ONESHOT | IRQF_NO_AUTOEN,
 					"stmfts_irq", sdata);
 	if (err)
 		return err;
diff --git a/drivers/input/touchscreen/wm831x-ts.c b/drivers/input/touchscreen/wm831x-ts.c
index bb1699e0d3c7..319f57fb9af5 100644
--- a/drivers/input/touchscreen/wm831x-ts.c
+++ b/drivers/input/touchscreen/wm831x-ts.c
@@ -317,14 +317,13 @@ static int wm831x_ts_probe(struct platform_device *pdev)
 
 	error = request_threaded_irq(wm831x_ts->data_irq,
 				     NULL, wm831x_ts_data_irq,
-				     irqf | IRQF_ONESHOT,
+				     irqf | IRQF_ONESHOT | IRQF_NO_AUTOEN,
 				     "Touchscreen data", wm831x_ts);
 	if (error) {
 		dev_err(&pdev->dev, "Failed to request data IRQ %d: %d\n",
 			wm831x_ts->data_irq, error);
 		goto err_alloc;
 	}
-	disable_irq(wm831x_ts->data_irq);
 
 	if (pdata && pdata->pd_irqf)
 		irqf = pdata->pd_irqf;
diff --git a/drivers/input/touchscreen/zinitix.c b/drivers/input/touchscreen/zinitix.c
index 3b636beb583c..b8d901099378 100644
--- a/drivers/input/touchscreen/zinitix.c
+++ b/drivers/input/touchscreen/zinitix.c
@@ -513,10 +513,10 @@ static int zinitix_ts_probe(struct i2c_client *client)
 		return -EINVAL;
 	}
 
-	irq_set_status_flags(client->irq, IRQ_NOAUTOEN);
 	error = devm_request_threaded_irq(&client->dev, client->irq,
 					  NULL, zinitix_ts_irq_handler,
-					  IRQF_ONESHOT, client->name, bt541);
+					  IRQF_ONESHOT | IRQF_NO_AUTOEN,
+					  client->name, bt541);
 	if (error) {
 		dev_err(&client->dev, "Failed to request IRQ: %d\n", error);
 		return error;
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [tip: irq/core] genirq: Add IRQF_NO_AUTOEN for request_irq/nmi()
  2021-03-02 22:49 ` [PATCH v5 1/2] genirq: " Barry Song
@ 2021-03-04 10:53   ` tip-bot2 for Barry Song
  2021-03-04 10:57     ` Thomas Gleixner
  2021-03-06 11:54   ` tip-bot2 for Barry Song
  1 sibling, 1 reply; 11+ messages in thread
From: tip-bot2 for Barry Song @ 2021-03-04 10:53 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: Barry Song, Thomas Gleixner, dmitry.torokhov, x86, linux-kernel, maz

The following commit has been merged into the irq/core branch of tip:

Commit-ID:     e749df1bbd23f4472082210650514548d8a39e9b
Gitweb:        https://git.kernel.org/tip/e749df1bbd23f4472082210650514548d8a39e9b
Author:        Barry Song <song.bao.hua@hisilicon.com>
AuthorDate:    Wed, 03 Mar 2021 11:49:15 +13:00
Committer:     Thomas Gleixner <tglx@linutronix.de>
CommitterDate: Thu, 04 Mar 2021 11:47:52 +01:00

genirq: Add IRQF_NO_AUTOEN for request_irq/nmi()

Many drivers don't want interrupts enabled automatically via request_irq().
So they are handling this issue by either way of the below two:

(1)
  irq_set_status_flags(irq, IRQ_NOAUTOEN);
  request_irq(dev, irq...);

(2)
  request_irq(dev, irq...);
  disable_irq(irq);

The code in the second way is silly and unsafe. In the small time gap
between request_irq() and disable_irq(), interrupts can still come.

The code in the first way is safe though it's subobtimal.

Add a new IRQF_NO_AUTOEN flag which can be handed in by drivers to
request_irq() and request_nmi(). It prevents the automatic enabling of the
requested interrupt/nmi in the same safe way as #1 above. With that the
various usage sites of #1 and #2 above can be simplified and corrected.

Signed-off-by: Barry Song <song.bao.hua@hisilicon.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: dmitry.torokhov@gmail.com
Link: https://lore.kernel.org/r/20210302224916.13980-2-song.bao.hua@hisilicon.com

---
 include/linux/interrupt.h |  4 ++++
 kernel/irq/manage.c       | 11 +++++++++--
 2 files changed, 13 insertions(+), 2 deletions(-)

diff --git a/include/linux/interrupt.h b/include/linux/interrupt.h
index 967e257..76f1161 100644
--- a/include/linux/interrupt.h
+++ b/include/linux/interrupt.h
@@ -61,6 +61,9 @@
  *                interrupt handler after suspending interrupts. For system
  *                wakeup devices users need to implement wakeup detection in
  *                their interrupt handlers.
+ * IRQF_NO_AUTOEN - Don't enable IRQ or NMI automatically when users request it.
+ *                Users will enable it explicitly by enable_irq() or enable_nmi()
+ *                later.
  */
 #define IRQF_SHARED		0x00000080
 #define IRQF_PROBE_SHARED	0x00000100
@@ -74,6 +77,7 @@
 #define IRQF_NO_THREAD		0x00010000
 #define IRQF_EARLY_RESUME	0x00020000
 #define IRQF_COND_SUSPEND	0x00040000
+#define IRQF_NO_AUTOEN		0x00080000
 
 #define IRQF_TIMER		(__IRQF_TIMER | IRQF_NO_SUSPEND | IRQF_NO_THREAD)
 
diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c
index dec3f73..97c231a 100644
--- a/kernel/irq/manage.c
+++ b/kernel/irq/manage.c
@@ -1693,7 +1693,8 @@ __setup_irq(unsigned int irq, struct irq_desc *desc, struct irqaction *new)
 			irqd_set(&desc->irq_data, IRQD_NO_BALANCING);
 		}
 
-		if (irq_settings_can_autoenable(desc)) {
+		if (!(new->flags & IRQF_NO_AUTOEN) &&
+		    irq_settings_can_autoenable(desc)) {
 			irq_startup(desc, IRQ_RESEND, IRQ_START_COND);
 		} else {
 			/*
@@ -2086,10 +2087,15 @@ int request_threaded_irq(unsigned int irq, irq_handler_t handler,
 	 * which interrupt is which (messes up the interrupt freeing
 	 * logic etc).
 	 *
+	 * Also shared interrupts do not go well with disabling auto enable.
+	 * The sharing interrupt might request it while it's still disabled
+	 * and then wait for interrupts forever.
+	 *
 	 * Also IRQF_COND_SUSPEND only makes sense for shared interrupts and
 	 * it cannot be set along with IRQF_NO_SUSPEND.
 	 */
 	if (((irqflags & IRQF_SHARED) && !dev_id) ||
+	    ((irqflags & IRQF_SHARED) && (irqflags & IRQF_NO_AUTOEN)) ||
 	    (!(irqflags & IRQF_SHARED) && (irqflags & IRQF_COND_SUSPEND)) ||
 	    ((irqflags & IRQF_NO_SUSPEND) && (irqflags & IRQF_COND_SUSPEND)))
 		return -EINVAL;
@@ -2245,7 +2251,8 @@ int request_nmi(unsigned int irq, irq_handler_t handler,
 
 	desc = irq_to_desc(irq);
 
-	if (!desc || irq_settings_can_autoenable(desc) ||
+	if (!desc || (irq_settings_can_autoenable(desc) &&
+	    !(irqflags & IRQF_NO_AUTOEN)) ||
 	    !irq_settings_can_request(desc) ||
 	    WARN_ON(irq_settings_is_per_cpu_devid(desc)) ||
 	    !irq_supports_nmi(desc))

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* Re: [tip: irq/core] genirq: Add IRQF_NO_AUTOEN for request_irq/nmi()
  2021-03-04 10:53   ` [tip: irq/core] genirq: Add IRQF_NO_AUTOEN for request_irq/nmi() tip-bot2 for Barry Song
@ 2021-03-04 10:57     ` Thomas Gleixner
  2021-03-04 18:50       ` Thomas Gleixner
  0 siblings, 1 reply; 11+ messages in thread
From: Thomas Gleixner @ 2021-03-04 10:57 UTC (permalink / raw)
  To: tip-bot2 for Barry Song, linux-tip-commits
  Cc: Barry Song, dmitry.torokhov, x86, linux-kernel, maz

Dmitry,

On Thu, Mar 04 2021 at 10:53, tip-bot wrote:

> The following commit has been merged into the irq/core branch of tip:
>
> Commit-ID:     e749df1bbd23f4472082210650514548d8a39e9b
> Gitweb:        https://git.kernel.org/tip/e749df1bbd23f4472082210650514548d8a39e9b
> Author:        Barry Song <song.bao.hua@hisilicon.com>
> AuthorDate:    Wed, 03 Mar 2021 11:49:15 +13:00
> Committer:     Thomas Gleixner <tglx@linutronix.de>
> CommitterDate: Thu, 04 Mar 2021 11:47:52 +01:00
>
> genirq: Add IRQF_NO_AUTOEN for request_irq/nmi()

this commit is immutable and I tagged it so you can pull it into your
tree to add the input changes on top:

   git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git irq-no-autoen-2021-03-04

Thanks,

        tglx

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [tip: irq/core] genirq: Add IRQF_NO_AUTOEN for request_irq/nmi()
  2021-03-04 10:57     ` Thomas Gleixner
@ 2021-03-04 18:50       ` Thomas Gleixner
  2021-03-23 22:44         ` Dmitry Torokhov
  0 siblings, 1 reply; 11+ messages in thread
From: Thomas Gleixner @ 2021-03-04 18:50 UTC (permalink / raw)
  To: tip-bot2 for Barry Song, linux-tip-commits
  Cc: Barry Song, dmitry.torokhov, x86, linux-kernel, maz

Dmitry,

On Thu, Mar 04 2021 at 11:57, Thomas Gleixner wrote:
> On Thu, Mar 04 2021 at 10:53, tip-bot wrote:
>
>> The following commit has been merged into the irq/core branch of tip:
>>
>> Commit-ID:     e749df1bbd23f4472082210650514548d8a39e9b
>> Gitweb:        https://git.kernel.org/tip/e749df1bbd23f4472082210650514548d8a39e9b
>> Author:        Barry Song <song.bao.hua@hisilicon.com>
>> AuthorDate:    Wed, 03 Mar 2021 11:49:15 +13:00
>> Committer:     Thomas Gleixner <tglx@linutronix.de>
>> CommitterDate: Thu, 04 Mar 2021 11:47:52 +01:00
>>
>> genirq: Add IRQF_NO_AUTOEN for request_irq/nmi()
>
> this commit is immutable and I tagged it so you can pull it into your
> tree to add the input changes on top:
>
>    git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git irq-no-autoen-2021-03-04

Please hold on:

  https://lkml.kernel.org/r/CAHk-=wgZjJ89jeH72TC3i6N%2Bz9WEY=3ysp8zR9naRUcSqcAvTA@mail.gmail.com

I'll recreate a tag for you once rc2 is out.

Thanks,

        tglx

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [tip: irq/core] genirq: Add IRQF_NO_AUTOEN for request_irq/nmi()
  2021-03-02 22:49 ` [PATCH v5 1/2] genirq: " Barry Song
  2021-03-04 10:53   ` [tip: irq/core] genirq: Add IRQF_NO_AUTOEN for request_irq/nmi() tip-bot2 for Barry Song
@ 2021-03-06 11:54   ` tip-bot2 for Barry Song
  1 sibling, 0 replies; 11+ messages in thread
From: tip-bot2 for Barry Song @ 2021-03-06 11:54 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: Barry Song, Thomas Gleixner, Ingo Molnar, dmitry.torokhov, x86,
	linux-kernel, maz

The following commit has been merged into the irq/core branch of tip:

Commit-ID:     cbe16f35bee6880becca6f20d2ebf6b457148552
Gitweb:        https://git.kernel.org/tip/cbe16f35bee6880becca6f20d2ebf6b457148552
Author:        Barry Song <song.bao.hua@hisilicon.com>
AuthorDate:    Wed, 03 Mar 2021 11:49:15 +13:00
Committer:     Ingo Molnar <mingo@kernel.org>
CommitterDate: Sat, 06 Mar 2021 12:48:00 +01:00

genirq: Add IRQF_NO_AUTOEN for request_irq/nmi()

Many drivers don't want interrupts enabled automatically via request_irq().
So they are handling this issue by either way of the below two:

(1)
  irq_set_status_flags(irq, IRQ_NOAUTOEN);
  request_irq(dev, irq...);

(2)
  request_irq(dev, irq...);
  disable_irq(irq);

The code in the second way is silly and unsafe. In the small time gap
between request_irq() and disable_irq(), interrupts can still come.

The code in the first way is safe though it's subobtimal.

Add a new IRQF_NO_AUTOEN flag which can be handed in by drivers to
request_irq() and request_nmi(). It prevents the automatic enabling of the
requested interrupt/nmi in the same safe way as #1 above. With that the
various usage sites of #1 and #2 above can be simplified and corrected.

Signed-off-by: Barry Song <song.bao.hua@hisilicon.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Cc: dmitry.torokhov@gmail.com
Link: https://lore.kernel.org/r/20210302224916.13980-2-song.bao.hua@hisilicon.com
---
 include/linux/interrupt.h |  4 ++++
 kernel/irq/manage.c       | 11 +++++++++--
 2 files changed, 13 insertions(+), 2 deletions(-)

diff --git a/include/linux/interrupt.h b/include/linux/interrupt.h
index 967e257..76f1161 100644
--- a/include/linux/interrupt.h
+++ b/include/linux/interrupt.h
@@ -61,6 +61,9 @@
  *                interrupt handler after suspending interrupts. For system
  *                wakeup devices users need to implement wakeup detection in
  *                their interrupt handlers.
+ * IRQF_NO_AUTOEN - Don't enable IRQ or NMI automatically when users request it.
+ *                Users will enable it explicitly by enable_irq() or enable_nmi()
+ *                later.
  */
 #define IRQF_SHARED		0x00000080
 #define IRQF_PROBE_SHARED	0x00000100
@@ -74,6 +77,7 @@
 #define IRQF_NO_THREAD		0x00010000
 #define IRQF_EARLY_RESUME	0x00020000
 #define IRQF_COND_SUSPEND	0x00040000
+#define IRQF_NO_AUTOEN		0x00080000
 
 #define IRQF_TIMER		(__IRQF_TIMER | IRQF_NO_SUSPEND | IRQF_NO_THREAD)
 
diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c
index dec3f73..97c231a 100644
--- a/kernel/irq/manage.c
+++ b/kernel/irq/manage.c
@@ -1693,7 +1693,8 @@ __setup_irq(unsigned int irq, struct irq_desc *desc, struct irqaction *new)
 			irqd_set(&desc->irq_data, IRQD_NO_BALANCING);
 		}
 
-		if (irq_settings_can_autoenable(desc)) {
+		if (!(new->flags & IRQF_NO_AUTOEN) &&
+		    irq_settings_can_autoenable(desc)) {
 			irq_startup(desc, IRQ_RESEND, IRQ_START_COND);
 		} else {
 			/*
@@ -2086,10 +2087,15 @@ int request_threaded_irq(unsigned int irq, irq_handler_t handler,
 	 * which interrupt is which (messes up the interrupt freeing
 	 * logic etc).
 	 *
+	 * Also shared interrupts do not go well with disabling auto enable.
+	 * The sharing interrupt might request it while it's still disabled
+	 * and then wait for interrupts forever.
+	 *
 	 * Also IRQF_COND_SUSPEND only makes sense for shared interrupts and
 	 * it cannot be set along with IRQF_NO_SUSPEND.
 	 */
 	if (((irqflags & IRQF_SHARED) && !dev_id) ||
+	    ((irqflags & IRQF_SHARED) && (irqflags & IRQF_NO_AUTOEN)) ||
 	    (!(irqflags & IRQF_SHARED) && (irqflags & IRQF_COND_SUSPEND)) ||
 	    ((irqflags & IRQF_NO_SUSPEND) && (irqflags & IRQF_COND_SUSPEND)))
 		return -EINVAL;
@@ -2245,7 +2251,8 @@ int request_nmi(unsigned int irq, irq_handler_t handler,
 
 	desc = irq_to_desc(irq);
 
-	if (!desc || irq_settings_can_autoenable(desc) ||
+	if (!desc || (irq_settings_can_autoenable(desc) &&
+	    !(irqflags & IRQF_NO_AUTOEN)) ||
 	    !irq_settings_can_request(desc) ||
 	    WARN_ON(irq_settings_is_per_cpu_devid(desc)) ||
 	    !irq_supports_nmi(desc))

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* Re: [tip: irq/core] genirq: Add IRQF_NO_AUTOEN for request_irq/nmi()
  2021-03-04 18:50       ` Thomas Gleixner
@ 2021-03-23 22:44         ` Dmitry Torokhov
  2021-03-25  6:59           ` Thomas Gleixner
  0 siblings, 1 reply; 11+ messages in thread
From: Dmitry Torokhov @ 2021-03-23 22:44 UTC (permalink / raw)
  To: Thomas Gleixner
  Cc: tip-bot2 for Barry Song, linux-tip-commits, Barry Song, x86,
	linux-kernel, maz

Hi Thomas,

On Thu, Mar 04, 2021 at 07:50:31PM +0100, Thomas Gleixner wrote:
> Dmitry,
> 
> On Thu, Mar 04 2021 at 11:57, Thomas Gleixner wrote:
> > On Thu, Mar 04 2021 at 10:53, tip-bot wrote:
> >
> >> The following commit has been merged into the irq/core branch of tip:
> >>
> >> Commit-ID:     e749df1bbd23f4472082210650514548d8a39e9b
> >> Gitweb:        https://git.kernel.org/tip/e749df1bbd23f4472082210650514548d8a39e9b
> >> Author:        Barry Song <song.bao.hua@hisilicon.com>
> >> AuthorDate:    Wed, 03 Mar 2021 11:49:15 +13:00
> >> Committer:     Thomas Gleixner <tglx@linutronix.de>
> >> CommitterDate: Thu, 04 Mar 2021 11:47:52 +01:00
> >>
> >> genirq: Add IRQF_NO_AUTOEN for request_irq/nmi()
> >
> > this commit is immutable and I tagged it so you can pull it into your
> > tree to add the input changes on top:
> >
> >    git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git irq-no-autoen-2021-03-04
> 
> Please hold on:
> 
>   https://lkml.kernel.org/r/CAHk-=wgZjJ89jeH72TC3i6N%2Bz9WEY=3ysp8zR9naRUcSqcAvTA@mail.gmail.com
> 
> I'll recreate a tag for you once rc2 is out.

It looks like the change has been picked up as
cbe16f35bee6880becca6f20d2ebf6b457148552i on top of -rc2,
but I don't think there is tag for it?

Thanks!

-- 
Dmitry

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [tip: irq/core] genirq: Add IRQF_NO_AUTOEN for request_irq/nmi()
  2021-03-23 22:44         ` Dmitry Torokhov
@ 2021-03-25  6:59           ` Thomas Gleixner
  2021-03-25 22:32             ` Dmitry Torokhov
  0 siblings, 1 reply; 11+ messages in thread
From: Thomas Gleixner @ 2021-03-25  6:59 UTC (permalink / raw)
  To: Dmitry Torokhov
  Cc: tip-bot2 for Barry Song, linux-tip-commits, Barry Song, x86,
	linux-kernel, maz

Dmitry,

On Tue, Mar 23 2021 at 15:44, Dmitry Torokhov wrote:
> On Thu, Mar 04, 2021 at 07:50:31PM +0100, Thomas Gleixner wrote:
>> Please hold on:
>> 
>>   https://lkml.kernel.org/r/CAHk-=wgZjJ89jeH72TC3i6N%2Bz9WEY=3ysp8zR9naRUcSqcAvTA@mail.gmail.com
>> 
>> I'll recreate a tag for you once rc2 is out.
>
> It looks like the change has been picked up as
> cbe16f35bee6880becca6f20d2ebf6b457148552i on top of -rc2,
> but I don't think there is tag for it?

Sorry, forgot about it. Here you go:

      git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git irq-no-autoen-2021-03-25

Thanks,

        tglx

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH v5 2/2] Input: move to use request_irq by IRQF_NO_AUTOEN flag
  2021-03-02 22:49 ` [PATCH v5 2/2] Input: move to use request_irq by IRQF_NO_AUTOEN flag Barry Song
@ 2021-03-25 22:31   ` Dmitry Torokhov
  0 siblings, 0 replies; 11+ messages in thread
From: Dmitry Torokhov @ 2021-03-25 22:31 UTC (permalink / raw)
  To: Barry Song
  Cc: tglx, linux-input, linux-kernel, maz, gregkh, linuxarm, jonathan.cameron

On Wed, Mar 03, 2021 at 11:49:16AM +1300, Barry Song wrote:
> disable_irq() after request_irq() still has a time gap in which
> interrupts can come. request_irq() with IRQF_NO_AUTOEN flag will
> disable IRQ auto-enable because of requesting.
> 
> On the other hand, request_irq() after setting IRQ_NOAUTOEN as
> below
> irq_set_status_flags(irq, IRQ_NOAUTOEN);
> request_irq(dev, irq...);
> can also be replaced by request_irq() with IRQF_NO_AUTOEN flag.
> 
> Signed-off-by: Barry Song <song.bao.hua@hisilicon.com>

Applied, thank you.

-- 
Dmitry

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [tip: irq/core] genirq: Add IRQF_NO_AUTOEN for request_irq/nmi()
  2021-03-25  6:59           ` Thomas Gleixner
@ 2021-03-25 22:32             ` Dmitry Torokhov
  0 siblings, 0 replies; 11+ messages in thread
From: Dmitry Torokhov @ 2021-03-25 22:32 UTC (permalink / raw)
  To: Thomas Gleixner
  Cc: tip-bot2 for Barry Song, linux-tip-commits, Barry Song, x86,
	linux-kernel, maz

On Thu, Mar 25, 2021 at 07:59:44AM +0100, Thomas Gleixner wrote:
> Dmitry,
> 
> On Tue, Mar 23 2021 at 15:44, Dmitry Torokhov wrote:
> > On Thu, Mar 04, 2021 at 07:50:31PM +0100, Thomas Gleixner wrote:
> >> Please hold on:
> >> 
> >>   https://lkml.kernel.org/r/CAHk-=wgZjJ89jeH72TC3i6N%2Bz9WEY=3ysp8zR9naRUcSqcAvTA@mail.gmail.com
> >> 
> >> I'll recreate a tag for you once rc2 is out.
> >
> > It looks like the change has been picked up as
> > cbe16f35bee6880becca6f20d2ebf6b457148552i on top of -rc2,
> > but I don't think there is tag for it?
> 
> Sorry, forgot about it. Here you go:
> 
>       git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git irq-no-autoen-2021-03-25

Thank you!

-- 
Dmitry

^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2021-03-25 22:33 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-03-02 22:49 [PATCH v5 0/2] add IRQF_NO_AUTOEN for request_irq Barry Song
2021-03-02 22:49 ` [PATCH v5 1/2] genirq: " Barry Song
2021-03-04 10:53   ` [tip: irq/core] genirq: Add IRQF_NO_AUTOEN for request_irq/nmi() tip-bot2 for Barry Song
2021-03-04 10:57     ` Thomas Gleixner
2021-03-04 18:50       ` Thomas Gleixner
2021-03-23 22:44         ` Dmitry Torokhov
2021-03-25  6:59           ` Thomas Gleixner
2021-03-25 22:32             ` Dmitry Torokhov
2021-03-06 11:54   ` tip-bot2 for Barry Song
2021-03-02 22:49 ` [PATCH v5 2/2] Input: move to use request_irq by IRQF_NO_AUTOEN flag Barry Song
2021-03-25 22:31   ` Dmitry Torokhov

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.