LKML Archive on lore.kernel.org
help / color / mirror / Atom feed
* [PATCH v1] mfd: tps6586x: Move interrupt handling into workqueue
@ 2018-05-13 21:18 Dmitry Osipenko
  2018-05-14 11:51 ` Thierry Reding
  0 siblings, 1 reply; 5+ messages in thread
From: Dmitry Osipenko @ 2018-05-13 21:18 UTC (permalink / raw)
  To: Lee Jones, Thierry Reding, Jonathan Hunter
  Cc: linux-tegra, linux-i2c, linux-kernel

Reading of status register within the interrupt handler fails with -EAGAIN
if I2C is busy with handling some other request at the same time. Move the
actual interrupt handling into a workqueue to avoid the unfortunate I2C
failure and to avoid hanging CPU in interrupt up to 1 second (transfer
timeout in the Tegra I2C driver).

Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
 drivers/mfd/tps6586x.c | 40 +++++++++++++++++++++++++++++-----------
 1 file changed, 29 insertions(+), 11 deletions(-)

diff --git a/drivers/mfd/tps6586x.c b/drivers/mfd/tps6586x.c
index b89379782741..9896e080b274 100644
--- a/drivers/mfd/tps6586x.c
+++ b/drivers/mfd/tps6586x.c
@@ -133,6 +133,7 @@ struct tps6586x {
 	u32			irq_en;
 	u8			mask_reg[5];
 	struct irq_domain	*irq_domain;
+	struct work_struct	isr_work;
 };
 
 static inline struct tps6586x *dev_to_tps6586x(struct device *dev)
@@ -309,18 +310,19 @@ static const struct irq_domain_ops tps6586x_domain_ops = {
 	.xlate  = irq_domain_xlate_twocell,
 };
 
-static irqreturn_t tps6586x_irq(int irq, void *data)
+static void tps6586x_isr_work(struct work_struct *work)
 {
-	struct tps6586x *tps6586x = data;
+	struct tps6586x *tps6586x = container_of(work, struct tps6586x,
+						 isr_work);
 	u32 acks;
-	int ret = 0;
+	int err;
 
-	ret = tps6586x_reads(tps6586x->dev, TPS6586X_INT_ACK1,
+	err = tps6586x_reads(tps6586x->dev, TPS6586X_INT_ACK1,
 			     sizeof(acks), (uint8_t *)&acks);
-
-	if (ret < 0) {
-		dev_err(tps6586x->dev, "failed to read interrupt status\n");
-		return IRQ_NONE;
+	if (err < 0) {
+		dev_err(tps6586x->dev,
+			"failed to read interrupt status %d\n", err);
+		return;
 	}
 
 	acks = le32_to_cpu(acks);
@@ -335,6 +337,16 @@ static irqreturn_t tps6586x_irq(int irq, void *data)
 		acks &= ~(1 << i);
 	}
 
+	enable_irq(tps6586x->irq);
+}
+
+static irqreturn_t tps6586x_irq(int irq, void *data)
+{
+	struct tps6586x *tps6586x = data;
+
+	disable_irq_nosync(irq);
+	schedule_work(&tps6586x->isr_work);
+
 	return IRQ_HANDLED;
 }
 
@@ -542,8 +554,9 @@ static int tps6586x_i2c_probe(struct i2c_client *client,
 		return ret;
 	}
 
-
 	if (client->irq) {
+		INIT_WORK(&tps6586x->isr_work, tps6586x_isr_work);
+
 		ret = tps6586x_irq_init(tps6586x, client->irq,
 					pdata->irq_base);
 		if (ret) {
@@ -585,10 +598,15 @@ static int tps6586x_i2c_remove(struct i2c_client *client)
 {
 	struct tps6586x *tps6586x = i2c_get_clientdata(client);
 
+	if (client->irq) {
+		disable_irq(client->irq);
+		flush_work(&tps6586x->isr_work);
+		free_irq(client->irq, tps6586x);
+	}
+
 	tps6586x_remove_subdevs(tps6586x);
 	mfd_remove_devices(tps6586x->dev);
-	if (client->irq)
-		free_irq(client->irq, tps6586x);
+
 	return 0;
 }
 
-- 
2.17.0

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

* Re: [PATCH v1] mfd: tps6586x: Move interrupt handling into workqueue
  2018-05-13 21:18 [PATCH v1] mfd: tps6586x: Move interrupt handling into workqueue Dmitry Osipenko
@ 2018-05-14 11:51 ` Thierry Reding
  2018-05-14 12:01   ` Dmitry Osipenko
  0 siblings, 1 reply; 5+ messages in thread
From: Thierry Reding @ 2018-05-14 11:51 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Lee Jones, Jonathan Hunter, linux-tegra, linux-i2c, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 675 bytes --]

On Mon, May 14, 2018 at 12:18:42AM +0300, Dmitry Osipenko wrote:
> Reading of status register within the interrupt handler fails with -EAGAIN
> if I2C is busy with handling some other request at the same time. Move the
> actual interrupt handling into a workqueue to avoid the unfortunate I2C
> failure and to avoid hanging CPU in interrupt up to 1 second (transfer
> timeout in the Tegra I2C driver).
> 
> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> ---
>  drivers/mfd/tps6586x.c | 40 +++++++++++++++++++++++++++++-----------
>  1 file changed, 29 insertions(+), 11 deletions(-)

Could this not be achieved with a threaded interrupt handler?

Thierry

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

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

* Re: [PATCH v1] mfd: tps6586x: Move interrupt handling into workqueue
  2018-05-14 11:51 ` Thierry Reding
@ 2018-05-14 12:01   ` Dmitry Osipenko
  2018-05-14 12:20     ` Dmitry Osipenko
  0 siblings, 1 reply; 5+ messages in thread
From: Dmitry Osipenko @ 2018-05-14 12:01 UTC (permalink / raw)
  To: Thierry Reding
  Cc: Lee Jones, Jonathan Hunter, linux-tegra, linux-i2c, linux-kernel

On 14.05.2018 14:51, Thierry Reding wrote:
> On Mon, May 14, 2018 at 12:18:42AM +0300, Dmitry Osipenko wrote:
>> Reading of status register within the interrupt handler fails with -EAGAIN
>> if I2C is busy with handling some other request at the same time. Move the
>> actual interrupt handling into a workqueue to avoid the unfortunate I2C
>> failure and to avoid hanging CPU in interrupt up to 1 second (transfer
>> timeout in the Tegra I2C driver).
>>
>> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
>> ---
>>  drivers/mfd/tps6586x.c | 40 +++++++++++++++++++++++++++++-----------
>>  1 file changed, 29 insertions(+), 11 deletions(-)
> 
> Could this not be achieved with a threaded interrupt handler?
> 
> Thierry
> 

Seems yes. I completely forgot about the threaded interrupt handlers existence.
Thank you very much for the suggestion, I'll try with the threaded IRQ and send
v2 if it will be fine.

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

* Re: [PATCH v1] mfd: tps6586x: Move interrupt handling into workqueue
  2018-05-14 12:01   ` Dmitry Osipenko
@ 2018-05-14 12:20     ` Dmitry Osipenko
  2018-05-14 12:39       ` Thierry Reding
  0 siblings, 1 reply; 5+ messages in thread
From: Dmitry Osipenko @ 2018-05-14 12:20 UTC (permalink / raw)
  To: Thierry Reding
  Cc: Lee Jones, Jonathan Hunter, linux-tegra, linux-i2c, linux-kernel

On 14.05.2018 15:01, Dmitry Osipenko wrote:
> On 14.05.2018 14:51, Thierry Reding wrote:
>> On Mon, May 14, 2018 at 12:18:42AM +0300, Dmitry Osipenko wrote:
>>> Reading of status register within the interrupt handler fails with -EAGAIN
>>> if I2C is busy with handling some other request at the same time. Move the
>>> actual interrupt handling into a workqueue to avoid the unfortunate I2C
>>> failure and to avoid hanging CPU in interrupt up to 1 second (transfer
>>> timeout in the Tegra I2C driver).
>>>
>>> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
>>> ---
>>>  drivers/mfd/tps6586x.c | 40 +++++++++++++++++++++++++++++-----------
>>>  1 file changed, 29 insertions(+), 11 deletions(-)
>>
>> Could this not be achieved with a threaded interrupt handler?
>>
>> Thierry
>>
> 
> Seems yes. I completely forgot about the threaded interrupt handlers existence.
> Thank you very much for the suggestion, I'll try with the threaded IRQ and send
> v2 if it will be fine.
> 

Oh wait! TPS6586x driver already uses threaded interrupt handler, so everything
should be fine in regards to the interrupt handling and this patch is obsolete.
Thank you again for the good suggestion, then it's only the Tegra's I2C driver
that causes trouble for the TPS6586x right now.

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

* Re: [PATCH v1] mfd: tps6586x: Move interrupt handling into workqueue
  2018-05-14 12:20     ` Dmitry Osipenko
@ 2018-05-14 12:39       ` Thierry Reding
  0 siblings, 0 replies; 5+ messages in thread
From: Thierry Reding @ 2018-05-14 12:39 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Lee Jones, Jonathan Hunter, linux-tegra, linux-i2c, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 1525 bytes --]

On Mon, May 14, 2018 at 03:20:55PM +0300, Dmitry Osipenko wrote:
> On 14.05.2018 15:01, Dmitry Osipenko wrote:
> > On 14.05.2018 14:51, Thierry Reding wrote:
> >> On Mon, May 14, 2018 at 12:18:42AM +0300, Dmitry Osipenko wrote:
> >>> Reading of status register within the interrupt handler fails with -EAGAIN
> >>> if I2C is busy with handling some other request at the same time. Move the
> >>> actual interrupt handling into a workqueue to avoid the unfortunate I2C
> >>> failure and to avoid hanging CPU in interrupt up to 1 second (transfer
> >>> timeout in the Tegra I2C driver).
> >>>
> >>> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> >>> ---
> >>>  drivers/mfd/tps6586x.c | 40 +++++++++++++++++++++++++++++-----------
> >>>  1 file changed, 29 insertions(+), 11 deletions(-)
> >>
> >> Could this not be achieved with a threaded interrupt handler?
> >>
> >> Thierry
> >>
> > 
> > Seems yes. I completely forgot about the threaded interrupt handlers existence.
> > Thank you very much for the suggestion, I'll try with the threaded IRQ and send
> > v2 if it will be fine.
> > 
> 
> Oh wait! TPS6586x driver already uses threaded interrupt handler, so everything
> should be fine in regards to the interrupt handling and this patch is obsolete.
> Thank you again for the good suggestion, then it's only the Tegra's I2C driver
> that causes trouble for the TPS6586x right now.

Heh... indeed. Sounds like the discussion that Wolfram pointed out is
the right way forward.

Thierry

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

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

end of thread, other threads:[~2018-05-14 12:39 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-05-13 21:18 [PATCH v1] mfd: tps6586x: Move interrupt handling into workqueue Dmitry Osipenko
2018-05-14 11:51 ` Thierry Reding
2018-05-14 12:01   ` Dmitry Osipenko
2018-05-14 12:20     ` Dmitry Osipenko
2018-05-14 12:39       ` Thierry Reding

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).