From: Barry Song <hidden> Date: 2021-01-07 22:45:44
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.
Signed-off-by: Barry Song <redacted>
---
drivers/input/touchscreen/ar1021_i2c.c | 5 +----
1 file changed, 1 insertion(+), 4 deletions(-)
@@ -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,returnerror;}-/* 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,
From: Barry Song <hidden> Date: 2021-01-07 22:45:44
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 <redacted>
---
include/linux/interrupt.h | 3 +++
kernel/irq/manage.c | 8 ++++++++
kernel/irq/settings.h | 10 ++++++++++
3 files changed, 21 insertions(+)
@@ -2086,10 +2089,15 @@ int request_threaded_irq(unsigned int irq, irq_handler_t handler,*whichinterruptiswhich(messesuptheinterruptfreeing*logicetc).*+*Alsosharedinterruptsdonotgowellwithdisablingautoenable.+*Thesharinginterruptmightrequestitwhileit'sstilldisabled+*andthenwaitforinterruptsforever.+**AlsoIRQF_COND_SUSPENDonlymakessenseforsharedinterruptsand*itcannotbesetalongwithIRQF_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;
From: Barry Song <hidden> Date: 2021-01-07 22:45:44
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.
Signed-off-by: Barry Song <redacted>
---
drivers/input/touchscreen/melfas_mip4.c | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
From: Barry Song <hidden> Date: 2021-01-07 22:45:44
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.
Signed-off-by: Barry Song <redacted>
---
drivers/input/touchscreen/atmel_mxt_ts.c | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
From: Barry Song <hidden> Date: 2021-01-07 22:45:45
Right now, irq core supports requesting irq with IRQF_NO_AUTOEN, this means
the driver doesn't need to call irq_set_status_flags any more.
Signed-off-by: Barry Song <redacted>
---
drivers/input/touchscreen/stmfts.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
From: Barry Song <hidden> Date: 2021-01-07 22:45:45
Right now, irq core supports requesting irq with IRQF_NO_AUTOEN, this means
the driver doesn't need to call irq_set_status_flags any more.
Signed-off-by: Barry Song <redacted>
---
drivers/input/touchscreen/bu21029_ts.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
From: Barry Song <hidden> Date: 2021-01-07 22:46:24
Right now, irq core supports requesting irq with IRQF_NO_AUTOEN, this means
the driver doesn't need to call irq_set_status_flags any more.
Signed-off-by: Barry Song <redacted>
---
drivers/input/touchscreen/zinitix.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
From: Barry Song <hidden> Date: 2021-01-07 22:46:24
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.
Signed-off-by: Barry Song <redacted>
---
drivers/input/touchscreen/mms114.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
From: Barry Song <hidden> Date: 2021-01-07 22:46:24
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.
Signed-off-by: Barry Song <redacted>
---
drivers/input/touchscreen/cyttsp_core.c | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
From: Barry Song <hidden> Date: 2021-01-07 22:46:24
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.
Signed-off-by: Barry Song <redacted>
---
drivers/input/touchscreen/wm831x-ts.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
From: Barry Song <hidden> Date: 2021-01-07 22:46:24
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.
Signed-off-by: Barry Song <redacted>
---
drivers/input/keyboard/tca6416-keypad.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
From: Barry Song <hidden> Date: 2021-01-07 22:46:25
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.
Signed-off-by: Barry Song <redacted>
---
drivers/input/keyboard/tegra-kbc.c | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
On Wed, Jan 27, 2021 at 02:49:21PM +0100, gregkh@linuxfoundation.org wrote:
On Thu, Jan 21, 2021 at 09:38:28PM +0000, Song Bao Hua (Barry Song) wrote:
quoted
Hi Thomas, Greg, Dmitry, Marc,
Any further comment on this new API?
It's not my subsystem, I'll let the irq maintainers handle it :)
Not my subsystem either, but I would like to have this feature
available. I do not like calling irq_set_status_flags() before
request_irq() as at that time we are not ensured of irq ownership, and
using disable_irq() afterwards is indeed awkward.
Thanks.
--
Dmitry
From: Jonathan Cameron <hidden> Date: 2021-01-28 11:10:26
On Wed, 27 Jan 2021 11:45:45 -0800
"dmitry.torokhov@gmail.com" [off-list ref] wrote:
On Wed, Jan 27, 2021 at 02:49:21PM +0100, gregkh@linuxfoundation.org wrote:
quoted
On Thu, Jan 21, 2021 at 09:38:28PM +0000, Song Bao Hua (Barry Song) wrote:
quoted
Hi Thomas, Greg, Dmitry, Marc,
Any further comment on this new API?
It's not my subsystem, I'll let the irq maintainers handle it :)
Not my subsystem either, but I would like to have this feature
available. I do not like calling irq_set_status_flags() before
request_irq() as at that time we are not ensured of irq ownership, and
using disable_irq() afterwards is indeed awkward.
If we move this to request time flags, then setting the noautoen bit on
the irq descriptor is pretty pointless. See below.
I rather get rid of the irq_settings magic for NOAUTOEN completely.
Thanks,
tglx
---
@@ -2086,10 +2087,15 @@ int request_threaded_irq(unsigned int ir*whichinterruptiswhich(messesuptheinterruptfreeing*logicetc).*+*Alsosharedinterruptsdonotgowellwithdisablingautoenable.+*Thesharinginterruptmightrequestitwhileit'sstilldisabled+*andthenwaitforinterruptsforever.+**AlsoIRQF_COND_SUSPENDonlymakessenseforsharedinterruptsand*itcannotbesetalongwithIRQF_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;
From: Song Bao Hua (Barry Song) <hidden> Date: 2021-02-01 04:09:52
-----Original Message-----
From: Thomas Gleixner [mailto:tglx@linutronix.de]
Sent: Friday, January 29, 2021 8:55 AM
To: Song Bao Hua (Barry Song) <redacted>;
dmitry.torokhov@gmail.com; maz@kernel.org; gregkh@linuxfoundation.org;
linux-input@vger.kernel.org; linux-kernel@vger.kernel.org
Cc: linuxarm@openeuler.org; Song Bao Hua (Barry Song)
[off-list ref]
Subject: Re: [PATCH v3 01/12] genirq: add IRQF_NO_AUTOEN for request_irq
Barry,
On Fri, Jan 08 2021 at 11:39, Barry Song wrote:
@@ -1693,6 +1693,9 @@ __setup_irq(unsigned int irq, struct irq_desc *desc,
struct irqaction *new)
quoted
irqd_set(&desc->irq_data, IRQD_NO_BALANCING);
}
+ if (new->flags & IRQF_NO_AUTOEN)
+ irq_settings_set_noautoen(desc);
If we move this to request time flags, then setting the noautoen bit on
the irq descriptor is pretty pointless. See below.
I rather get rid of the irq_settings magic for NOAUTOEN completely.
Thanks for your comment, Thomas.
Got this issue fixed in v4:
https://lore.kernel.org/lkml/20210128223538.20272-1-song.bao.hua@hisilicon.com/
btw, for those drivers which are using the first pattern:
irq_set_status_flags(irq, IRQ_NOAUTOEN);
request_irq(dev, irq...);
Simply running "git grep IRQ_NOAUTOEN" will help figure where to fix.
For those drivers which are using the second pattern:
request_irq(dev, irq...);
disable_irq(irq);
I wrote a script as below:
#!/bin/bash
if [ $# != 1 -o ! -d $1 ] ; then
echo "USAGE: $0 dir"
exit 1;
fi
find $1 -iname "*.c" | while read i
do
if [ -d "$i" ]; then
break
fi
irq=`grep -n -A 10 -E "request_irq|request_threaded_irq|request_any_context_irq" $i | grep disable_irq`
if [ "$irq" != "" ]; then
echo "$i":"$irq"
fi
done
The script says there are more than 70 cases in 5.11-rc6.
We are going to fix all of them after this one settles down.
Thanks
Barry
@@ -2086,10 +2087,15 @@ int request_threaded_irq(unsigned int ir*whichinterruptiswhich(messesuptheinterruptfreeing*logicetc).*+*Alsosharedinterruptsdonotgowellwithdisablingautoenable.+*Thesharinginterruptmightrequestitwhileit'sstilldisabled+*andthenwaitforinterruptsforever.+**AlsoIRQF_COND_SUSPENDonlymakessenseforsharedinterruptsand*itcannotbesetalongwithIRQF_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;