USB: dwc3: Add support for non standard charger detection

Current driver does have support for detecting non standard
charger. If this support is enabled, there are chances that slowly
connecting device to SDP slowly can be detected as non standard
charger and will start charging with 1500mA. This happens due to
data lines not making contact within 900msec. Hence add support for
detecting these scenarios and detect the correct charger.

CRs-Fixed: 492480
Change-Id: I27518f0090d5c321823d2e632b61f81e523f6087
Signed-off-by: Vijayavardhan Vennapusa <vvreddy@codeaurora.org>
diff --git a/drivers/usb/dwc3/dwc3_otg.c b/drivers/usb/dwc3/dwc3_otg.c
index be9a4b5..98c9b4c 100644
--- a/drivers/usb/dwc3/dwc3_otg.c
+++ b/drivers/usb/dwc3/dwc3_otg.c
@@ -13,6 +13,7 @@
  * GNU General Public License for more details.
  */
 
+#include <linux/module.h>
 #include <linux/usb.h>
 #include <linux/usb/hcd.h>
 #include <linux/platform_device.h>
@@ -23,6 +24,10 @@
 #include "io.h"
 #include "xhci.h"
 
+#define MAX_INVALID_CHRGR_RETRY 3
+static int max_chgr_retry_count = MAX_INVALID_CHRGR_RETRY;
+module_param(max_chgr_retry_count, int, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(max_chgr_retry_count, "Max invalid charger retry count");
 static void dwc3_otg_reset(struct dwc3_otg *dotg);
 
 static void dwc3_otg_notify_host_mode(struct usb_otg *otg, int host_mode);
@@ -686,6 +691,7 @@
 			dev_dbg(phy->dev, "!id\n");
 			phy->state = OTG_STATE_A_IDLE;
 			work = 1;
+			dotg->charger_retry_count = 0;
 			if (charger) {
 				if (charger->chg_type == DWC3_INVALID_CHARGER)
 					charger->start_detection(dotg->charger,
@@ -720,6 +726,17 @@
 					phy->state = OTG_STATE_B_PERIPHERAL;
 					work = 1;
 					break;
+				case DWC3_UNSUPPORTED_CHARGER:
+					dotg->charger_retry_count++;
+					if (dotg->charger_retry_count ==
+						max_chgr_retry_count) {
+						dwc3_otg_set_power(phy, 0);
+						pm_runtime_put_sync(phy->dev);
+						break;
+					}
+					charger->start_detection(dotg->charger,
+									false);
+
 				default:
 					dev_dbg(phy->dev, "chg_det started\n");
 					charger->start_detection(charger, true);
@@ -744,6 +761,7 @@
 			if (charger)
 				charger->start_detection(dotg->charger, false);
 
+			dotg->charger_retry_count = 0;
 			dwc3_otg_set_power(phy, 0);
 			dev_dbg(phy->dev, "No device, trying to suspend\n");
 			pm_runtime_put_sync(phy->dev);