usb: dwc2: extcon: Update recent state once 30/224630/1 accepted/tizen/unified/20200213.121551 submit/tizen/20200212.081340
authorDongwoo Lee <dwoo08.lee@samsung.com>
Wed, 12 Feb 2020 03:36:58 +0000 (12:36 +0900)
committerDongwoo Lee <dwoo08.lee@samsung.com>
Wed, 12 Feb 2020 05:16:14 +0000 (14:16 +0900)
To prevent wrong notification due to bunch of interrupts, give delay
to notification worker and thus update recent state once by discarding
events not yet notified.

Change-Id: I9bc096a5df95da78d0d91af5d2b97fbfad657247
Signed-off-by: Dongwoo Lee <dwoo08.lee@samsung.com>
drivers/usb/dwc2/core.h
drivers/usb/dwc2/extcon.c

index a5d0308..fc390f9 100644 (file)
@@ -1167,7 +1167,7 @@ struct dwc2_hsotg {
 
 #if IS_ENABLED(CONFIG_USB_DWC2_EXTCON_NOTIFY)
        struct extcon_dev *edev;
-       struct work_struct extcon_work;
+       struct delayed_work extcon_work;
        unsigned int extcon_state;
 #endif /* CONFIG_DWC2_EXTCON_NOTIFY */
 #endif /* CONFIG_USB_DWC2_PERIPHERAL || CONFIG_USB_DWC2_DUAL_ROLE */
index f8958a9..dae7ef3 100644 (file)
@@ -17,6 +17,8 @@
 #include "core.h"
 #include "hw.h"
 
+#define DWC2_EXTCON_NOTIFY_DELAY       10 /* msec */
+
 static const unsigned int supported_cable[] = {
        EXTCON_USB,
        EXTCON_NONE,
@@ -28,7 +30,12 @@ void dwc2_gadget_extcon_notify(struct dwc2_hsotg *hsotg, bool on)
                return;
 
        hsotg->extcon_state = on;
-       queue_work(system_power_efficient_wq, &hsotg->extcon_work);
+
+       if (delayed_work_pending(&hsotg->extcon_work))
+               cancel_delayed_work(&hsotg->extcon_work);
+
+       queue_delayed_work(system_power_efficient_wq, &hsotg->extcon_work,
+                          msecs_to_jiffies(DWC2_EXTCON_NOTIFY_DELAY));
 }
 
 void dwc2_gadget_cancel_extcon_work(struct dwc2_hsotg *hsotg)
@@ -36,12 +43,13 @@ void dwc2_gadget_cancel_extcon_work(struct dwc2_hsotg *hsotg)
        if (!hsotg->params.g_extcon_notify)
                return;
 
-       cancel_work_sync(&hsotg->extcon_work);
+       cancel_delayed_work_sync(&hsotg->extcon_work);
 }
 
 static void dwc2_gadget_extcon_work(struct work_struct *work)
 {
-       struct dwc2_hsotg *hsotg = container_of(work, struct dwc2_hsotg,
+       struct dwc2_hsotg *hsotg = container_of(to_delayed_work(work),
+                                               struct dwc2_hsotg,
                                                extcon_work);
 
        extcon_set_state_sync(hsotg->edev, EXTCON_USB, hsotg->extcon_state);
@@ -66,7 +74,7 @@ int dwc2_gadget_extcon_init(struct dwc2_hsotg *hsotg)
 
        hsotg->edev = edev;
 
-       INIT_WORK(&hsotg->extcon_work, dwc2_gadget_extcon_work);
+       INIT_DELAYED_WORK(&hsotg->extcon_work, dwc2_gadget_extcon_work);
 
        /*
         * HACK: In order to give chance to setup gadget for user-space