staging: r8188eu: use a delayed worker for led updates
authorMartin Kaiser <martin@kaiser.cx>
Fri, 26 Nov 2021 11:41:35 +0000 (12:41 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 3 Dec 2021 14:14:41 +0000 (15:14 +0100)
The led layer uses a combination of timer and worker for periodic led
updates, e.g. for blinking. The reason seems to be that blocking
operations like a usb read are not allowed in a timer handler.

Replace the combination of timer and worker with a delayed worker.

Convert the timeout defines from milliseconds to jiffies to make them
usable as delays for the delayed worker. Shorten the names of the defines
and rename the work item to make checkpatch happy.

Other layers may call SwLedControlMode1 to update the led state. Such
an update may result in cancelling the delayed worker. SwLedControlMode1
might be called in interrupt context, we must use cancel_delayed_work to
cancel the worker. cancel_delayed_work_sync waits until the worker is
finished, this is not allowed in interrupt context.

DeInitLed871x is called when the driver is removed or when the system
goes into standby. We may use cancel_delayed_work_sync here to cancel
the delayed worker.

Signed-off-by: Martin Kaiser <martin@kaiser.cx>
Link: https://lore.kernel.org/r/20211126114135.18228-1-martin@kaiser.cx
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/staging/r8188eu/core/rtw_led.c
drivers/staging/r8188eu/include/rtw_led.h

index ae46fd48f940da1c7bf332af777fc14849127a47..1eda366c61aad40feb81ade42cb610f92230e525 100644 (file)
@@ -4,20 +4,10 @@
 #include "../include/drv_types.h"
 #include "../include/rtw_led.h"
 
-void BlinkTimerCallback(struct timer_list *t)
-{
-       struct LED_871x *pLed = from_timer(pLed, t, BlinkTimer);
-       struct adapter *padapter = pLed->padapter;
-
-       if ((padapter->bSurpriseRemoved) || (padapter->bDriverStopped))
-               return;
-
-       schedule_work(&pLed->BlinkWorkItem);
-}
-
 void BlinkWorkItemCallback(struct work_struct *work)
 {
-       struct LED_871x *pLed = container_of(work, struct LED_871x, BlinkWorkItem);
+       struct delayed_work *dwork = to_delayed_work(work);
+       struct LED_871x *pLed = container_of(dwork, struct LED_871x, blink_work);
        BlinkHandler(pLed);
 }
 
@@ -45,14 +35,12 @@ void InitLed871x(struct adapter *padapter, struct LED_871x *pLed, enum LED_PIN_8
 
        ResetLedStatus(pLed);
 
-       timer_setup(&pLed->BlinkTimer, BlinkTimerCallback, 0);
-       INIT_WORK(&pLed->BlinkWorkItem, BlinkWorkItemCallback);
+       INIT_DELAYED_WORK(&pLed->blink_work, BlinkWorkItemCallback);
 }
 
 void DeInitLed871x(struct LED_871x *pLed)
 {
-       cancel_work_sync(&pLed->BlinkWorkItem);
-       _cancel_timer_ex(&pLed->BlinkTimer);
+       cancel_delayed_work_sync(&pLed->blink_work);
        ResetLedStatus(pLed);
 }
 
@@ -80,14 +68,14 @@ static void SwLedBlink1(struct LED_871x *pLed)
                        pLed->BlinkingLedState = RTW_LED_OFF;
                else
                        pLed->BlinkingLedState = RTW_LED_ON;
-               _set_timer(&pLed->BlinkTimer, LED_BLINK_NO_LINK_INTERVAL_ALPHA);
+               schedule_delayed_work(&pLed->blink_work, LED_BLINK_NO_LINK_INTVL);
                break;
        case LED_BLINK_NORMAL:
                if (pLed->bLedOn)
                        pLed->BlinkingLedState = RTW_LED_OFF;
                else
                        pLed->BlinkingLedState = RTW_LED_ON;
-               _set_timer(&pLed->BlinkTimer, LED_BLINK_LINK_INTERVAL_ALPHA);
+               schedule_delayed_work(&pLed->blink_work, LED_BLINK_LINK_INTVL);
                break;
        case LED_BLINK_SCAN:
                pLed->BlinkTimes--;
@@ -101,7 +89,7 @@ static void SwLedBlink1(struct LED_871x *pLed)
                                        pLed->BlinkingLedState = RTW_LED_OFF;
                                else
                                        pLed->BlinkingLedState = RTW_LED_ON;
-                               _set_timer(&pLed->BlinkTimer, LED_BLINK_LINK_INTERVAL_ALPHA);
+                               schedule_delayed_work(&pLed->blink_work, LED_BLINK_LINK_INTVL);
                        } else if (!check_fwstate(pmlmepriv, _FW_LINKED)) {
                                pLed->bLedNoLinkBlinkInProgress = true;
                                pLed->CurrLedState = LED_BLINK_SLOWLY;
@@ -109,7 +97,7 @@ static void SwLedBlink1(struct LED_871x *pLed)
                                        pLed->BlinkingLedState = RTW_LED_OFF;
                                else
                                        pLed->BlinkingLedState = RTW_LED_ON;
-                               _set_timer(&pLed->BlinkTimer, LED_BLINK_NO_LINK_INTERVAL_ALPHA);
+                               schedule_delayed_work(&pLed->blink_work, LED_BLINK_NO_LINK_INTVL);
                        }
                        pLed->bLedScanBlinkInProgress = false;
                } else {
@@ -117,7 +105,7 @@ static void SwLedBlink1(struct LED_871x *pLed)
                                pLed->BlinkingLedState = RTW_LED_OFF;
                        else
                                pLed->BlinkingLedState = RTW_LED_ON;
-                       _set_timer(&pLed->BlinkTimer, LED_BLINK_SCAN_INTERVAL_ALPHA);
+                       schedule_delayed_work(&pLed->blink_work, LED_BLINK_SCAN_INTVL);
                }
                break;
        case LED_BLINK_TXRX:
@@ -132,7 +120,7 @@ static void SwLedBlink1(struct LED_871x *pLed)
                                        pLed->BlinkingLedState = RTW_LED_OFF;
                                else
                                        pLed->BlinkingLedState = RTW_LED_ON;
-                               _set_timer(&pLed->BlinkTimer, LED_BLINK_LINK_INTERVAL_ALPHA);
+                               schedule_delayed_work(&pLed->blink_work, LED_BLINK_LINK_INTVL);
                        } else if (!check_fwstate(pmlmepriv, _FW_LINKED)) {
                                pLed->bLedNoLinkBlinkInProgress = true;
                                pLed->CurrLedState = LED_BLINK_SLOWLY;
@@ -140,7 +128,7 @@ static void SwLedBlink1(struct LED_871x *pLed)
                                        pLed->BlinkingLedState = RTW_LED_OFF;
                                else
                                        pLed->BlinkingLedState = RTW_LED_ON;
-                               _set_timer(&pLed->BlinkTimer, LED_BLINK_NO_LINK_INTERVAL_ALPHA);
+                               schedule_delayed_work(&pLed->blink_work, LED_BLINK_NO_LINK_INTVL);
                        }
                        pLed->bLedBlinkInProgress = false;
                } else {
@@ -148,7 +136,7 @@ static void SwLedBlink1(struct LED_871x *pLed)
                                pLed->BlinkingLedState = RTW_LED_OFF;
                        else
                                pLed->BlinkingLedState = RTW_LED_ON;
-                       _set_timer(&pLed->BlinkTimer, LED_BLINK_FASTER_INTERVAL_ALPHA);
+                       schedule_delayed_work(&pLed->blink_work, LED_BLINK_FASTER_INTVL);
                }
                break;
        case LED_BLINK_WPS:
@@ -156,7 +144,7 @@ static void SwLedBlink1(struct LED_871x *pLed)
                        pLed->BlinkingLedState = RTW_LED_OFF;
                else
                        pLed->BlinkingLedState = RTW_LED_ON;
-               _set_timer(&pLed->BlinkTimer, LED_BLINK_SCAN_INTERVAL_ALPHA);
+               schedule_delayed_work(&pLed->blink_work, LED_BLINK_SCAN_INTVL);
                break;
        case LED_BLINK_WPS_STOP:        /* WPS success */
                if (pLed->BlinkingLedState == RTW_LED_ON)
@@ -171,12 +159,12 @@ static void SwLedBlink1(struct LED_871x *pLed)
                                pLed->BlinkingLedState = RTW_LED_OFF;
                        else
                                pLed->BlinkingLedState = RTW_LED_ON;
-                       _set_timer(&pLed->BlinkTimer, LED_BLINK_LINK_INTERVAL_ALPHA);
+                       schedule_delayed_work(&pLed->blink_work, LED_BLINK_LINK_INTVL);
 
                        pLed->bLedWPSBlinkInProgress = false;
                } else {
                        pLed->BlinkingLedState = RTW_LED_OFF;
-                       _set_timer(&pLed->BlinkTimer, LED_BLINK_WPS_SUCESS_INTERVAL_ALPHA);
+                       schedule_delayed_work(&pLed->blink_work, LED_BLINK_WPS_SUCESS_INTVL);
                }
                break;
        default:
@@ -198,11 +186,11 @@ static void SwLedControlMode1(struct adapter *padapter, enum LED_CTL_MODE LedAct
                        if (pLed->CurrLedState == LED_BLINK_SCAN || IS_LED_WPS_BLINKING(pLed))
                                return;
                        if (pLed->bLedLinkBlinkInProgress) {
-                               _cancel_timer_ex(&pLed->BlinkTimer);
+                               cancel_delayed_work(&pLed->blink_work);
                                pLed->bLedLinkBlinkInProgress = false;
                        }
                        if (pLed->bLedBlinkInProgress) {
-                               _cancel_timer_ex(&pLed->BlinkTimer);
+                               cancel_delayed_work(&pLed->blink_work);
                                pLed->bLedBlinkInProgress = false;
                        }
 
@@ -212,7 +200,7 @@ static void SwLedControlMode1(struct adapter *padapter, enum LED_CTL_MODE LedAct
                                pLed->BlinkingLedState = RTW_LED_OFF;
                        else
                                pLed->BlinkingLedState = RTW_LED_ON;
-                       _set_timer(&pLed->BlinkTimer, LED_BLINK_NO_LINK_INTERVAL_ALPHA);
+                       schedule_delayed_work(&pLed->blink_work, LED_BLINK_NO_LINK_INTVL);
                }
                break;
        case LED_CTL_LINK:
@@ -220,11 +208,11 @@ static void SwLedControlMode1(struct adapter *padapter, enum LED_CTL_MODE LedAct
                        if (pLed->CurrLedState == LED_BLINK_SCAN || IS_LED_WPS_BLINKING(pLed))
                                return;
                        if (pLed->bLedNoLinkBlinkInProgress) {
-                               _cancel_timer_ex(&pLed->BlinkTimer);
+                               cancel_delayed_work(&pLed->blink_work);
                                pLed->bLedNoLinkBlinkInProgress = false;
                        }
                        if (pLed->bLedBlinkInProgress) {
-                               _cancel_timer_ex(&pLed->BlinkTimer);
+                               cancel_delayed_work(&pLed->blink_work);
                                pLed->bLedBlinkInProgress = false;
                        }
                        pLed->bLedLinkBlinkInProgress = true;
@@ -233,7 +221,7 @@ static void SwLedControlMode1(struct adapter *padapter, enum LED_CTL_MODE LedAct
                                pLed->BlinkingLedState = RTW_LED_OFF;
                        else
                                pLed->BlinkingLedState = RTW_LED_ON;
-                       _set_timer(&pLed->BlinkTimer, LED_BLINK_LINK_INTERVAL_ALPHA);
+                       schedule_delayed_work(&pLed->blink_work, LED_BLINK_LINK_INTVL);
                }
                break;
        case LED_CTL_SITE_SURVEY:
@@ -243,15 +231,15 @@ static void SwLedControlMode1(struct adapter *padapter, enum LED_CTL_MODE LedAct
                        if (IS_LED_WPS_BLINKING(pLed))
                                return;
                        if (pLed->bLedNoLinkBlinkInProgress) {
-                               _cancel_timer_ex(&pLed->BlinkTimer);
+                               cancel_delayed_work(&pLed->blink_work);
                                pLed->bLedNoLinkBlinkInProgress = false;
                        }
                        if (pLed->bLedLinkBlinkInProgress) {
-                               _cancel_timer_ex(&pLed->BlinkTimer);
+                               cancel_delayed_work(&pLed->blink_work);
                                pLed->bLedLinkBlinkInProgress = false;
                        }
                        if (pLed->bLedBlinkInProgress) {
-                               _cancel_timer_ex(&pLed->BlinkTimer);
+                               cancel_delayed_work(&pLed->blink_work);
                                pLed->bLedBlinkInProgress = false;
                        }
                        pLed->bLedScanBlinkInProgress = true;
@@ -261,7 +249,7 @@ static void SwLedControlMode1(struct adapter *padapter, enum LED_CTL_MODE LedAct
                                pLed->BlinkingLedState = RTW_LED_OFF;
                        else
                                pLed->BlinkingLedState = RTW_LED_ON;
-                       _set_timer(&pLed->BlinkTimer, LED_BLINK_SCAN_INTERVAL_ALPHA);
+                       schedule_delayed_work(&pLed->blink_work, LED_BLINK_SCAN_INTVL);
                 }
                break;
        case LED_CTL_TX:
@@ -270,11 +258,11 @@ static void SwLedControlMode1(struct adapter *padapter, enum LED_CTL_MODE LedAct
                        if (pLed->CurrLedState == LED_BLINK_SCAN || IS_LED_WPS_BLINKING(pLed))
                                return;
                        if (pLed->bLedNoLinkBlinkInProgress) {
-                               _cancel_timer_ex(&pLed->BlinkTimer);
+                               cancel_delayed_work(&pLed->blink_work);
                                pLed->bLedNoLinkBlinkInProgress = false;
                        }
                        if (pLed->bLedLinkBlinkInProgress) {
-                               _cancel_timer_ex(&pLed->BlinkTimer);
+                               cancel_delayed_work(&pLed->blink_work);
                                pLed->bLedLinkBlinkInProgress = false;
                        }
                        pLed->bLedBlinkInProgress = true;
@@ -284,26 +272,26 @@ static void SwLedControlMode1(struct adapter *padapter, enum LED_CTL_MODE LedAct
                                pLed->BlinkingLedState = RTW_LED_OFF;
                        else
                                pLed->BlinkingLedState = RTW_LED_ON;
-                       _set_timer(&pLed->BlinkTimer, LED_BLINK_FASTER_INTERVAL_ALPHA);
+                       schedule_delayed_work(&pLed->blink_work, LED_BLINK_FASTER_INTVL);
                }
                break;
        case LED_CTL_START_WPS: /* wait until xinpin finish */
        case LED_CTL_START_WPS_BOTTON:
                 if (!pLed->bLedWPSBlinkInProgress) {
                        if (pLed->bLedNoLinkBlinkInProgress) {
-                               _cancel_timer_ex(&pLed->BlinkTimer);
+                               cancel_delayed_work(&pLed->blink_work);
                                pLed->bLedNoLinkBlinkInProgress = false;
                        }
                        if (pLed->bLedLinkBlinkInProgress) {
-                               _cancel_timer_ex(&pLed->BlinkTimer);
+                               cancel_delayed_work(&pLed->blink_work);
                                pLed->bLedLinkBlinkInProgress = false;
                        }
                        if (pLed->bLedBlinkInProgress) {
-                               _cancel_timer_ex(&pLed->BlinkTimer);
+                               cancel_delayed_work(&pLed->blink_work);
                                pLed->bLedBlinkInProgress = false;
                        }
                        if (pLed->bLedScanBlinkInProgress) {
-                               _cancel_timer_ex(&pLed->BlinkTimer);
+                               cancel_delayed_work(&pLed->blink_work);
                                pLed->bLedScanBlinkInProgress = false;
                        }
                        pLed->bLedWPSBlinkInProgress = true;
@@ -312,42 +300,42 @@ static void SwLedControlMode1(struct adapter *padapter, enum LED_CTL_MODE LedAct
                                pLed->BlinkingLedState = RTW_LED_OFF;
                        else
                                pLed->BlinkingLedState = RTW_LED_ON;
-                       _set_timer(&pLed->BlinkTimer, LED_BLINK_SCAN_INTERVAL_ALPHA);
+                       schedule_delayed_work(&pLed->blink_work, LED_BLINK_SCAN_INTVL);
                 }
                break;
        case LED_CTL_STOP_WPS:
                if (pLed->bLedNoLinkBlinkInProgress) {
-                       _cancel_timer_ex(&pLed->BlinkTimer);
+                       cancel_delayed_work(&pLed->blink_work);
                        pLed->bLedNoLinkBlinkInProgress = false;
                }
                if (pLed->bLedLinkBlinkInProgress) {
-                       _cancel_timer_ex(&pLed->BlinkTimer);
+                       cancel_delayed_work(&pLed->blink_work);
                        pLed->bLedLinkBlinkInProgress = false;
                }
                if (pLed->bLedBlinkInProgress) {
-                       _cancel_timer_ex(&pLed->BlinkTimer);
+                       cancel_delayed_work(&pLed->blink_work);
                        pLed->bLedBlinkInProgress = false;
                }
                if (pLed->bLedScanBlinkInProgress) {
-                       _cancel_timer_ex(&pLed->BlinkTimer);
+                       cancel_delayed_work(&pLed->blink_work);
                        pLed->bLedScanBlinkInProgress = false;
                }
                if (pLed->bLedWPSBlinkInProgress)
-                       _cancel_timer_ex(&pLed->BlinkTimer);
+                       cancel_delayed_work(&pLed->blink_work);
                else
                        pLed->bLedWPSBlinkInProgress = true;
                pLed->CurrLedState = LED_BLINK_WPS_STOP;
                if (pLed->bLedOn) {
                        pLed->BlinkingLedState = RTW_LED_OFF;
-                       _set_timer(&pLed->BlinkTimer, LED_BLINK_WPS_SUCESS_INTERVAL_ALPHA);
+                       schedule_delayed_work(&pLed->blink_work, LED_BLINK_WPS_SUCESS_INTVL);
                } else {
                        pLed->BlinkingLedState = RTW_LED_ON;
-                       _set_timer(&pLed->BlinkTimer, 0);
+                       schedule_delayed_work(&pLed->blink_work, 0);
                }
                break;
        case LED_CTL_STOP_WPS_FAIL:
                if (pLed->bLedWPSBlinkInProgress) {
-                       _cancel_timer_ex(&pLed->BlinkTimer);
+                       cancel_delayed_work(&pLed->blink_work);
                        pLed->bLedWPSBlinkInProgress = false;
                }
                pLed->bLedNoLinkBlinkInProgress = true;
@@ -356,29 +344,29 @@ static void SwLedControlMode1(struct adapter *padapter, enum LED_CTL_MODE LedAct
                        pLed->BlinkingLedState = RTW_LED_OFF;
                else
                        pLed->BlinkingLedState = RTW_LED_ON;
-               _set_timer(&pLed->BlinkTimer, LED_BLINK_NO_LINK_INTERVAL_ALPHA);
+               schedule_delayed_work(&pLed->blink_work, LED_BLINK_NO_LINK_INTVL);
                break;
        case LED_CTL_POWER_OFF:
                pLed->CurrLedState = RTW_LED_OFF;
                pLed->BlinkingLedState = RTW_LED_OFF;
                if (pLed->bLedNoLinkBlinkInProgress) {
-                       _cancel_timer_ex(&pLed->BlinkTimer);
+                       cancel_delayed_work(&pLed->blink_work);
                        pLed->bLedNoLinkBlinkInProgress = false;
                }
                if (pLed->bLedLinkBlinkInProgress) {
-                       _cancel_timer_ex(&pLed->BlinkTimer);
+                       cancel_delayed_work(&pLed->blink_work);
                        pLed->bLedLinkBlinkInProgress = false;
                }
                if (pLed->bLedBlinkInProgress) {
-                       _cancel_timer_ex(&pLed->BlinkTimer);
+                       cancel_delayed_work(&pLed->blink_work);
                        pLed->bLedBlinkInProgress = false;
                }
                if (pLed->bLedWPSBlinkInProgress) {
-                       _cancel_timer_ex(&pLed->BlinkTimer);
+                       cancel_delayed_work(&pLed->blink_work);
                        pLed->bLedWPSBlinkInProgress = false;
                }
                if (pLed->bLedScanBlinkInProgress) {
-                       _cancel_timer_ex(&pLed->BlinkTimer);
+                       cancel_delayed_work(&pLed->blink_work);
                        pLed->bLedScanBlinkInProgress = false;
                }
                SwLedOff(padapter, pLed);
index c035fe2676355aec1e4739ddf194431028b093c6..7e901aae92fb4f2b7f03097d587debb3dedef3c4 100644 (file)
 #define LED_BLINK_SLOWLY_INTERVAL              200
 #define LED_BLINK_LONG_INTERVAL                        400
 
-#define LED_BLINK_NO_LINK_INTERVAL_ALPHA       1000
-#define LED_BLINK_LINK_INTERVAL_ALPHA          500     /* 500 */
-#define LED_BLINK_SCAN_INTERVAL_ALPHA          180     /* 150 */
-#define LED_BLINK_FASTER_INTERVAL_ALPHA                50
-#define LED_BLINK_WPS_SUCESS_INTERVAL_ALPHA    5000
+#define LED_BLINK_NO_LINK_INTVL                        msecs_to_jiffies(1000)
+#define LED_BLINK_LINK_INTVL                   msecs_to_jiffies(500)
+#define LED_BLINK_SCAN_INTVL                   msecs_to_jiffies(180)
+#define LED_BLINK_FASTER_INTVL                 msecs_to_jiffies(50)
+#define LED_BLINK_WPS_SUCESS_INTVL             msecs_to_jiffies(5000)
 
 #define LED_BLINK_NORMAL_INTERVAL_NETTRONIX    100
 #define LED_BLINK_SLOWLY_INTERVAL_NETTRONIX    2000
@@ -105,15 +105,12 @@ struct LED_871x {
 
        u32 BlinkTimes; /*  Number of times to toggle led state for blinking. */
 
-       struct timer_list BlinkTimer; /*  Timer object for led blinking. */
-
        /*  ALPHA, added by chiyoko, 20090106 */
        u8 bLedNoLinkBlinkInProgress;
        u8 bLedLinkBlinkInProgress;
        u8 bLedStartToLinkBlinkInProgress;
        u8 bLedScanBlinkInProgress;
-       struct work_struct BlinkWorkItem; /* Workitem used by BlinkTimer to
-                                          * manipulate H/W to blink LED. */
+       struct delayed_work blink_work;
 };
 
 #define IS_LED_WPS_BLINKING(_LED_871x)                                 \
@@ -143,7 +140,6 @@ struct led_priv{
                        (adapt)->ledpriv.LedControlHandler((adapt), (action)); \
        } while (0)
 
-void BlinkTimerCallback(struct timer_list *t);
 void BlinkWorkItemCallback(struct work_struct *work);
 
 void ResetLedStatus(struct LED_871x * pLed);