linux & android平台WIFI休眠唤醒问题

这两周很痛苦,因为自己负责的WIFI模块休眠唤醒有问题,导致每天晚上都睡不好觉,第二天没有精神上班。

不过所幸的是,这两天找到了方法解决了,现在想把经验和大家分享下。

把调试环境和硬件说一下:

硬件平台:三星S5PV210

kernel: 2.6.35

android:2.3.4

WIFI驱动使用SDIO接口,有独立的上电及复位接口。

先上问题:

在WIFI打开的情况下,在WIFI的设置界面,按“MENU”键,选择高级->Wi-Fi休眠策略->充电时永不休眠/永不休眠,然后按POWER键使机器进入深度休眠,唤醒后WIFI不正常,软件跑飞。

跑飞的LOG:

[ 96.430142] DAPM sequencing finished, waiting 2ms
[ 96.432989] DAPM sequencing finished, waiting 2ms
[ 96.437106] smdkc110-rtc smdkc110-rtc: rtc disabled, re-enabling
[ 96.437127] smdkc110-rtc smdkc110-rtc: rtc disabled, re-enabling
[ 96.437143] smdkc110-rtc smdkc110-rtc: rtc disabled, re-enabling
[ 96.437185] pm_op(): platform_pm_suspend+0x0/0x64 returns -16
[ 96.437197] PM: Device alarm failed to suspend: error -16
[ 96.437206] PM: Some devices failed to suspend
[ 96.437541] PM: resume of devices complete after 0.321 msecs
[ 96.486343] Restarting tasks ...
[ 96.493614] done.
[ 96.499432] suspend: exit suspend, ret = -16 (2012-06-12 08:24:09.352134502 UTC)
[ 96.508291] DAPM sequencing finished, waiting 2ms
[ 96.515022] DAPM sequencing finished, waiting 2ms
[ 96.518930] dai_active 0, IISMOD 00000100, IISCON 8050c491
[ 96.526857] Inside s5p_i2s_resume..@550
[ 97.430432] dhdsdio_disconnect: Enter
[ 97.432612] dhdsdio_release: Enter
[ 97.436029] kernel BUG at drivers/mmc/core/sdio_io.c:29!
[ 97.441340] Unable to handle kernel NULL pointer dereference at virtual address 00000000
[ 97.449358] pgd = c0004000
[ 97.452023] [00000000] *pgd=00000000
[ 97.455578] Internal error: Oops: 817 [#1] PREEMPT
[ 97.460342] last sysfs file: /sys/devices/platform/sec-fake-battery/power_supply/battery/technology
[ 97.469354] Modules linked in: dhd
[ 97.472737] CPU: 0 Not tainted (2.6.35.7 #72)
[ 97.477422] PC is at __bug+0x20/0x2c
[ 97.480971] LR is at schedule+0x274/0x2e8
[ 97.484955] pc : [<c0033dcc>] lr : [<c0448298>] psr: 60000013
[ 97.484961] sp : df89ddc8 ip : df89dcd0 fp : df89ddd4
[ 97.496391] r10: dfa991c4 r9 : dfa991c0 r8 : df87b050
[ 97.501591] r7 : df87b058 r6 : bf02a670 r5 : bf02a668 r4 : db9ced80
[ 97.508090] r3 : 00000000 r2 : 00000000 r1 : 00000002 r0 : 00000042
[ 97.514591] Flags: nZCv IRQs on FIQs on Mode SVC_32 ISA ARM Segment kernel
[ 97.521870] Control: 10c5387d Table: 4f078019 DAC: 00000017
[ 97.527587]
[ 97.527590] PC: 0xc0033d4c:
[ 97.531832] 3d4c e89da800 c0567cee e1a0c00d e92dd800 e24cb004 e1a0c001 e1a03002 e1a01000
[ 97.539978] 3d6c e1a0200c e59f0004 eb104f83 e89da800 c0567d05 e1a0c00d e92dd800 e24cb004
[ 97.548123] 3d8c e1a0c001 e1a03002 e1a01000 e1a0200c e59f0004 eb104f78 e89da800 c0567d1c
[ 97.556269] 3dac e1a0c00d e92dd800 e24cb004 e1a02001 e1a01000 e59f000c eb104f6f e3a03000
[ 97.564415] 3dcc e5833000 eafffffe c0567d33 e1a0c00d e92dd800 e24cb004 e59f0004 e30012e1
[ 97.572561] 3dec ebffffee c0567d4c e1a0c00d e92dd800 e24cb004 e1a01000 e59f000c eb104f5e
[ 97.580706] 3e0c e59f0008 e30012c5 ebffffe4 c0567d64 c0567d4c e1a0c00d e92dd800 e24cb004
[ 97.588852] 3e2c e59f000c eb104f54 e59f0008 eb104f52 e89da800 c0567d84 c0567dbb e1a0c00d
[ 97.596999]
[ 97.597001] LR: 0xc0448218:
[ 97.601244] 8218 0a000001 e1570006 0a000012 e59f20d8 e5963170 e5922000 e0223003 e1b03423
[ 97.609390] 8238 0a000001 e1a00006 ebefc4a9 e59f30bc e5962184 e5933184 e1520003 0a000001
[ 97.617536] 8258 e1a00006 ebefbcd3 e5960024 e1a01006 e2800207 ebefc519 e59530dc e1a00005
[ 97.625681] 8278 e3530000 058530e0 059f3074 05837440 e5982004 e5951004 ebef9f37 ebf0204f
[ 97.633827] 8298 ea000001 e1a0000c eb000990 e594300c e5933014 e3530000 ba000005 eb000a46
[ 97.641973] 82b8 e3500000 b59f3038 b5935434 b285af62 baffff68 e5942000 e5943004 e3120002
[ 97.650118] 82d8 e2433001 e5843004 0a000003 eaffff55 e3a03000 e5853000 eaffff85 e24bd024
[ 97.658264] 82f8 e89dadf0 c05ff6f0 c044c5b8 c05f2900 c060e724 e1a0c00d e92dd878 e24cb004
[ 97.666410]
[ 97.666413] SP: 0xdf89dd48:
[ 97.670656] dd48 00205d39 00000000 df89dde4 df89dd60 c00578fc c04484d4 ffffffff df89ddb4
[ 97.678802] dd68 bf02a670 df87b058 df89ddd4 df89dd80 c002fa6c c002f2c4 00000042 00000002
[ 97.686947] dd88 00000000 00000000 db9ced80 bf02a668 bf02a670 df87b058 df87b050 dfa991c0
[ 97.695093] dda8 dfa991c4 df89ddd4 df89dcd0 df89ddc8 c0448298 c0033dcc 60000013 ffffffff
[ 97.703239] ddc8 df89dde4 df89ddd8 c02dc960 c0033db8 df89ddfc df89dde8 bf01e6c8 c02dc938
[ 97.711384] dde8 ce7e2800 db9cd940 df89de0c df89de00 bf020194 bf01e6ac df89de24 df89de10
[ 97.719530] de08 bf016718 bf02018c ce7e2800 db9cd880 df89de3c df89de28 bf01687c bf0166d0
[ 97.727676] de28 00000002 bf02a65c df89de5c df89de40 bf0203c8 bf016838 00000002 bf02787c
[ 97.735822]
[ 97.735825] IP: 0xdf89dc50:
[ 97.740068] dc50 00000000 00000000 df89dd80 00000000 00000817 00000000 df89dc9c df89dc78
[ 97.748214] dc70 c00368cc c003430c df89dd80 df88ae00 df89dd80 00000001 00000000 00000000
[ 97.756359] dc90 df89dcd4 df89dca0 c0036acc c003686c df17601c df88ae00 df89dccc 00000817
[ 97.764505] dcb0 c05f247c 00000000 df89dd80 df87b050 20000113 dfa991c4 df89dd7c df89dcd8
[ 97.772651] dcd0 c002f2f4 c00368f8 df89c000 00000042 0000002d c05ffcdc 60000013 0000000f
[ 97.780797] dcf0 df89dd14 df89dd00 c0448508 c0448030 00000002 00000000 df89dd9c df89dd18
[ 97.788942] dd10 c00578fc c04484d4 c05ffd68 00000002 2df3f42b 0000000c afa3d24b 00000016
[ 97.797088] dd30 60000013 60000013 df89dd5c 2020205b 342e3739 32303633 00205d39 00000000


WIFI模块使用的是SDIO接口,经过认真分析后,觉得应该从MMC驱动入手,毕竟是在MMC驱动出的问题。可关键是,查找了很久,也没发现什么可疑的。

最后无奈,采用最原始的方法,就是加LOG,一步一步的跟。

终于,还是被我找到原因了。

在SDIO驱动的sdio_reset_comm函数中,每次唤醒时,都会调用mmc_send_io_op_cond函数,现在出错时,就是这个函数返回失败了。

那么再研究下这个函数,发现它有通过mmc_wait_for_cmd函数来发命令给模块,而且传递的参数中,有MMC_CMD_RETRIES值,设置了3次。

那么,会不会是这个值太短了呢?

以我的经验,有的时候模块在唤醒的过程中,由于模块硬件本身没有准备好,还在进行模块本身的初始化,而这时候与模块进行通信有可能会导致通信失败。

那么,何不把MMC_CMD_RETRIES这个值改个极限值试试?即改一个极端的大一点的值。

我把它改成300,以及把当前函数下的mmc_delay(10)改成mmc_delay(100),再测试。

奇迹出现了,唤醒后,它居然没有跑飞。

我欣喜若狂,赶紧测试多几次,发现还真没有跑飞的情况出现。

那么,这个问题就这么解决了?

以我的经验,不能马上下结论,需要多测看看会不会导致别的问题出现。

于是我再多测,发现还会有另外一个问题,即dhd_dev_reset: dhd_bus_devreset: -35

但这个问题不是因为我修改跑飞的情况出现的,而是之前就出现的。

但是现在已经没有多少时间查找了,于是我做了如下修改:

1、修改MMC驱动,休眠唤醒初始化模块次数增加。

2、深度休眠时,把WIFI的POWER及RESET脚置低,使模块断电。唤醒时再恢复。
3、在WIFI打开的情况下,在WIFI的设置界面,按“MENU”键,选择高级->Wi-Fi休眠策略->屏幕关闭时休眠时,android层修改为按POER键休眠时,卸载wifi驱动,唤醒时再加载。
4、在WIFI打开的情况下,当选择“充电时永不休眠”时,充电情况下,休眠时,锁住电源不让系统进入深度休眠(虽然进入深度休眠按照方法1已经改好,但测试时发现唤醒后会有10%的概率产生驱动出错的问题)。非充电情况下休眠时按照方法2操作。
5、在WIFI打开的情况下,当选择“永不休眠”时,休眠时锁住电源不让系统进入深度休眠。
按如上方法修改后,WIFI未测到出现休眠唤醒问题。

此问题得到圆满解决。


  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值