Sdio card sleep processing sdio card removed Solution
Sdio card removed will appear when debugging several sdio card suspend recently.
Either the device crashes or the module does not work properly. The root cause is that sleep is not properly handled.
Yesterday, I finally found a solution on the Broadcom Nic.
1: nonremovable needs to be set on the host, and the software setting: mmc-> caps | =
MMC_CAP_NONREMOVABLE;
2: keep power needs to be set on the host, and the software is set when sdio card suspend is used.
Set: host-> pm_flags | = MMC_PM_KEEP_POWER;
At present, the 4G network card, Broadcom network card, and sdio encrypted tcard that I have come into contact with will display card
Removed problem.
In Supplement 2, host keep power must be set in sdio card pm:
Static int XXX_suspend (struct device * pdev)
{
Struct sdio_func * func = dev_to_sdio_func (pdev );
/* Keep power while host susponded */
Ret = sdio_set_host_pm_flags (func, MMC_PM_KEEP_POWER );
If (ret ){
Sd_err ("% s: error while trying to keep power \ n", _ FUNCTION __));
Return ret;
}
Return 0;
}
Static const struct dev_pm_ops XXX_pm_ops = {
. Suspend = XXX_suspend,
. Resume = XXX_resume,
};
It took some time today to figure out the reason for card removed.
The error 1 occurs because pm_notify calls msm_rescan during resume.
If nonremovable is set, the system will run into detect, and the system will detect the card removed,
Then, the removal operation is performed.
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 );
---------
}
The following is the call information printed by dump_stack:
<4> [48.709320] [ ] (Unwind_backtrace + 0x0/0x11c) from
[ ] (Dhdsdio_disconnect + 0xc/0x10c [bcmdhd])
<4> [48.720214] [ ] (Dhdsdio_disconnect + 0xc/0x10c [bcmdhd])
From [ ] (Bcmsdh_remove + 0x1c/0x98 [bcmdhd])
<4> [48.730041] [ ] (Bcmsdh_remove + 0x1c/0x98 [bcmdhd]) from
[ ] (Bcmsdh_sdmmc_remove + 0x28/0x70 [bcmdhd])
<4> [48.740600] [ ] (Bcmsdh_sdmmc_remove + 0x28/0x70 [bcmdhd])
From [ ] (Sdio_bus_remove + 0x38/0 xf0)
<4> [48.753021] [ ] (Sdio_bus_remove + 0x38/0 xf0) from
[ ] (_ Device_release_driver + 0x9c/0xe0)
<4> [48.762725] [ ] (_ Device_release_driver + 0x9c/0xe0) from
[ ] (Device_release_driver + 0x1c/0x28)
<4> [48.771881] [ ] (Device_release_driver + 0x1c/0x28) from
[ ] (Bus_remove_device + 0x124/0x140)
<4> [48.781829] [ ] (Bus_remove_device + 0x124/0x140) from
[ ] (Device_del + 0x108/0 x16c)
<4> [48.790802] [ ] (Device_del + 0x108/0 x16c) from
[ ] (Sdio_remove_func + 0x1c/0x28)
<4> [48.799560] [ ] (Sdio_remove_func + 0x1c/0x28) from
[ ] (Mmc_sdio_remove + 0x3c/0x68)
<4> [48.808593] [ ] (Mmc_sdio_remove + 0x3c/0x68) from
[ ] (Mmc_sdio_detect + 0x8c/0xb4)
<4> [48.817565] [ ] (Mmc_sdio_detect + 0x8c/0xb4) from
[ ] (Mmc_rescan + 0x7c/0x2d8)
<4> [48.826141] [ ] (Mmc_rescan + 0x7c/0x2d8) from [ ]
(Process_one_work + 0x27c/0x484)
<4> [48.834991] [ ] (Process_one_work + 0x27c/0x484) from
[ ] (Worker_thread + 0x210/0 x3b0)
<4> [48.844177] [ ] (Worker_thread + 0x210/0 x3b0) from
[ ] (Kthread + 0x80/0 x8c)
<4> [48.852355] [ ] (Kthread + 0x80/0 x8c) from [ ]
(Kernel_thread_exit + 0x0/0x8)
<6> [49.083587] mmc2: card 0001 removed
The cause of the 2 error is that when sdio resume is not set
After running sdio reset and go idle (CMD 0), the first CMD that enters init_card will not respond, that is
After these two operations, the card is abnormal.
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 ));
---------
}
The following is the dump_stack () printing information:
<4> [55.269378] [ ] (Unwind_backtrace + 0x0/0x11c) from
[ ] (Mmc_resume_host + 0xec/0x15c)
<4> [55.269439] [ ] (Mmc_resume_host + 0xec/0x15c) from
[ ] (Msmsdcc_runtime_resume + 0xb8/0x17c)
<4> [55.269500] [ ] (Msmsdcc_runtime_resume + 0xb8/0x17c) from
[ ] (Msmsdcc_pm_resume + 0x44/0 xa8)
<4> [55.269561] [ ] (Msmsdcc_pm_resume + 0x44/0 xa8) from
[ ] (Platform_pm_resume + 0x40/0x54)
<4> [55.269653] [ ] (Platform_pm_resume + 0x40/0x54) from
[ ] (Dpm_run_callback + 0x44/0 x7c)
<4> [55.269683] [ ] (Dpm_run_callback + 0x44/0 x7c) from
[ ] (Device_resume + 0x140/0x184)
<4> [55.269744] [ ] (Device_resume + 0x140/0x184) from
[ ] (Dpm_resume + 0xfc/0x234)
<4> [55.269805] [ ] (Dpm_resume + 0xfc/0x234) from [ ]
(Dpm_resume_end + 0xc/0x18)
<4> [55.269866] [ ] (Dpm_resume_end + 0xc/0x18) from
[ ] (Suspend_devices_and_enter + 0x240/0x314)
<4> [55.269927] [ ] (Suspend_devices_and_enter + 0x240/0x314)
From [ ] (Pm_suspend + 0x120/0x200)
<4> [55.269958] [ ] (Pm_suspend + 0x120/0x200) from
[ ] (Suspend + 0x68/0x180)
<4> [55.270019] [ ] (Suspend + 0x68/0x180) from [ ]
(Process_one_work + 0x27c/0x484)
<4> [55.270080] [ ] (Process_one_work + 0x27c/0x484) from
[ ] (Worker_thread + 0x210/0 x3b0)
<4> [55.270141] [ ] (Worker_thread + 0x210/0 x3b0) from
[ ] (Kthread + 0x80/0 x8c)
<4> [55.270202] [ ] (Kthread + 0x80/0 x8c) from [ ]
(Kernel_thread_exit + 0x0/0x8)
<4> [55.270233] mmc2: error-110 during resume (card was removed ?)