if (((rtlpriv->link_info.num_rx_inperiod +
                rtlpriv->link_info.num_tx_inperiod) > 8) ||
                (rtlpriv->link_info.num_rx_inperiod > 2)) {
-               tasklet_schedule(&rtlpriv->works.ips_leave_tasklet);
+               schedule_work(&rtlpriv->works.lps_leave_work);
        }
 }
 
                if (((rtlpriv->link_info.num_rx_inperiod +
                        rtlpriv->link_info.num_tx_inperiod) > 8) ||
                        (rtlpriv->link_info.num_rx_inperiod > 2)) {
-                       tasklet_schedule(&rtlpriv->works.ips_leave_tasklet);
+                       schedule_work(&rtlpriv->works.lps_leave_work);
                }
 
                dev_kfree_skb_any(skb);
        _rtl_pci_tx_chk_waitq(hw);
 }
 
-static void _rtl_pci_ips_leave_tasklet(struct ieee80211_hw *hw)
-{
-       rtl_lps_leave(hw);
-}
-
 static void _rtl_pci_prepare_bcn_tasklet(struct ieee80211_hw *hw)
 {
        struct rtl_priv *rtlpriv = rtl_priv(hw);
        return;
 }
 
+static void rtl_lps_leave_work_callback(struct work_struct *work)
+{
+       struct rtl_works *rtlworks =
+           container_of(work, struct rtl_works, lps_leave_work);
+       struct ieee80211_hw *hw = rtlworks->hw;
+
+       rtl_lps_leave(hw);
+}
+
 static void _rtl_pci_init_trx_var(struct ieee80211_hw *hw)
 {
        struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
        tasklet_init(&rtlpriv->works.irq_prepare_bcn_tasklet,
                     (void (*)(unsigned long))_rtl_pci_prepare_bcn_tasklet,
                     (unsigned long)hw);
-       tasklet_init(&rtlpriv->works.ips_leave_tasklet,
-                    (void (*)(unsigned long))_rtl_pci_ips_leave_tasklet,
-                    (unsigned long)hw);
+       INIT_WORK(&rtlpriv->works.lps_leave_work, rtl_lps_leave_work_callback);
 }
 
 static int _rtl_pci_init_tx_ring(struct ieee80211_hw *hw,
 
        synchronize_irq(rtlpci->pdev->irq);
        tasklet_kill(&rtlpriv->works.irq_tasklet);
-       tasklet_kill(&rtlpriv->works.ips_leave_tasklet);
+       cancel_work_sync(&rtlpriv->works.lps_leave_work);
 
        flush_workqueue(rtlpriv->works.rtl_wq);
        destroy_workqueue(rtlpriv->works.rtl_wq);
        set_hal_stop(rtlhal);
 
        rtlpriv->cfg->ops->disable_interrupt(hw);
-       tasklet_kill(&rtlpriv->works.ips_leave_tasklet);
+       cancel_work_sync(&rtlpriv->works.lps_leave_work);
 
        spin_lock_irqsave(&rtlpriv->locks.rf_ps_lock, flags);
        while (ppsc->rfchange_inprogress) {