From a6a4762e0c466e4b5f31387ecd78c0d96cb1b1fb Mon Sep 17 00:00:00 2001 From: William Wu Date: Wed, 13 Mar 2024 10:07:43 +0800 Subject: [PATCH] usb: typec: tcpci_husb311: Refactor irq wakeup Currently, the husb311 driver enable irq wakeup by default, it can wakeup system if the vbus or the CC state changes. However, if the Type-C port data role is DFP and the vbus is power on, after enter deep sleep, the vbus maybe power off for low power management, this cause system resume immediately by husb311 irq. Actually, the husb311 vbus irq wakeup is no need if the vbus state changes for DFP mode. This patch only enable irq wakeup if the vbus is power off, it can support husb311 irq wakeup system if the Type-C connect with Type-C charger or Type-C DFP. And disable husb311 irq if the vbus is power on, it can avoid the tcpm_state_machine_work run before the husb311_pm_resume during system resume. Signed-off-by: William Wu Change-Id: I62d35b10b6b2375125b32101426ea141f709ed91 --- drivers/usb/typec/tcpm/tcpci_husb311.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/drivers/usb/typec/tcpm/tcpci_husb311.c b/drivers/usb/typec/tcpm/tcpci_husb311.c index 7b44a2367da6..185eee7f9729 100644 --- a/drivers/usb/typec/tcpm/tcpci_husb311.c +++ b/drivers/usb/typec/tcpm/tcpci_husb311.c @@ -199,7 +199,7 @@ static int husb311_probe(struct i2c_client *client, return ret; } - enable_irq_wake(client->irq); + device_init_wakeup(chip->dev, true); return 0; } @@ -208,12 +208,14 @@ static void husb311_remove(struct i2c_client *client) { struct husb311_chip *chip = i2c_get_clientdata(client); + device_init_wakeup(chip->dev, false); tcpci_unregister_port(chip->tcpci); } static int husb311_pm_suspend(struct device *dev) { struct husb311_chip *chip = dev->driver_data; + struct i2c_client *client = to_i2c_client(dev); int ret = 0; u8 pwr; @@ -230,15 +232,26 @@ static int husb311_pm_suspend(struct device *dev) if (ret < 0) return ret; + if (device_may_wakeup(dev) && !chip->vbus_on) + enable_irq_wake(client->irq); + else + disable_irq(client->irq); + return 0; } static int husb311_pm_resume(struct device *dev) { struct husb311_chip *chip = dev->driver_data; + struct i2c_client *client = to_i2c_client(dev); int ret = 0; u8 filter; + if (device_may_wakeup(dev) && !chip->vbus_on) + disable_irq_wake(client->irq); + else + enable_irq(client->irq); + /* * When the power of husb311 is lost or i2c read failed in PM S/R * process, we must reset the tcpm port first to ensure the devices