On Wed, Aug 28, 2024 at 01:20:58PM +0200, Parth Pancholi wrote: > From: Emanuele Ghidoli <emanuele.ghidoli@xxxxxxxxxxx> > > TCPCI USB PHY - PTN5110 could be used with SOCs that only support > the edge-triggered GPIO interrupts such as TI's K3 device AM69. > Move the interrupt configuration to the firmware which would > allow to accommodate edge triggered interrupts for such SOCs. > In order to support the edge interrupts, register irq line in advance > and keep track of occurrence during port registering. > > When the edge interrupts are used, it is observed that some of the > interrupts are missed when tcpci_irq() is serving the current > interrupt. Therefore, check the status register at the end of > tcpci_irq() and re-run the function if the status is not clear > i.e. pending interrupt. > > Signed-off-by: Emanuele Ghidoli <emanuele.ghidoli@xxxxxxxxxxx> > Signed-off-by: Parth Pancholi <parth.pancholi@xxxxxxxxxxx> > --- > drivers/usb/typec/tcpm/tcpci.c | 32 +++++++++++++++++++++++--------- > 1 file changed, 23 insertions(+), 9 deletions(-) > > diff --git a/drivers/usb/typec/tcpm/tcpci.c b/drivers/usb/typec/tcpm/tcpci.c > index a2651a2a7f2e..4537c1d97e8f 100644 > --- a/drivers/usb/typec/tcpm/tcpci.c > +++ b/drivers/usb/typec/tcpm/tcpci.c ... > @@ -915,18 +923,24 @@ static int tcpci_probe(struct i2c_client *client) > > chip->data.set_orientation = err; > > - chip->tcpci = tcpci_register_port(&client->dev, &chip->data); > - if (IS_ERR(chip->tcpci)) > - return PTR_ERR(chip->tcpci); > - > err = devm_request_threaded_irq(&client->dev, client->irq, NULL, > _tcpci_irq, > - IRQF_SHARED | IRQF_ONESHOT | IRQF_TRIGGER_LOW, > + IRQF_SHARED | IRQF_ONESHOT, > dev_name(&client->dev), chip); > - if (err < 0) { > - tcpci_unregister_port(chip->tcpci); > + if (err < 0) > return err; > - } > + > + /* > + * Disable irq while registering port. If irq is configured as an edge > + * irq this allow to keep track and process the irq as soon as it is enabled. > + */ > + disable_irq(client->irq); > + > + chip->tcpci = tcpci_register_port(&client->dev, &chip->data); > + if (IS_ERR(chip->tcpci)) > + return PTR_ERR(chip->tcpci); > + > + enable_irq(client->irq); If I undestand this correctly, if tcpci_register_port() fails the irq stays disabled. disable_irq(client->irq); chip->tcpci = tcpci_register_port(&client->dev, &chip->data); enable_irq(client->irq); return PTR_ERR_OR_ZERO(chip->tcpci); maybe? Francesco