3 * Copyright (c) 2004-2010 Atheros Communications Inc.
8 // Permission to use, copy, modify, and/or distribute this software for any
9 // purpose with or without fee is hereby granted, provided that the above
10 // copyright notice and this permission notice appear in all copies.
12 // THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
13 // WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
14 // MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
15 // ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
16 // WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
17 // ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
18 // OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
25 * Implementation of system power management
28 #include "ar6000_drv.h"
29 #include <linux/inetdevice.h>
30 #include <linux/platform_device.h>
31 #include "wlan_config.h"
33 #define WOW_ENABLE_MAX_INTERVAL 0
34 #define WOW_SET_SCAN_PARAMS 0
36 extern unsigned int wmitimeout;
37 extern wait_queue_head_t arEvent;
39 #undef ATH_MODULE_NAME
40 #define ATH_MODULE_NAME pm
41 #define ATH_DEBUG_PM ATH_DEBUG_MAKE_MODULE_MASK(0)
44 static struct ath_debug_mask_description pm_debug_desc[] = {
45 { ATH_DEBUG_PM , "System power management"},
48 ATH_DEBUG_INSTANTIATE_MODULE_VAR(pm,
50 "System Power Management",
51 ATH_DEBUG_MASK_DEFAULTS | ATH_DEBUG_PM,
52 ATH_DEBUG_DESCRIPTION_COUNT(pm_debug_desc),
57 int ar6000_exit_cut_power_state(struct ar6_softc *ar);
60 static void ar6k_send_asleep_event_to_app(struct ar6_softc *ar, bool asleep)
63 union iwreq_data wrqu;
65 snprintf(buf, sizeof(buf), "HOST_ASLEEP=%s", asleep ? "asleep" : "awake");
66 A_MEMZERO(&wrqu, sizeof(wrqu));
67 wrqu.data.length = strlen(buf);
68 wireless_send_event(ar->arNetDev, IWEVCUSTOM, &wrqu, buf);
71 static void ar6000_wow_resume(struct ar6_softc *ar)
73 if (ar->arWowState!= WLAN_WOW_STATE_NONE) {
74 u16 fg_start_period = (ar->scParams.fg_start_period==0) ? 1 : ar->scParams.fg_start_period;
75 u16 bg_period = (ar->scParams.bg_period==0) ? 60 : ar->scParams.bg_period;
76 WMI_SET_HOST_SLEEP_MODE_CMD hostSleepMode = {true, false};
77 ar->arWowState = WLAN_WOW_STATE_NONE;
78 if (wmi_set_host_sleep_mode_cmd(ar->arWmi, &hostSleepMode)!= 0) {
79 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Fail to setup restore host awake\n"));
81 #if WOW_SET_SCAN_PARAMS
82 wmi_scanparams_cmd(ar->arWmi, fg_start_period,
83 ar->scParams.fg_end_period,
85 ar->scParams.minact_chdwell_time,
86 ar->scParams.maxact_chdwell_time,
87 ar->scParams.pas_chdwell_time,
88 ar->scParams.shortScanRatio,
89 ar->scParams.scanCtrlFlags,
90 ar->scParams.max_dfsch_act_time,
91 ar->scParams.maxact_scan_per_ssid);
93 (void)fg_start_period;
98 #if WOW_ENABLE_MAX_INTERVAL /* we don't do it if the power consumption is already good enough. */
99 if (wmi_listeninterval_cmd(ar->arWmi, ar->arListenIntervalT, ar->arListenIntervalB) == 0) {
102 ar6k_send_asleep_event_to_app(ar, false);
103 AR_DEBUG_PRINTF(ATH_DEBUG_PM, ("Resume WoW successfully\n"));
105 AR_DEBUG_PRINTF(ATH_DEBUG_PM, ("WoW does not invoked. skip resume"));
107 ar->arWlanPowerState = WLAN_POWER_STATE_ON;
110 static void ar6000_wow_suspend(struct ar6_softc *ar)
112 #define WOW_LIST_ID 1
113 if (ar->arNetworkType != AP_NETWORK) {
114 /* Setup WoW for unicast & Arp request for our own IP
115 disable background scan. Set listen interval into 1000 TUs
116 Enable keepliave for 110 seconds
118 struct in_ifaddr **ifap = NULL;
119 struct in_ifaddr *ifa = NULL;
120 struct in_device *in_dev;
121 u8 macMask[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
123 WMI_ADD_WOW_PATTERN_CMD addWowCmd = { .filter = { 0 } };
124 WMI_DEL_WOW_PATTERN_CMD delWowCmd;
125 WMI_SET_HOST_SLEEP_MODE_CMD hostSleepMode = {false, true};
126 WMI_SET_WOW_MODE_CMD wowMode = { .enable_wow = true,
127 .hostReqDelay = 500 };/*500 ms delay*/
129 if (ar->arWowState!= WLAN_WOW_STATE_NONE) {
130 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("System already go into wow mode!\n"));
134 ar6000_TxDataCleanup(ar); /* IMPORTANT, otherwise there will be 11mA after listen interval as 1000*/
136 #if WOW_ENABLE_MAX_INTERVAL /* we don't do it if the power consumption is already good enough. */
137 if (wmi_listeninterval_cmd(ar->arWmi, A_MAX_WOW_LISTEN_INTERVAL, 0) == 0) {
141 #if WOW_SET_SCAN_PARAMS
142 status = wmi_scanparams_cmd(ar->arWmi, 0xFFFF, 0, 0xFFFF, 0, 0, 0, 0, 0, 0, 0);
144 /* clear up our WoW pattern first */
145 delWowCmd.filter_list_id = WOW_LIST_ID;
146 delWowCmd.filter_id = 0;
147 wmi_del_wow_pattern_cmd(ar->arWmi, &delWowCmd);
149 /* setup unicast packet pattern for WoW */
150 if (ar->arNetDev->dev_addr[1]) {
151 addWowCmd.filter_list_id = WOW_LIST_ID;
152 addWowCmd.filter_size = 6; /* MAC address */
153 addWowCmd.filter_offset = 0;
154 status = wmi_add_wow_pattern_cmd(ar->arWmi, &addWowCmd, ar->arNetDev->dev_addr, macMask, addWowCmd.filter_size);
156 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Fail to add WoW pattern\n"));
159 /* setup ARP request for our own IP */
160 if ((in_dev = __in_dev_get_rtnl(ar->arNetDev)) != NULL) {
161 for (ifap = &in_dev->ifa_list; (ifa = *ifap) != NULL; ifap = &ifa->ifa_next) {
162 if (!strcmp(ar->arNetDev->name, ifa->ifa_label)) {
167 if (ifa && ifa->ifa_local) {
168 WMI_SET_IP_CMD ipCmd;
169 memset(&ipCmd, 0, sizeof(ipCmd));
170 ipCmd.ips[0] = ifa->ifa_local;
171 status = wmi_set_ip_cmd(ar->arWmi, &ipCmd);
173 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Fail to setup IP for ARP agent\n"));
177 #ifndef ATH6K_CONFIG_OTA_MODE
178 wmi_powermode_cmd(ar->arWmi, REC_POWER);
181 status = wmi_set_wow_mode_cmd(ar->arWmi, &wowMode);
183 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Fail to enable wow mode\n"));
185 ar6k_send_asleep_event_to_app(ar, true);
187 status = wmi_set_host_sleep_mode_cmd(ar->arWmi, &hostSleepMode);
189 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Fail to set host asleep\n"));
192 ar->arWowState = WLAN_WOW_STATE_SUSPENDING;
193 if (ar->arTxPending[ar->arControlEp]) {
194 u32 timeleft = wait_event_interruptible_timeout(arEvent,
195 ar->arTxPending[ar->arControlEp] == 0, wmitimeout * HZ);
196 if (!timeleft || signal_pending(current)) {
197 /* what can I do? wow resume at once */
198 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Fail to setup WoW. Pending wmi control data %d\n", ar->arTxPending[ar->arControlEp]));
202 status = hifWaitForPendingRecv(ar->arHifDevice);
204 ar->arWowState = WLAN_WOW_STATE_SUSPENDED;
205 ar->arWlanPowerState = WLAN_POWER_STATE_WOW;
207 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Not allowed to go to WOW at this moment.\n"));
211 int ar6000_suspend_ev(void *context)
214 struct ar6_softc *ar = (struct ar6_softc *)context;
215 s16 pmmode = ar->arSuspendConfig;
218 case WLAN_SUSPEND_WOW:
219 if (ar->arWmiReady && ar->arWlanState==WLAN_ENABLED && ar->arConnected) {
220 ar6000_wow_suspend(ar);
221 AR_DEBUG_PRINTF(ATH_DEBUG_PM,("%s:Suspend for wow mode %d\n", __func__, ar->arWlanPowerState));
223 pmmode = ar->arWow2Config;
224 goto wow_not_connected;
227 case WLAN_SUSPEND_CUT_PWR:
229 case WLAN_SUSPEND_CUT_PWR_IF_BT_OFF:
231 case WLAN_SUSPEND_DEEP_SLEEP:
234 status = ar6000_update_wlan_pwr_state(ar, WLAN_DISABLED, true);
235 if (ar->arWlanPowerState==WLAN_POWER_STATE_ON ||
236 ar->arWlanPowerState==WLAN_POWER_STATE_WOW) {
237 AR_DEBUG_PRINTF(ATH_DEBUG_PM, ("Strange suspend state for not wow mode %d", ar->arWlanPowerState));
239 AR_DEBUG_PRINTF(ATH_DEBUG_PM,("%s:Suspend for %d mode pwr %d status %d\n", __func__, pmmode, ar->arWlanPowerState, status));
240 status = (ar->arWlanPowerState == WLAN_POWER_STATE_CUT_PWR) ? 0 : A_EBUSY;
244 ar->scan_triggered = 0;
248 int ar6000_resume_ev(void *context)
250 struct ar6_softc *ar = (struct ar6_softc *)context;
251 u16 powerState = ar->arWlanPowerState;
253 AR_DEBUG_PRINTF(ATH_DEBUG_PM, ("%s: enter previous state %d wowState %d\n", __func__, powerState, ar->arWowState));
254 switch (powerState) {
255 case WLAN_POWER_STATE_WOW:
256 ar6000_wow_resume(ar);
258 case WLAN_POWER_STATE_CUT_PWR:
260 case WLAN_POWER_STATE_DEEP_SLEEP:
261 ar6000_update_wlan_pwr_state(ar, WLAN_ENABLED, true);
262 AR_DEBUG_PRINTF(ATH_DEBUG_PM,("%s:Resume for %d mode pwr %d\n", __func__, powerState, ar->arWlanPowerState));
264 case WLAN_POWER_STATE_ON:
267 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Strange SDIO bus power mode!!\n"));
273 void ar6000_check_wow_status(struct ar6_softc *ar, struct sk_buff *skb, bool isEvent)
275 if (ar->arWowState!=WLAN_WOW_STATE_NONE) {
276 if (ar->arWowState==WLAN_WOW_STATE_SUSPENDING) {
277 AR_DEBUG_PRINTF(ATH_DEBUG_PM,("\n%s: Received IRQ while we are wow suspending!!!\n\n", __func__));
280 /* Wow resume from irq interrupt */
281 AR_DEBUG_PRINTF(ATH_DEBUG_PM, ("%s: WoW resume from irq thread status %d\n", __func__, ar->arWlanPowerState));
282 ar6000_wow_resume(ar);
286 int ar6000_power_change_ev(void *context, u32 config)
288 struct ar6_softc *ar = (struct ar6_softc *)context;
291 AR_DEBUG_PRINTF(ATH_DEBUG_PM, ("%s: power change event callback %d \n", __func__, config));
293 case HIF_DEVICE_POWER_UP:
294 ar6000_restart_endpoint(ar->arNetDev);
297 case HIF_DEVICE_POWER_DOWN:
298 case HIF_DEVICE_POWER_CUT:
305 static int ar6000_pm_probe(struct platform_device *pdev)
307 plat_setup_power(1,1);
311 static int ar6000_pm_remove(struct platform_device *pdev)
313 plat_setup_power(0,1);
317 static int ar6000_pm_suspend(struct platform_device *pdev, pm_message_t state)
322 static int ar6000_pm_resume(struct platform_device *pdev)
327 static struct platform_driver ar6000_pm_device = {
328 .probe = ar6000_pm_probe,
329 .remove = ar6000_pm_remove,
330 .suspend = ar6000_pm_suspend,
331 .resume = ar6000_pm_resume,
333 .name = "wlan_ar6000_pm",
336 #endif /* CONFIG_PM */
339 ar6000_setup_cut_power_state(struct ar6_softc *ar, AR6000_WLAN_STATE state)
342 HIF_DEVICE_POWER_CHANGE_TYPE config;
344 AR_DEBUG_PRINTF(ATH_DEBUG_PM, ("%s: Cut power %d %d \n", __func__,state, ar->arWlanPowerState));
346 AR_DEBUG_PRINTF(ATH_DEBUG_PM, ("Wlan OFF %d BT OFf %d \n", ar->arWlanOff, ar->arBTOff));
349 if (state == WLAN_ENABLED) {
350 /* Not in cut power state.. exit */
351 if (ar->arWlanPowerState != WLAN_POWER_STATE_CUT_PWR) {
355 plat_setup_power(1,0);
357 /* Change the state to ON */
358 ar->arWlanPowerState = WLAN_POWER_STATE_ON;
361 /* Indicate POWER_UP to HIF */
362 config = HIF_DEVICE_POWER_UP;
363 status = HIFConfigureDevice(ar->arHifDevice,
364 HIF_DEVICE_POWER_STATE_CHANGE,
366 sizeof(HIF_DEVICE_POWER_CHANGE_TYPE));
368 if (status == A_PENDING) {
369 } else if (status == 0) {
370 ar6000_restart_endpoint(ar->arNetDev);
373 } else if (state == WLAN_DISABLED) {
376 /* Already in cut power state.. exit */
377 if (ar->arWlanPowerState == WLAN_POWER_STATE_CUT_PWR) {
380 ar6000_stop_endpoint(ar->arNetDev, true, false);
382 config = HIF_DEVICE_POWER_CUT;
383 status = HIFConfigureDevice(ar->arHifDevice,
384 HIF_DEVICE_POWER_STATE_CHANGE,
386 sizeof(HIF_DEVICE_POWER_CHANGE_TYPE));
388 plat_setup_power(0,0);
390 ar->arWlanPowerState = WLAN_POWER_STATE_CUT_PWR;
398 ar6000_setup_deep_sleep_state(struct ar6_softc *ar, AR6000_WLAN_STATE state)
402 AR_DEBUG_PRINTF(ATH_DEBUG_PM, ("%s: Deep sleep %d %d \n", __func__,state, ar->arWlanPowerState));
404 AR_DEBUG_PRINTF(ATH_DEBUG_PM, ("Wlan OFF %d BT OFf %d \n", ar->arWlanOff, ar->arBTOff));
407 WMI_SET_HOST_SLEEP_MODE_CMD hostSleepMode;
409 if (state == WLAN_ENABLED) {
412 /* Not in deep sleep state.. exit */
413 if (ar->arWlanPowerState != WLAN_POWER_STATE_DEEP_SLEEP) {
414 if (ar->arWlanPowerState != WLAN_POWER_STATE_ON) {
415 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Strange state when we resume from deep sleep %d\n", ar->arWlanPowerState));
420 fg_start_period = (ar->scParams.fg_start_period==0) ? 1 : ar->scParams.fg_start_period;
421 hostSleepMode.awake = true;
422 hostSleepMode.asleep = false;
424 if ((status=wmi_set_host_sleep_mode_cmd(ar->arWmi, &hostSleepMode)) != 0) {
428 /* Change the state to ON */
429 ar->arWlanPowerState = WLAN_POWER_STATE_ON;
431 /* Enable foreground scanning */
432 if ((status=wmi_scanparams_cmd(ar->arWmi, fg_start_period,
433 ar->scParams.fg_end_period,
434 ar->scParams.bg_period,
435 ar->scParams.minact_chdwell_time,
436 ar->scParams.maxact_chdwell_time,
437 ar->scParams.pas_chdwell_time,
438 ar->scParams.shortScanRatio,
439 ar->scParams.scanCtrlFlags,
440 ar->scParams.max_dfsch_act_time,
441 ar->scParams.maxact_scan_per_ssid)) != 0)
446 if (ar->arNetworkType != AP_NETWORK)
449 if (ar6000_connect_to_ap(ar) != 0) {
450 /* no need to report error if connection failed */
455 } else if (state == WLAN_DISABLED){
456 WMI_SET_WOW_MODE_CMD wowMode = { .enable_wow = false };
458 /* Already in deep sleep state.. exit */
459 if (ar->arWlanPowerState != WLAN_POWER_STATE_ON) {
460 if (ar->arWlanPowerState != WLAN_POWER_STATE_DEEP_SLEEP) {
461 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Strange state when we suspend for deep sleep %d\n", ar->arWlanPowerState));
466 if (ar->arNetworkType != AP_NETWORK)
468 /* Disconnect from the AP and disable foreground scanning */
469 AR6000_SPIN_LOCK(&ar->arLock, 0);
470 if (ar->arConnected == true || ar->arConnectPending == true) {
471 AR6000_SPIN_UNLOCK(&ar->arLock, 0);
472 wmi_disconnect_cmd(ar->arWmi);
474 AR6000_SPIN_UNLOCK(&ar->arLock, 0);
478 ar->scan_triggered = 0;
480 if ((status=wmi_scanparams_cmd(ar->arWmi, 0xFFFF, 0, 0, 0, 0, 0, 0, 0, 0, 0)) != 0) {
484 /* make sure we disable wow for deep sleep */
485 if ((status=wmi_set_wow_mode_cmd(ar->arWmi, &wowMode))!= 0)
490 ar6000_TxDataCleanup(ar);
491 #ifndef ATH6K_CONFIG_OTA_MODE
492 wmi_powermode_cmd(ar->arWmi, REC_POWER);
495 hostSleepMode.awake = false;
496 hostSleepMode.asleep = true;
497 if ((status=wmi_set_host_sleep_mode_cmd(ar->arWmi, &hostSleepMode))!= 0) {
500 if (ar->arTxPending[ar->arControlEp]) {
501 u32 timeleft = wait_event_interruptible_timeout(arEvent,
502 ar->arTxPending[ar->arControlEp] == 0, wmitimeout * HZ);
503 if (!timeleft || signal_pending(current)) {
508 status = hifWaitForPendingRecv(ar->arHifDevice);
510 ar->arWlanPowerState = WLAN_POWER_STATE_DEEP_SLEEP;
515 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Fail to enter/exit deep sleep %d\n", state));
522 ar6000_update_wlan_pwr_state(struct ar6_softc *ar, AR6000_WLAN_STATE state, bool pmEvent)
525 u16 powerState, oldPowerState;
526 AR6000_WLAN_STATE oldstate = ar->arWlanState;
527 bool wlanOff = ar->arWlanOff;
529 bool btOff = ar->arBTOff;
530 #endif /* CONFIG_PM */
532 if ((state!=WLAN_DISABLED && state!=WLAN_ENABLED)) {
536 if (ar->bIsDestroyProgress) {
540 if (down_interruptible(&ar->arSem)) {
544 if (ar->bIsDestroyProgress) {
549 ar->arWlanState = wlanOff ? WLAN_DISABLED : state;
550 oldPowerState = ar->arWlanPowerState;
551 if (state == WLAN_ENABLED) {
552 powerState = ar->arWlanPowerState;
553 AR_DEBUG_PRINTF(ATH_DEBUG_PM, ("WLAN PWR set to ENABLE^^\n"));
555 if (powerState == WLAN_POWER_STATE_DEEP_SLEEP) {
556 status = ar6000_setup_deep_sleep_state(ar, WLAN_ENABLED);
557 } else if (powerState == WLAN_POWER_STATE_CUT_PWR) {
558 status = ar6000_setup_cut_power_state(ar, WLAN_ENABLED);
562 else if (pmEvent && wlanOff) {
563 bool allowCutPwr = ((!ar->arBTSharing) || btOff);
564 if ((powerState==WLAN_POWER_STATE_CUT_PWR) && (!allowCutPwr)) {
565 /* Come out of cut power */
566 ar6000_setup_cut_power_state(ar, WLAN_ENABLED);
567 status = ar6000_setup_deep_sleep_state(ar, WLAN_DISABLED);
570 #endif /* CONFIG_PM */
571 } else if (state == WLAN_DISABLED) {
572 AR_DEBUG_PRINTF(ATH_DEBUG_PM, ("WLAN PWR set to DISABLED~\n"));
573 powerState = WLAN_POWER_STATE_DEEP_SLEEP;
575 if (pmEvent) { /* disable due to suspend */
576 bool suspendCutPwr = (ar->arSuspendConfig == WLAN_SUSPEND_CUT_PWR ||
577 (ar->arSuspendConfig == WLAN_SUSPEND_WOW &&
578 ar->arWow2Config==WLAN_SUSPEND_CUT_PWR));
579 bool suspendCutIfBtOff = ((ar->arSuspendConfig ==
580 WLAN_SUSPEND_CUT_PWR_IF_BT_OFF ||
581 (ar->arSuspendConfig == WLAN_SUSPEND_WOW &&
582 ar->arWow2Config==WLAN_SUSPEND_CUT_PWR_IF_BT_OFF)) &&
583 (!ar->arBTSharing || btOff));
584 if ((suspendCutPwr) ||
585 (suspendCutIfBtOff) ||
586 (ar->arWlanState==WLAN_POWER_STATE_CUT_PWR))
588 powerState = WLAN_POWER_STATE_CUT_PWR;
592 (ar->arWlanOffConfig == WLAN_OFF_CUT_PWR) &&
593 (!ar->arBTSharing || btOff))
595 /* For BT clock sharing designs, CUT_POWER depend on BT state */
596 powerState = WLAN_POWER_STATE_CUT_PWR;
599 #endif /* CONFIG_PM */
601 if (powerState == WLAN_POWER_STATE_DEEP_SLEEP) {
602 if (ar->arWlanPowerState == WLAN_POWER_STATE_CUT_PWR) {
603 AR_DEBUG_PRINTF(ATH_DEBUG_PM, ("Load firmware before set to deep sleep\n"));
604 ar6000_setup_cut_power_state(ar, WLAN_ENABLED);
606 status = ar6000_setup_deep_sleep_state(ar, WLAN_DISABLED);
607 } else if (powerState == WLAN_POWER_STATE_CUT_PWR) {
608 status = ar6000_setup_cut_power_state(ar, WLAN_DISABLED);
614 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Fail to setup WLAN state %d\n", ar->arWlanState));
615 ar->arWlanState = oldstate;
616 } else if (status == 0) {
617 WMI_REPORT_SLEEP_STATE_EVENT wmiSleepEvent, *pSleepEvent = NULL;
618 if ((ar->arWlanPowerState == WLAN_POWER_STATE_ON) && (oldPowerState != WLAN_POWER_STATE_ON)) {
619 wmiSleepEvent.sleepState = WMI_REPORT_SLEEP_STATUS_IS_AWAKE;
620 pSleepEvent = &wmiSleepEvent;
621 } else if ((ar->arWlanPowerState != WLAN_POWER_STATE_ON) && (oldPowerState == WLAN_POWER_STATE_ON)) {
622 wmiSleepEvent.sleepState = WMI_REPORT_SLEEP_STATUS_IS_DEEP_SLEEP;
623 pSleepEvent = &wmiSleepEvent;
626 AR_DEBUG_PRINTF(ATH_DEBUG_PM, ("SENT WLAN Sleep Event %d\n", wmiSleepEvent.sleepState));
634 ar6000_set_bt_hw_state(struct ar6_softc *ar, u32 enable)
637 bool off = (enable == 0);
639 if (ar->arBTOff == off) {
643 status = ar6000_update_wlan_pwr_state(ar, ar->arWlanOff ? WLAN_DISABLED : WLAN_ENABLED, false);
651 ar6000_set_wlan_state(struct ar6_softc *ar, AR6000_WLAN_STATE state)
654 bool off = (state == WLAN_DISABLED);
655 if (ar->arWlanOff == off) {
659 status = ar6000_update_wlan_pwr_state(ar, state, false);
663 void ar6000_pm_init()
665 A_REGISTER_MODULE_DEBUG_INFO(pm);
668 * Register ar6000_pm_device into system.
669 * We should also add platform_device into the first item of array
670 * of devices[] in file arch/xxx/mach-xxx/board-xxxx.c
672 if (platform_driver_register(&ar6000_pm_device)) {
673 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("ar6000: fail to register the power control driver.\n"));
675 #endif /* CONFIG_PM */
678 void ar6000_pm_exit()
681 platform_driver_unregister(&ar6000_pm_device);
682 #endif /* CONFIG_PM */