OSDN Git Service

smb-lib: improve handling of usbin plugin interrupt
authorAbhijeet Dharmapurikar <adharmap@codeaurora.org>
Tue, 5 Jul 2016 21:03:31 +0000 (14:03 -0700)
committerAbhijeet Dharmapurikar <adharmap@codeaurora.org>
Wed, 20 Jul 2016 23:50:56 +0000 (16:50 -0700)
Currently the code disables the dpdm regulator if VBUS is present and
regulator is enabled.

It could happen that the charger oscillates its VBUS as it settles and
based on the delay's in responding to an interrupt, the software could
read vbus_present while the regulator was enabled earlier causing an
incorrect disable of the dpdm regulator.

It is required to ignore the interrupt in such cases.

Change-Id: I882780c1bcbc7713973eda5383291d891787f144
Signed-off-by: Abhijeet Dharmapurikar <adharmap@codeaurora.org>
drivers/power/qcom-charger/smb-lib.c

index 55bcc9e..57919ee 100644 (file)
@@ -1280,15 +1280,6 @@ irqreturn_t smblib_handle_usb_plugin(int irq, void *data)
        int rc;
        u8 stat;
 
-       rc = smblib_read(chg, USBIN_BASE + INT_RT_STS_OFFSET, &stat);
-       if (rc < 0) {
-               dev_err(chg->dev, "Couldn't read USB_INT_RT_STS rc=%d\n",
-                       rc);
-               return IRQ_HANDLED;
-       }
-
-       chg->vbus_present = (bool)(stat & USBIN_PLUGIN_RT_STS_BIT);
-
        /* fetch the DPDM regulator */
        if (!chg->dpdm_reg && of_get_property(chg->dev->of_node,
                                              "dpdm-supply", NULL)) {
@@ -1303,18 +1294,30 @@ irqreturn_t smblib_handle_usb_plugin(int irq, void *data)
        if (!chg->dpdm_reg)
                goto skip_dpdm_float;
 
-       if (chg->vbus_present && !regulator_is_enabled(chg->dpdm_reg)) {
-               smblib_dbg(chg, PR_MISC, "enabling DPDM regulator\n");
-               rc = regulator_enable(chg->dpdm_reg);
-               if (rc < 0)
-                       dev_err(chg->dev, "Couldn't enable dpdm regulator rc=%d\n",
-                               rc);
-       } else if (regulator_is_enabled(chg->dpdm_reg)) {
-               smblib_dbg(chg, PR_MISC, "disabling DPDM regulator\n");
-               rc = regulator_disable(chg->dpdm_reg);
-               if (rc < 0)
-                       dev_err(chg->dev, "Couldn't disable dpdm regulator rc=%d\n",
-                               rc);
+       rc = smblib_read(chg, USBIN_BASE + INT_RT_STS_OFFSET, &stat);
+       if (rc < 0) {
+               dev_err(chg->dev, "Couldn't read USB_INT_RT_STS rc=%d\n", rc);
+               return IRQ_HANDLED;
+       }
+
+       chg->vbus_present = (bool)(stat & USBIN_PLUGIN_RT_STS_BIT);
+
+       if (chg->vbus_present) {
+               if (!regulator_is_enabled(chg->dpdm_reg)) {
+                       smblib_dbg(chg, PR_MISC, "enabling DPDM regulator\n");
+                       rc = regulator_enable(chg->dpdm_reg);
+                       if (rc < 0)
+                               dev_err(chg->dev, "Couldn't enable dpdm regulator rc=%d\n",
+                                       rc);
+               }
+       } else {
+               if (regulator_is_enabled(chg->dpdm_reg)) {
+                       smblib_dbg(chg, PR_MISC, "disabling DPDM regulator\n");
+                       rc = regulator_disable(chg->dpdm_reg);
+                       if (rc < 0)
+                               dev_err(chg->dev, "Couldn't disable dpdm regulator rc=%d\n",
+                                       rc);
+               }
        }
 
 skip_dpdm_float: