zoukankan      html  css  js  c++  java
  • linux sdio card睡眠治疗 sdio card removed解决方案

             近期调试几款sdio card suspend时都会出现sdio card removed,之后 

    要么死机要么模块不能正常工作。根本原因也就是休眠没有处理好。昨天最终找到了

    解决方法。

             1:host端须要设置nonremovable,软件设置:mmc->caps |= 
    MMC_CAP_NONREMOVABLE;
             2:host端须要设置keep power,在sdio card suspend时 软件设 
    置:host->pm_flags | = MMC_PM_KEEP_POWER;


             眼下我所接触到的4g网卡,博通网卡,sdio加密t卡等都会出现card 
    removed问题。



             关于2补充下须要在sdio card pm中置host keep power:


             static int XXX_suspend(struct device *pdev)
    {
         struct sdio_func *func = dev_to_sdio_func(pdev);
    
         /* keep power while host suspended */
         ret = sdio_set_host_pm_flags(func, MMC_PM_KEEP_POWER);
         if (ret) {
             sd_err(("%s: error while trying to keep power
    ", __FUNCTION__));
             return ret;
         }
    
         return 0;
    }
    
    static const struct dev_pm_ops XXX_pm_ops = {
         .suspend    = XXX_suspend,
         .resume        = XXX_resume,
    };
    


              今天花了点时间理清了card removed的原因。

            出现1错误的原因是在resume 时pm_notify调用到了msm_rescan,假设没 
    有置nonremovable,将会跑进detect,而进去就会detect出了card removed,
    进而进行了移除操作。



           

      void mmc_rescan(struct work_struct *work)
         {
             struct mmc_host *host =
                 container_of(work, struct mmc_host, detect.work);
             bool extend_wakelock = false;
    
             if (host->rescan_disable)
                 return;
    
             mmc_bus_get(host);
    
             /*
              * if there is a _removable_ card registered, check whether it is
              * still present
              */
             if (host->bus_ops && host->bus_ops->detect && !host->bus_dead
                 && !(host->caps & MMC_CAP_NONREMOVABLE))
                 host->bus_ops->detect(host);
             ---------
         }
             以下是dump_stack()打印的调用信息:
    <4>[   48.709320] [<c0013d4c>] (unwind_backtrace+0x0/0x11c) from 
    [<bf011d74>] (dhdsdio_disconnect+0xc/0x10c [bcmdhd])
    <4>[   48.720214] [<bf011d74>] (dhdsdio_disconnect+0xc/0x10c [bcmdhd]) 
    from [<bf01f9a8>] (bcmsdh_remove+0x1c/0x98 [bcmdhd])
    <4>[   48.730041] [<bf01f9a8>] (bcmsdh_remove+0x1c/0x98 [bcmdhd]) from 
    [<bf001a00>] (bcmsdh_sdmmc_remove+0x28/0x70 [bcmdhd])
    <4>[   48.740600] [<bf001a00>] (bcmsdh_sdmmc_remove+0x28/0x70 [bcmdhd]) 
    from [<c05855e0>] (sdio_bus_remove+0x38/0xf0)
    <4>[   48.753021] [<c05855e0>] (sdio_bus_remove+0x38/0xf0) from 
    [<c03a26c8>] (__device_release_driver+0x9c/0xe0)
    <4>[   48.762725] [<c03a26c8>] (__device_release_driver+0x9c/0xe0) from 
    [<c03a2728>] (device_release_driver+0x1c/0x28)
    <4>[   48.771881] [<c03a2728>] (device_release_driver+0x1c/0x28) from 
    [<c03a21f8>] (bus_remove_device+0x124/0x140)
    <4>[   48.781829] [<c03a21f8>] (bus_remove_device+0x124/0x140) from 
    [<c039fe30>] (device_del+0x108/0x16c)
    <4>[   48.790802] [<c039fe30>] (device_del+0x108/0x16c) from 
    [<c058596c>] (sdio_remove_func+0x1c/0x28)
    <4>[   48.799560] [<c058596c>] (sdio_remove_func+0x1c/0x28) from 
    [<c0584bfc>] (mmc_sdio_remove+0x3c/0x68)
    <4>[   48.808593] [<c0584bfc>] (mmc_sdio_remove+0x3c/0x68) from 
    [<c0584cb4>] (mmc_sdio_detect+0x8c/0xb4)
    <4>[   48.817565] [<c0584cb4>] (mmc_sdio_detect+0x8c/0xb4) from 
    [<c057e0c8>] (mmc_rescan+0x7c/0x2d8)
    <4>[   48.826141] [<c057e0c8>] (mmc_rescan+0x7c/0x2d8) from [<c0099dd8>] 
    (process_one_work+0x27c/0x484)
    <4>[   48.834991] [<c0099dd8>] (process_one_work+0x27c/0x484) from 
    [<c009a1f0>] (worker_thread+0x210/0x3b0)
    <4>[   48.844177] [<c009a1f0>] (worker_thread+0x210/0x3b0) from 
    [<c009e08c>] (kthread+0x80/0x8c)
    <4>[   48.852355] [<c009e08c>] (kthread+0x80/0x8c) from [<c000eaa8>] 
    (kernel_thread_exit+0x0/0x8)
    <6>[   49.083587] mmc2: card 0001 removed
    


              出现2错误的原因是在sdio resume时,假设没有设置keep power就会 
    跑sdio reset与go idle(CMD 0)后进入init_card第一个CMD就不会响应了。也就是
    这2个操作后card异常了。



      

    static int mmc_sdio_resume(struct mmc_host *host)
    {
         int i, err = 0;
    
         BUG_ON(!host);
         BUG_ON(!host->card);
    
         /* Basic card reinitialization. */
         mmc_claim_host(host);
    
         /* No need to reinitialize powered-resumed nonremovable cards */
         if (mmc_card_is_removable(host) || !mmc_card_keep_power(host)) {
             sdio_reset(host);
             mmc_go_idle(host);
             err = mmc_sdio_init_card(host, host->ocr, host->card,
                         mmc_card_keep_power(host));
             ---------
    }
            下面是dump_stack()信息打印:
         <4>[   55.269378] [<c0013d4c>] (unwind_backtrace+0x0/0x11c) from 
    [<c057d650>] (mmc_resume_host+0xec/0x15c)
    <4>[   55.269439] [<c057d650>] (mmc_resume_host+0xec/0x15c) from 
    [<c058bfdc>] (msmsdcc_runtime_resume+0xb8/0x17c)
    <4>[   55.269500] [<c058bfdc>] (msmsdcc_runtime_resume+0xb8/0x17c) from 
    [<c058c2ac>] (msmsdcc_pm_resume+0x44/0xa8)
    <4>[   55.269561] [<c058c2ac>] (msmsdcc_pm_resume+0x44/0xa8) from 
    [<c03a4074>] (platform_pm_resume+0x40/0x54)
    <4>[   55.269653] [<c03a4074>] (platform_pm_resume+0x40/0x54) from 
    [<c03a8160>] (dpm_run_callback+0x44/0x7c)
    <4>[   55.269683] [<c03a8160>] (dpm_run_callback+0x44/0x7c) from 
    [<c03a8c18>] (device_resume+0x140/0x184)
    <4>[   55.269744] [<c03a8c18>] (device_resume+0x140/0x184) from 
    [<c03a94ec>] (dpm_resume+0xfc/0x234)
    <4>[   55.269805] [<c03a94ec>] (dpm_resume+0xfc/0x234) from [<c03a97f0>] 
    (dpm_resume_end+0xc/0x18)
    <4>[   55.269866] [<c03a97f0>] (dpm_resume_end+0xc/0x18) from 
    [<c00b63bc>] (suspend_devices_and_enter+0x240/0x314)
    <4>[   55.269927] [<c00b63bc>] (suspend_devices_and_enter+0x240/0x314) 
    from [<c00b65b0>] (pm_suspend+0x120/0x200)
    <4>[   55.269958] [<c00b65b0>] (pm_suspend+0x120/0x200) from 
    [<c00b7508>] (suspend+0x68/0x180)
    <4>[   55.270019] [<c00b7508>] (suspend+0x68/0x180) from [<c0099dd8>] 
    (process_one_work+0x27c/0x484)
    <4>[   55.270080] [<c0099dd8>] (process_one_work+0x27c/0x484) from 
    [<c009a1f0>] (worker_thread+0x210/0x3b0)
    <4>[   55.270141] [<c009a1f0>] (worker_thread+0x210/0x3b0) from 
    [<c009e08c>] (kthread+0x80/0x8c)
    <4>[   55.270202] [<c009e08c>] (kthread+0x80/0x8c) from [<c000eaa8>] 
    (kernel_thread_exit+0x0/0x8)
    <4>[   55.270233] mmc2: error -110 during resume (card was removed?

    )



    以上2点做到了理论上kernel能够正常睡眠了,以下是正常的睡眠log:



    版权声明:本文博客原创文章,博客,未经同意,不得转载。

  • 相关阅读:
    Swift学习笔记(7)--控制流
    安装APK时报 Installation failed with message Failed to finalize session : INSTALL_FAILED_USER_RESTRICTED: Invalid apk.
    Android Notification 的四种使用方式
    Socket.io
    socket
    socket.io 中文手册 socket.io 中文文档
    Android中的CardView使用
    TabLayout实现底部导航栏(2)
    使用PagerSlidingTabStrip实现顶部导航栏
    TabLayout实现顶部导航栏(1)
  • 原文地址:https://www.cnblogs.com/blfshiye/p/4710211.html
Copyright © 2011-2022 走看看