linux-input.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v2] genirq: add IRQF_NO_AUTOEN for request_irq
@ 2021-01-05  2:14 Barry Song
  2021-01-07 18:58 ` Greg KH
  0 siblings, 1 reply; 3+ messages in thread
From: Barry Song @ 2021-01-05  2:14 UTC (permalink / raw)
  To: tglx, maz, gregkh, linux-input, linux-kernel
  Cc: linuxarm, Barry Song, Dmitry Torokhov

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().
Hundreds of drivers with this problem will be handled afterwards.

Cc: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Signed-off-by: Barry Song <song.bao.hua@hisilicon.com>
---
 -v2:
 refuse the cases IRQF_NO_AUTOEN + IRQF_DISABLED are both set with
 respect to Dmitry's feedback in v1

 include/linux/interrupt.h |  3 +++
 kernel/irq/manage.c       |  8 ++++++++
 kernel/irq/settings.h     | 10 ++++++++++
 3 files changed, 21 insertions(+)

diff --git a/include/linux/interrupt.h b/include/linux/interrupt.h
index bb8ff9083e7d..0f22d277078c 100644
--- a/include/linux/interrupt.h
+++ b/include/linux/interrupt.h
@@ -61,6 +61,8 @@
  *                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 automatically when users request it. Users
+ *                will enable it explicitly by enable_irq() later.
  */
 #define IRQF_SHARED		0x00000080
 #define IRQF_PROBE_SHARED	0x00000100
@@ -74,6 +76,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 ab8567f32501..2b28314e2572 100644
--- a/kernel/irq/manage.c
+++ b/kernel/irq/manage.c
@@ -1693,6 +1693,9 @@ __setup_irq(unsigned int irq, struct irq_desc *desc, struct irqaction *new)
 			irqd_set(&desc->irq_data, IRQD_NO_BALANCING);
 		}
 
+		if (new->flags & IRQF_NO_AUTOEN)
+			irq_settings_set_noautoen(desc);
+
 		if (irq_settings_can_autoenable(desc)) {
 			irq_startup(desc, IRQ_RESEND, IRQ_START_COND);
 		} else {
@@ -2086,10 +2089,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;
diff --git a/kernel/irq/settings.h b/kernel/irq/settings.h
index 403378b9947b..a28958a9c548 100644
--- a/kernel/irq/settings.h
+++ b/kernel/irq/settings.h
@@ -145,6 +145,16 @@ static inline bool irq_settings_can_move_pcntxt(struct irq_desc *desc)
 	return desc->status_use_accessors & _IRQ_MOVE_PCNTXT;
 }
 
+static inline void irq_settings_clr_noautoen(struct irq_desc *desc)
+{
+	desc->status_use_accessors &= ~_IRQ_NOAUTOEN;
+}
+
+static inline void irq_settings_set_noautoen(struct irq_desc *desc)
+{
+	desc->status_use_accessors |= _IRQ_NOAUTOEN;
+}
+
 static inline bool irq_settings_can_autoenable(struct irq_desc *desc)
 {
 	return !(desc->status_use_accessors & _IRQ_NOAUTOEN);
-- 
2.25.1


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

* Re: [PATCH v2] genirq: add IRQF_NO_AUTOEN for request_irq
  2021-01-05  2:14 [PATCH v2] genirq: add IRQF_NO_AUTOEN for request_irq Barry Song
@ 2021-01-07 18:58 ` Greg KH
  2021-01-07 20:40   ` Song Bao Hua (Barry Song)
  0 siblings, 1 reply; 3+ messages in thread
From: Greg KH @ 2021-01-07 18:58 UTC (permalink / raw)
  To: Barry Song
  Cc: tglx, maz, linux-input, linux-kernel, linuxarm, Dmitry Torokhov

On Tue, Jan 05, 2021 at 03:14:11PM +1300, Barry Song wrote:
> 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().
> Hundreds of drivers with this problem will be handled afterwards.
> 
> Cc: Dmitry Torokhov <dmitry.torokhov@gmail.com>
> Signed-off-by: Barry Song <song.bao.hua@hisilicon.com>

Can you also convert some in-kernel drivers to this new api so that we
can see how this works?

thanks,

greg k-h

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

* RE: [PATCH v2] genirq: add IRQF_NO_AUTOEN for request_irq
  2021-01-07 18:58 ` Greg KH
@ 2021-01-07 20:40   ` Song Bao Hua (Barry Song)
  0 siblings, 0 replies; 3+ messages in thread
From: Song Bao Hua (Barry Song) @ 2021-01-07 20:40 UTC (permalink / raw)
  To: Greg KH; +Cc: tglx, maz, linux-input, linux-kernel, linuxarm, Dmitry Torokhov



> -----Original Message-----
> From: Greg KH [mailto:gregkh@linuxfoundation.org]
> Sent: Friday, January 8, 2021 7:58 AM
> To: Song Bao Hua (Barry Song) <song.bao.hua@hisilicon.com>
> Cc: tglx@linutronix.de; maz@kernel.org; linux-input@vger.kernel.org;
> linux-kernel@vger.kernel.org; linuxarm@openeuler.org; Dmitry Torokhov
> <dmitry.torokhov@gmail.com>
> Subject: Re: [PATCH v2] genirq: add IRQF_NO_AUTOEN for request_irq
> 
> On Tue, Jan 05, 2021 at 03:14:11PM +1300, Barry Song wrote:
> > 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().
> > Hundreds of drivers with this problem will be handled afterwards.
> >
> > Cc: Dmitry Torokhov <dmitry.torokhov@gmail.com>
> > Signed-off-by: Barry Song <song.bao.hua@hisilicon.com>
> 
> Can you also convert some in-kernel drivers to this new api so that we
> can see how this works?

Sure. As the discussion got started from input, so I'll take some
input drivers as examples before moving to other folders.

> 
> thanks,
> 
> greg k-h

Thanks
Barry


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

end of thread, other threads:[~2021-01-07 20:41 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-01-05  2:14 [PATCH v2] genirq: add IRQF_NO_AUTOEN for request_irq Barry Song
2021-01-07 18:58 ` Greg KH
2021-01-07 20:40   ` Song Bao Hua (Barry Song)

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).