* [PATCH] serial: max310x: improve interrupt handling @ 2025-09-03 9:23 Tapio Reijonen 2025-09-03 15:37 ` Hugo Villeneuve 2025-09-04 7:53 ` Jiri Slaby 0 siblings, 2 replies; 7+ messages in thread From: Tapio Reijonen @ 2025-09-03 9:23 UTC (permalink / raw) To: Greg Kroah-Hartman, Jiri Slaby, Alexander Shiyan, Hugo Villeneuve Cc: linux-kernel, linux-serial, Tapio Reijonen When there is a heavy load of receiving characters to all four UART's, the warning 'Hardware RX FIFO overrun' is sometimes detected. The current implementation always service first UART3 until no more interrupt and then service another UARTs. This commit improve interrupt service routine to handle all interrupt sources, e.g. UARTs when a global IRQ is detected. Signed-off-by: Tapio Reijonen <tapio.reijonen@vaisala.com> --- drivers/tty/serial/max310x.c | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/drivers/tty/serial/max310x.c b/drivers/tty/serial/max310x.c index ce260e9949c3c268e706b2615d6fc01adc21e49b..3234ed7c688ff423d25a007ed8b938b249ae0b82 100644 --- a/drivers/tty/serial/max310x.c +++ b/drivers/tty/serial/max310x.c @@ -824,15 +824,26 @@ static irqreturn_t max310x_ist(int irq, void *dev_id) if (s->devtype->nr > 1) { do { - unsigned int val = ~0; + unsigned int val; + unsigned int global_irq = ~0; + int port; WARN_ON_ONCE(regmap_read(s->regmap, - MAX310X_GLOBALIRQ_REG, &val)); - val = ((1 << s->devtype->nr) - 1) & ~val; + MAX310X_GLOBALIRQ_REG, &global_irq)); + + val = ((1 << s->devtype->nr) - 1) & ~global_irq; + if (!val) break; - if (max310x_port_irq(s, fls(val) - 1) == IRQ_HANDLED) - handled = true; + + do { + port = fls(val) - 1; + if (max310x_port_irq(s, port) == IRQ_HANDLED) + handled = true; + + global_irq |= 1 << port; + val = ((1 << s->devtype->nr) - 1) & ~global_irq; + } while (val); } while (1); } else { if (max310x_port_irq(s, 0) == IRQ_HANDLED) --- base-commit: c8bc81a52d5a2ac2e4b257ae123677cf94112755 change-id: 20250903-master-max310x-improve-interrupt-handling-aa22b7ba1c1d Best regards, -- Tapio Reijonen <tapio.reijonen@vaisala.com> ^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH] serial: max310x: improve interrupt handling 2025-09-03 9:23 [PATCH] serial: max310x: improve interrupt handling Tapio Reijonen @ 2025-09-03 15:37 ` Hugo Villeneuve 2025-09-04 7:23 ` Tapio Reijonen 2025-09-04 7:53 ` Jiri Slaby 1 sibling, 1 reply; 7+ messages in thread From: Hugo Villeneuve @ 2025-09-03 15:37 UTC (permalink / raw) To: Tapio Reijonen Cc: Greg Kroah-Hartman, Jiri Slaby, Alexander Shiyan, Hugo Villeneuve, linux-kernel, linux-serial Hi, On Wed, 03 Sep 2025 09:23:04 +0000 Tapio Reijonen <tapio.reijonen@vaisala.com> wrote: > When there is a heavy load of receiving characters to all > four UART's, the warning 'Hardware RX FIFO overrun' is > sometimes detected. > The current implementation always service first UART3 until > no more interrupt and then service another UARTs. To improve clarity and reduce confusion, maybe change to something like: ... always service first the highest UART until no more interrupt and then service another UART (ex: UART3 will be serviced for as long as there are interrupts for it, then UART2, etc). > > This commit improve interrupt service routine to handle all > interrupt sources, e.g. UARTs when a global IRQ is detected. The current code already handle all interrupt sources. What you maybe could be saying is that you handle all individual interrupt sources before reading the global IRQ register again? You could also add in your commit message that your modification has the nice side-effect of improving the efficiency of the driver by reducing the number of reads of the global IRQ register. > > Signed-off-by: Tapio Reijonen <tapio.reijonen@vaisala.com> > --- > drivers/tty/serial/max310x.c | 21 ++++++++++++++++----- > 1 file changed, 16 insertions(+), 5 deletions(-) > > diff --git a/drivers/tty/serial/max310x.c b/drivers/tty/serial/max310x.c > index ce260e9949c3c268e706b2615d6fc01adc21e49b..3234ed7c688ff423d25a007ed8b938b249ae0b82 100644 > --- a/drivers/tty/serial/max310x.c > +++ b/drivers/tty/serial/max310x.c > @@ -824,15 +824,26 @@ static irqreturn_t max310x_ist(int irq, void *dev_id) > > if (s->devtype->nr > 1) { > do { > - unsigned int val = ~0; > + unsigned int val; > + unsigned int global_irq = ~0; > + int port; > > WARN_ON_ONCE(regmap_read(s->regmap, > - MAX310X_GLOBALIRQ_REG, &val)); > - val = ((1 << s->devtype->nr) - 1) & ~val; > + MAX310X_GLOBALIRQ_REG, &global_irq)); You changed the indentation here... > + > + val = ((1 << s->devtype->nr) - 1) & ~global_irq; > + > if (!val) > break; > - if (max310x_port_irq(s, fls(val) - 1) == IRQ_HANDLED) > - handled = true; > + > + do { > + port = fls(val) - 1; > + if (max310x_port_irq(s, port) == IRQ_HANDLED) > + handled = true; > + > + global_irq |= 1 << port; > + val = ((1 << s->devtype->nr) - 1) & ~global_irq; > + } while (val); > } while (1); > } else { > if (max310x_port_irq(s, 0) == IRQ_HANDLED) Maybe you could simplify (and improve readability) with this instead: --- val = ((1 << s->devtype->nr) - 1) & ~val; if (!val) break; - if (max310x_port_irq(s, fls(val) - 1) == IRQ_HANDLED) - handled = true; + + do { + unsigned int channel; + + channel = fls(val) - 1; + + if (max310x_port_irq(s, channel) == IRQ_HANDLED) + handled = true; + + val &= ~(1 << channel); + } while (val); --- > > --- > base-commit: c8bc81a52d5a2ac2e4b257ae123677cf94112755 > change-id: 20250903-master-max310x-improve-interrupt-handling-aa22b7ba1c1d > > Best regards, > -- > Tapio Reijonen <tapio.reijonen@vaisala.com> > > > -- Hugo Villeneuve ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH] serial: max310x: improve interrupt handling 2025-09-03 15:37 ` Hugo Villeneuve @ 2025-09-04 7:23 ` Tapio Reijonen 0 siblings, 0 replies; 7+ messages in thread From: Tapio Reijonen @ 2025-09-04 7:23 UTC (permalink / raw) To: Hugo Villeneuve Cc: Greg Kroah-Hartman, Jiri Slaby, Alexander Shiyan, Hugo Villeneuve, linux-kernel, linux-serial Hi, On 9/3/25 18:37, Hugo Villeneuve wrote: > Hi, > > On Wed, 03 Sep 2025 09:23:04 +0000 > Tapio Reijonen <tapio.reijonen@vaisala.com> wrote: > >> When there is a heavy load of receiving characters to all >> four UART's, the warning 'Hardware RX FIFO overrun' is >> sometimes detected. >> The current implementation always service first UART3 until >> no more interrupt and then service another UARTs. > > To improve clarity and reduce confusion, maybe change to > something like: > > ... always service first the highest UART until > no more interrupt and then service another UART (ex: UART3 will be > serviced for as long as there are interrupts for it, then UART2, etc). > > >> >> This commit improve interrupt service routine to handle all >> interrupt sources, e.g. UARTs when a global IRQ is detected. > > The current code already handle all interrupt sources. What you > maybe could be saying is that you handle all individual interrupt > sources before reading the global IRQ register again? > > You could also add in your commit message that your modification has the > nice side-effect of improving the efficiency of the driver by reducing > the number of reads of the global IRQ register. > > Try to improve commit message in next patch version. >> >> Signed-off-by: Tapio Reijonen <tapio.reijonen@vaisala.com> >> --- >> drivers/tty/serial/max310x.c | 21 ++++++++++++++++----- >> 1 file changed, 16 insertions(+), 5 deletions(-) >> >> diff --git a/drivers/tty/serial/max310x.c b/drivers/tty/serial/max310x.c >> index ce260e9949c3c268e706b2615d6fc01adc21e49b..3234ed7c688ff423d25a007ed8b938b249ae0b82 100644 >> --- a/drivers/tty/serial/max310x.c >> +++ b/drivers/tty/serial/max310x.c >> @@ -824,15 +824,26 @@ static irqreturn_t max310x_ist(int irq, void *dev_id) >> >> if (s->devtype->nr > 1) { >> do { >> - unsigned int val = ~0; >> + unsigned int val; >> + unsigned int global_irq = ~0; >> + int port; >> >> WARN_ON_ONCE(regmap_read(s->regmap, >> - MAX310X_GLOBALIRQ_REG, &val)); >> - val = ((1 << s->devtype->nr) - 1) & ~val; >> + MAX310X_GLOBALIRQ_REG, &global_irq)); > > You changed the indentation here... > I'll fix the indentation, my fault. >> + >> + val = ((1 << s->devtype->nr) - 1) & ~global_irq; >> + >> if (!val) >> break; >> - if (max310x_port_irq(s, fls(val) - 1) == IRQ_HANDLED) >> - handled = true; >> + >> + do { >> + port = fls(val) - 1; >> + if (max310x_port_irq(s, port) == IRQ_HANDLED) >> + handled = true; >> + >> + global_irq |= 1 << port; >> + val = ((1 << s->devtype->nr) - 1) & ~global_irq; >> + } while (val); >> } while (1); >> } else { >> if (max310x_port_irq(s, 0) == IRQ_HANDLED) > > Maybe you could simplify (and improve readability) with this instead: > I am reviewing the proposal. > --- > val = ((1 << s->devtype->nr) - 1) & ~val; > if (!val) > break; > > - if (max310x_port_irq(s, fls(val) - 1) == IRQ_HANDLED) > - handled = true; > + > + do { > + unsigned int channel; > + > + channel = fls(val) - 1; > + > + if (max310x_port_irq(s, channel) == IRQ_HANDLED) > + handled = true; > + > + val &= ~(1 << channel); > + } while (val); > --- > >> >> --- >> base-commit: c8bc81a52d5a2ac2e4b257ae123677cf94112755 >> change-id: 20250903-master-max310x-improve-interrupt-handling-aa22b7ba1c1d >> >> Best regards, >> -- >> Tapio Reijonen <tapio.reijonen@vaisala.com> >> >> >> > > -- > Hugo Villeneuve -- Many thanks, Tapio Reijonen ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH] serial: max310x: improve interrupt handling 2025-09-03 9:23 [PATCH] serial: max310x: improve interrupt handling Tapio Reijonen 2025-09-03 15:37 ` Hugo Villeneuve @ 2025-09-04 7:53 ` Jiri Slaby 2025-09-04 11:50 ` Tapio Reijonen 1 sibling, 1 reply; 7+ messages in thread From: Jiri Slaby @ 2025-09-04 7:53 UTC (permalink / raw) To: Tapio Reijonen, Greg Kroah-Hartman, Alexander Shiyan, Hugo Villeneuve Cc: linux-kernel, linux-serial On 03. 09. 25, 11:23, Tapio Reijonen wrote: > When there is a heavy load of receiving characters to all > four UART's, the warning 'Hardware RX FIFO overrun' is > sometimes detected. > The current implementation always service first UART3 until > no more interrupt and then service another UARTs. > > This commit improve interrupt service routine to handle all > interrupt sources, e.g. UARTs when a global IRQ is detected. > > Signed-off-by: Tapio Reijonen <tapio.reijonen@vaisala.com> > --- > drivers/tty/serial/max310x.c | 21 ++++++++++++++++----- > 1 file changed, 16 insertions(+), 5 deletions(-) > > diff --git a/drivers/tty/serial/max310x.c b/drivers/tty/serial/max310x.c > index ce260e9949c3c268e706b2615d6fc01adc21e49b..3234ed7c688ff423d25a007ed8b938b249ae0b82 100644 > --- a/drivers/tty/serial/max310x.c > +++ b/drivers/tty/serial/max310x.c > @@ -824,15 +824,26 @@ static irqreturn_t max310x_ist(int irq, void *dev_id) > > if (s->devtype->nr > 1) { > do { > - unsigned int val = ~0; > + unsigned int val; > + unsigned int global_irq = ~0; > + int port; > > WARN_ON_ONCE(regmap_read(s->regmap, > - MAX310X_GLOBALIRQ_REG, &val)); > - val = ((1 << s->devtype->nr) - 1) & ~val; > + MAX310X_GLOBALIRQ_REG, &global_irq)); > + > + val = ((1 << s->devtype->nr) - 1) & ~global_irq; This is horrid. Use GENMASK() (or BIT() below) instead. Likely, you want a local var storing the mask (the first part before the &). > if (!val) > break; > - if (max310x_port_irq(s, fls(val) - 1) == IRQ_HANDLED) > - handled = true; > + > + do { > + port = fls(val) - 1; > + if (max310x_port_irq(s, port) == IRQ_HANDLED) > + handled = true; > + > + global_irq |= 1 << port; > + val = ((1 << s->devtype->nr) - 1) & ~global_irq; > + } while (val); Actually, does it have to be from the end? I am thinking of for_each_and_bit()... > } while (1); > } else { > if (max310x_port_irq(s, 0) == IRQ_HANDLED) thanks, -- js suse labs ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH] serial: max310x: improve interrupt handling 2025-09-04 7:53 ` Jiri Slaby @ 2025-09-04 11:50 ` Tapio Reijonen 2025-09-04 16:36 ` Hugo Villeneuve 0 siblings, 1 reply; 7+ messages in thread From: Tapio Reijonen @ 2025-09-04 11:50 UTC (permalink / raw) To: Jiri Slaby, Greg Kroah-Hartman, Alexander Shiyan, Hugo Villeneuve Cc: linux-kernel, linux-serial Hi, On 9/4/25 10:53, Jiri Slaby wrote: > On 03. 09. 25, 11:23, Tapio Reijonen wrote: >> When there is a heavy load of receiving characters to all >> four UART's, the warning 'Hardware RX FIFO overrun' is >> sometimes detected. >> The current implementation always service first UART3 until >> no more interrupt and then service another UARTs. >> >> This commit improve interrupt service routine to handle all >> interrupt sources, e.g. UARTs when a global IRQ is detected. >> >> Signed-off-by: Tapio Reijonen <tapio.reijonen@vaisala.com> >> --- >> drivers/tty/serial/max310x.c | 21 ++++++++++++++++----- >> 1 file changed, 16 insertions(+), 5 deletions(-) >> >> diff --git a/drivers/tty/serial/max310x.c b/drivers/tty/serial/max310x.c >> index >> ce260e9949c3c268e706b2615d6fc01adc21e49b..3234ed7c688ff423d25a007ed8b938b249ae0b82 100644 >> --- a/drivers/tty/serial/max310x.c >> +++ b/drivers/tty/serial/max310x.c >> @@ -824,15 +824,26 @@ static irqreturn_t max310x_ist(int irq, void >> *dev_id) >> if (s->devtype->nr > 1) { >> do { >> - unsigned int val = ~0; >> + unsigned int val; >> + unsigned int global_irq = ~0; >> + int port; >> WARN_ON_ONCE(regmap_read(s->regmap, >> - MAX310X_GLOBALIRQ_REG, &val)); >> - val = ((1 << s->devtype->nr) - 1) & ~val; >> + MAX310X_GLOBALIRQ_REG, &global_irq)); >> + >> + val = ((1 << s->devtype->nr) - 1) & ~global_irq; > > This is horrid. Use GENMASK() (or BIT() below) instead. Likely, you want > a local var storing the mask (the first part before the &). > val = GENMASK(s->devtype->nr - 1, 0) & ~global_irq;>> if (!val) >> break; >> - if (max310x_port_irq(s, fls(val) - 1) == IRQ_HANDLED) >> - handled = true; >> + >> + do { >> + port = fls(val) - 1; >> + if (max310x_port_irq(s, port) == IRQ_HANDLED) >> + handled = true; >> + >> + global_irq |= 1 << port; >> + val = ((1 << s->devtype->nr) - 1) & ~global_irq; >> + } while (val); > > Actually, does it have to be from the end? I am thinking of > for_each_and_bit()... > >> } while (1); >> } else { >> if (max310x_port_irq(s, 0) == IRQ_HANDLED) > > thanks, -- Many thanks, Tapio Reijonen ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH] serial: max310x: improve interrupt handling 2025-09-04 11:50 ` Tapio Reijonen @ 2025-09-04 16:36 ` Hugo Villeneuve 2025-09-05 5:11 ` Tapio Reijonen 0 siblings, 1 reply; 7+ messages in thread From: Hugo Villeneuve @ 2025-09-04 16:36 UTC (permalink / raw) To: Tapio Reijonen Cc: Jiri Slaby, Greg Kroah-Hartman, Alexander Shiyan, Hugo Villeneuve, linux-kernel, linux-serial Hi, On Thu, 4 Sep 2025 14:50:16 +0300 Tapio Reijonen <tapio.reijonen@vaisala.com> wrote: > Hi, > > On 9/4/25 10:53, Jiri Slaby wrote: > > On 03. 09. 25, 11:23, Tapio Reijonen wrote: > >> When there is a heavy load of receiving characters to all > >> four UART's, the warning 'Hardware RX FIFO overrun' is > >> sometimes detected. > >> The current implementation always service first UART3 until > >> no more interrupt and then service another UARTs. > >> > >> This commit improve interrupt service routine to handle all > >> interrupt sources, e.g. UARTs when a global IRQ is detected. > >> > >> Signed-off-by: Tapio Reijonen <tapio.reijonen@vaisala.com> > >> --- > >> drivers/tty/serial/max310x.c | 21 ++++++++++++++++----- > >> 1 file changed, 16 insertions(+), 5 deletions(-) > >> > >> diff --git a/drivers/tty/serial/max310x.c b/drivers/tty/serial/max310x.c > >> index > >> ce260e9949c3c268e706b2615d6fc01adc21e49b..3234ed7c688ff423d25a007ed8b938b249ae0b82 100644 > >> --- a/drivers/tty/serial/max310x.c > >> +++ b/drivers/tty/serial/max310x.c > >> @@ -824,15 +824,26 @@ static irqreturn_t max310x_ist(int irq, void > >> *dev_id) > >> if (s->devtype->nr > 1) { > >> do { > >> - unsigned int val = ~0; > >> + unsigned int val; > >> + unsigned int global_irq = ~0; > >> + int port; > >> WARN_ON_ONCE(regmap_read(s->regmap, > >> - MAX310X_GLOBALIRQ_REG, &val)); > >> - val = ((1 << s->devtype->nr) - 1) & ~val; > >> + MAX310X_GLOBALIRQ_REG, &global_irq)); > >> + > >> + val = ((1 << s->devtype->nr) - 1) & ~global_irq; > > > > This is horrid. Use GENMASK() (or BIT() below) instead. Likely, you want > > a local var storing the mask (the first part before the &). > > > val = GENMASK(s->devtype->nr - 1, 0) & ~global_irq;>> if > (!val) > >> break; > >> - if (max310x_port_irq(s, fls(val) - 1) == IRQ_HANDLED) > >> - handled = true; > >> + > >> + do { > >> + port = fls(val) - 1; > >> + if (max310x_port_irq(s, port) == IRQ_HANDLED) > >> + handled = true; > >> + > >> + global_irq |= 1 << port; > >> + val = ((1 << s->devtype->nr) - 1) & ~global_irq; > >> + } while (val); > > > > Actually, does it have to be from the end? I am thinking of > > for_each_and_bit()... > > > >> } while (1); > >> } else { > >> if (max310x_port_irq(s, 0) == IRQ_HANDLED) Combining what I suggested earlier, with Jiri's comments but using for_each_clear_bit() allow to get rid of the original horrid mask: --- if (s->devtype->nr > 1) { do { unsigned int val = ~0; + unsigned long channel; + unsigned long irq; + bool read_reg_done = true; WARN_ON_ONCE(regmap_read(s->regmap, MAX310X_GLOBALIRQ_REG, &val)); - val = ((1 << s->devtype->nr) - 1) & ~val; - if (!val) + irq = val; + + for_each_clear_bit(channel, &irq, s->devtype->nr) { + read_reg_done = false; + + if (max310x_port_irq(s, channel) == IRQ_HANDLED) + handled = true; + } + + if (read_reg_done) break; - if (max310x_port_irq(s, fls(val) - 1) == IRQ_HANDLED) - handled = true; } while (1); --- -- Hugo Villeneuve ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH] serial: max310x: improve interrupt handling 2025-09-04 16:36 ` Hugo Villeneuve @ 2025-09-05 5:11 ` Tapio Reijonen 0 siblings, 0 replies; 7+ messages in thread From: Tapio Reijonen @ 2025-09-05 5:11 UTC (permalink / raw) To: Hugo Villeneuve Cc: Jiri Slaby, Greg Kroah-Hartman, Alexander Shiyan, Hugo Villeneuve, linux-kernel, linux-serial Hi, On 9/4/25 19:36, Hugo Villeneuve wrote: > Hi, > > On Thu, 4 Sep 2025 14:50:16 +0300 > Tapio Reijonen <tapio.reijonen@vaisala.com> wrote: > >> Hi, >> >> On 9/4/25 10:53, Jiri Slaby wrote: >>> On 03. 09. 25, 11:23, Tapio Reijonen wrote: >>>> When there is a heavy load of receiving characters to all >>>> four UART's, the warning 'Hardware RX FIFO overrun' is >>>> sometimes detected. >>>> The current implementation always service first UART3 until >>>> no more interrupt and then service another UARTs. >>>> >>>> This commit improve interrupt service routine to handle all >>>> interrupt sources, e.g. UARTs when a global IRQ is detected. >>>> >>>> Signed-off-by: Tapio Reijonen <tapio.reijonen@vaisala.com> >>>> --- >>>> drivers/tty/serial/max310x.c | 21 ++++++++++++++++----- >>>> 1 file changed, 16 insertions(+), 5 deletions(-) >>>> >>>> diff --git a/drivers/tty/serial/max310x.c b/drivers/tty/serial/max310x.c >>>> index >>>> ce260e9949c3c268e706b2615d6fc01adc21e49b..3234ed7c688ff423d25a007ed8b938b249ae0b82 100644 >>>> --- a/drivers/tty/serial/max310x.c >>>> +++ b/drivers/tty/serial/max310x.c >>>> @@ -824,15 +824,26 @@ static irqreturn_t max310x_ist(int irq, void >>>> *dev_id) >>>> if (s->devtype->nr > 1) { >>>> do { >>>> - unsigned int val = ~0; >>>> + unsigned int val; >>>> + unsigned int global_irq = ~0; >>>> + int port; >>>> WARN_ON_ONCE(regmap_read(s->regmap, >>>> - MAX310X_GLOBALIRQ_REG, &val)); >>>> - val = ((1 << s->devtype->nr) - 1) & ~val; >>>> + MAX310X_GLOBALIRQ_REG, &global_irq)); >>>> + >>>> + val = ((1 << s->devtype->nr) - 1) & ~global_irq; >>> >>> This is horrid. Use GENMASK() (or BIT() below) instead. Likely, you want >>> a local var storing the mask (the first part before the &). >>> >> val = GENMASK(s->devtype->nr - 1, 0) & ~global_irq;>> if >> (!val) >>>> break; >>>> - if (max310x_port_irq(s, fls(val) - 1) == IRQ_HANDLED) >>>> - handled = true; >>>> + >>>> + do { >>>> + port = fls(val) - 1; >>>> + if (max310x_port_irq(s, port) == IRQ_HANDLED) >>>> + handled = true; >>>> + >>>> + global_irq |= 1 << port; >>>> + val = ((1 << s->devtype->nr) - 1) & ~global_irq; >>>> + } while (val); >>> >>> Actually, does it have to be from the end? I am thinking of >>> for_each_and_bit()... >>> >>>> } while (1); >>>> } else { >>>> if (max310x_port_irq(s, 0) == IRQ_HANDLED) > > Combining what I suggested earlier, with Jiri's comments but using > for_each_clear_bit() allow to get rid of the original horrid mask: > Thanks about suggested clear example. I'll test this in HW. > --- > if (s->devtype->nr > 1) { > do { > unsigned int val = ~0; > + unsigned long channel; > + unsigned long irq; > + bool read_reg_done = true; > > WARN_ON_ONCE(regmap_read(s->regmap, > MAX310X_GLOBALIRQ_REG, &val)); > - val = ((1 << s->devtype->nr) - 1) & ~val; > - if (!val) > + irq = val; > + > + for_each_clear_bit(channel, &irq, s->devtype->nr) { > + read_reg_done = false; > + > + if (max310x_port_irq(s, channel) == IRQ_HANDLED) > + handled = true; > + } > + > + if (read_reg_done) > break; > - if (max310x_port_irq(s, fls(val) - 1) == IRQ_HANDLED) > - handled = true; > } while (1); > --- > > -- Many thanks, Tapio Reijonen ^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2025-09-05 5:11 UTC | newest] Thread overview: 7+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2025-09-03 9:23 [PATCH] serial: max310x: improve interrupt handling Tapio Reijonen 2025-09-03 15:37 ` Hugo Villeneuve 2025-09-04 7:23 ` Tapio Reijonen 2025-09-04 7:53 ` Jiri Slaby 2025-09-04 11:50 ` Tapio Reijonen 2025-09-04 16:36 ` Hugo Villeneuve 2025-09-05 5:11 ` Tapio Reijonen
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox