diff options
author | Stanislaw Gruszka <sgruszka@redhat.com> | 2011-12-12 06:43:23 -0500 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2011-12-13 15:34:02 -0500 |
commit | 41affd5286fb91176eb99b34ecd8eb522ba22369 (patch) | |
tree | 8a2230e80e6d1aaa55c6db36764cdf8d8628e397 /drivers/net/wireless/rtlwifi/pci.c | |
parent | 49d55cef5b1925a5c1efb6aaddaa40fc7c693335 (diff) |
rtlwifi: use work for lps
Leaving leisure power save mode can take some time, so it's better to
perform that action in process context with interrupts enabled. This
patch changes lps_leave tasklet to work.
Reported-by: Philipp Dreimann <philipp@dreimann.net>
Tested-by: Larry Finger <Larry.Finger@lwfinger.net>
Cc: Mike McCormack <mikem@ring3k.org>
Cc: Chaoming Li <chaoming_li@realsil.com.cn>
Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
Signed-off-by: Larry Finger <Larry.Finger@lwfinger.net>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/rtlwifi/pci.c')
-rw-r--r-- | drivers/net/wireless/rtlwifi/pci.c | 26 |
1 files changed, 14 insertions, 12 deletions
diff --git a/drivers/net/wireless/rtlwifi/pci.c b/drivers/net/wireless/rtlwifi/pci.c index 91f0525364ea..0d4d242849b4 100644 --- a/drivers/net/wireless/rtlwifi/pci.c +++ b/drivers/net/wireless/rtlwifi/pci.c | |||
@@ -610,7 +610,7 @@ tx_status_ok: | |||
610 | if (((rtlpriv->link_info.num_rx_inperiod + | 610 | if (((rtlpriv->link_info.num_rx_inperiod + |
611 | rtlpriv->link_info.num_tx_inperiod) > 8) || | 611 | rtlpriv->link_info.num_tx_inperiod) > 8) || |
612 | (rtlpriv->link_info.num_rx_inperiod > 2)) { | 612 | (rtlpriv->link_info.num_rx_inperiod > 2)) { |
613 | tasklet_schedule(&rtlpriv->works.ips_leave_tasklet); | 613 | schedule_work(&rtlpriv->works.lps_leave_work); |
614 | } | 614 | } |
615 | } | 615 | } |
616 | 616 | ||
@@ -736,7 +736,7 @@ static void _rtl_pci_rx_interrupt(struct ieee80211_hw *hw) | |||
736 | if (((rtlpriv->link_info.num_rx_inperiod + | 736 | if (((rtlpriv->link_info.num_rx_inperiod + |
737 | rtlpriv->link_info.num_tx_inperiod) > 8) || | 737 | rtlpriv->link_info.num_tx_inperiod) > 8) || |
738 | (rtlpriv->link_info.num_rx_inperiod > 2)) { | 738 | (rtlpriv->link_info.num_rx_inperiod > 2)) { |
739 | tasklet_schedule(&rtlpriv->works.ips_leave_tasklet); | 739 | schedule_work(&rtlpriv->works.lps_leave_work); |
740 | } | 740 | } |
741 | 741 | ||
742 | dev_kfree_skb_any(skb); | 742 | dev_kfree_skb_any(skb); |
@@ -903,11 +903,6 @@ static void _rtl_pci_irq_tasklet(struct ieee80211_hw *hw) | |||
903 | _rtl_pci_tx_chk_waitq(hw); | 903 | _rtl_pci_tx_chk_waitq(hw); |
904 | } | 904 | } |
905 | 905 | ||
906 | static void _rtl_pci_ips_leave_tasklet(struct ieee80211_hw *hw) | ||
907 | { | ||
908 | rtl_lps_leave(hw); | ||
909 | } | ||
910 | |||
911 | static void _rtl_pci_prepare_bcn_tasklet(struct ieee80211_hw *hw) | 906 | static void _rtl_pci_prepare_bcn_tasklet(struct ieee80211_hw *hw) |
912 | { | 907 | { |
913 | struct rtl_priv *rtlpriv = rtl_priv(hw); | 908 | struct rtl_priv *rtlpriv = rtl_priv(hw); |
@@ -945,6 +940,15 @@ static void _rtl_pci_prepare_bcn_tasklet(struct ieee80211_hw *hw) | |||
945 | return; | 940 | return; |
946 | } | 941 | } |
947 | 942 | ||
943 | static void rtl_lps_leave_work_callback(struct work_struct *work) | ||
944 | { | ||
945 | struct rtl_works *rtlworks = | ||
946 | container_of(work, struct rtl_works, lps_leave_work); | ||
947 | struct ieee80211_hw *hw = rtlworks->hw; | ||
948 | |||
949 | rtl_lps_leave(hw); | ||
950 | } | ||
951 | |||
948 | static void _rtl_pci_init_trx_var(struct ieee80211_hw *hw) | 952 | static void _rtl_pci_init_trx_var(struct ieee80211_hw *hw) |
949 | { | 953 | { |
950 | struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); | 954 | struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); |
@@ -1006,9 +1010,7 @@ static void _rtl_pci_init_struct(struct ieee80211_hw *hw, | |||
1006 | tasklet_init(&rtlpriv->works.irq_prepare_bcn_tasklet, | 1010 | tasklet_init(&rtlpriv->works.irq_prepare_bcn_tasklet, |
1007 | (void (*)(unsigned long))_rtl_pci_prepare_bcn_tasklet, | 1011 | (void (*)(unsigned long))_rtl_pci_prepare_bcn_tasklet, |
1008 | (unsigned long)hw); | 1012 | (unsigned long)hw); |
1009 | tasklet_init(&rtlpriv->works.ips_leave_tasklet, | 1013 | INIT_WORK(&rtlpriv->works.lps_leave_work, rtl_lps_leave_work_callback); |
1010 | (void (*)(unsigned long))_rtl_pci_ips_leave_tasklet, | ||
1011 | (unsigned long)hw); | ||
1012 | } | 1014 | } |
1013 | 1015 | ||
1014 | static int _rtl_pci_init_tx_ring(struct ieee80211_hw *hw, | 1016 | static int _rtl_pci_init_tx_ring(struct ieee80211_hw *hw, |
@@ -1478,7 +1480,7 @@ static void rtl_pci_deinit(struct ieee80211_hw *hw) | |||
1478 | 1480 | ||
1479 | synchronize_irq(rtlpci->pdev->irq); | 1481 | synchronize_irq(rtlpci->pdev->irq); |
1480 | tasklet_kill(&rtlpriv->works.irq_tasklet); | 1482 | tasklet_kill(&rtlpriv->works.irq_tasklet); |
1481 | tasklet_kill(&rtlpriv->works.ips_leave_tasklet); | 1483 | cancel_work_sync(&rtlpriv->works.lps_leave_work); |
1482 | 1484 | ||
1483 | flush_workqueue(rtlpriv->works.rtl_wq); | 1485 | flush_workqueue(rtlpriv->works.rtl_wq); |
1484 | destroy_workqueue(rtlpriv->works.rtl_wq); | 1486 | destroy_workqueue(rtlpriv->works.rtl_wq); |
@@ -1553,7 +1555,7 @@ static void rtl_pci_stop(struct ieee80211_hw *hw) | |||
1553 | set_hal_stop(rtlhal); | 1555 | set_hal_stop(rtlhal); |
1554 | 1556 | ||
1555 | rtlpriv->cfg->ops->disable_interrupt(hw); | 1557 | rtlpriv->cfg->ops->disable_interrupt(hw); |
1556 | tasklet_kill(&rtlpriv->works.ips_leave_tasklet); | 1558 | cancel_work_sync(&rtlpriv->works.lps_leave_work); |
1557 | 1559 | ||
1558 | spin_lock_irqsave(&rtlpriv->locks.rf_ps_lock, flags); | 1560 | spin_lock_irqsave(&rtlpriv->locks.rf_ps_lock, flags); |
1559 | while (ppsc->rfchange_inprogress) { | 1561 | while (ppsc->rfchange_inprogress) { |