Skip to content

Commit 77e8510

Browse files
eghidoligregkh
authored andcommitted
usb: typec: tcpci: support edge irq
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 <[email protected]> Signed-off-by: Parth Pancholi <[email protected]> Reviewed-by: Heikki Krogerus <[email protected]> Reviewed-by: Francesco Dolcini <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent 7793472 commit 77e8510

File tree

1 file changed

+20
-10
lines changed

1 file changed

+20
-10
lines changed

drivers/usb/typec/tcpm/tcpci.c

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -707,10 +707,13 @@ irqreturn_t tcpci_irq(struct tcpci *tcpci)
707707
{
708708
u16 status;
709709
int ret;
710+
int irq_ret;
710711
unsigned int raw;
711712

712713
tcpci_read16(tcpci, TCPC_ALERT, &status);
714+
irq_ret = status & tcpci->alert_mask;
713715

716+
process_status:
714717
/*
715718
* Clear alert status for everything except RX_STATUS, which shouldn't
716719
* be cleared until we have successfully retrieved message.
@@ -783,7 +786,12 @@ irqreturn_t tcpci_irq(struct tcpci *tcpci)
783786
else if (status & TCPC_ALERT_TX_FAILED)
784787
tcpm_pd_transmit_complete(tcpci->port, TCPC_TX_FAILED);
785788

786-
return IRQ_RETVAL(status & tcpci->alert_mask);
789+
tcpci_read16(tcpci, TCPC_ALERT, &status);
790+
791+
if (status & tcpci->alert_mask)
792+
goto process_status;
793+
794+
return IRQ_RETVAL(irq_ret);
787795
}
788796
EXPORT_SYMBOL_GPL(tcpci_irq);
789797

@@ -915,20 +923,22 @@ static int tcpci_probe(struct i2c_client *client)
915923

916924
chip->data.set_orientation = err;
917925

918-
chip->tcpci = tcpci_register_port(&client->dev, &chip->data);
919-
if (IS_ERR(chip->tcpci))
920-
return PTR_ERR(chip->tcpci);
921-
922926
err = devm_request_threaded_irq(&client->dev, client->irq, NULL,
923927
_tcpci_irq,
924-
IRQF_SHARED | IRQF_ONESHOT | IRQF_TRIGGER_LOW,
928+
IRQF_SHARED | IRQF_ONESHOT,
925929
dev_name(&client->dev), chip);
926-
if (err < 0) {
927-
tcpci_unregister_port(chip->tcpci);
930+
if (err < 0)
928931
return err;
929-
}
930932

931-
return 0;
933+
/*
934+
* Disable irq while registering port. If irq is configured as an edge
935+
* irq this allow to keep track and process the irq as soon as it is enabled.
936+
*/
937+
disable_irq(client->irq);
938+
chip->tcpci = tcpci_register_port(&client->dev, &chip->data);
939+
enable_irq(client->irq);
940+
941+
return PTR_ERR_OR_ZERO(chip->tcpci);
932942
}
933943

934944
static void tcpci_remove(struct i2c_client *client)

0 commit comments

Comments
 (0)