scsi: ufs: rockchip: Fix ufs_rockchip_remove

Modular test showed a bug in ufs_rockchip_remove which looks like:
[   23.132276][  T844] ufshcd-rockchip 2a2d0000.ufs: Unbalanced pm_runtime_enable!
[   23.133411][  T217] ueventd: restorecon_recursive: /sys/devices/platform/2a2d0000.ufs
[   23.141741][   T80] platform 2a2d0000.ufs: uic cmd 0x16 with arg3 0x0 completion timeout
[   23.141749][   T10] platform 2a2d0000.ufs: uic cmd 0x14 with arg3 0x0 completion timeout
[   23.141772][   T10] platform 2a2d0000.ufs: dme-reset: error code -110
[   23.141775][   T10] platform 2a2d0000.ufs: DME_RESET failed
[   23.141779][   T10] platform 2a2d0000.ufs: link startup failed -110
[   23.141782][   T10] platform 2a2d0000.ufs: UFS Host state=0
[   23.141785][   T10] platform 2a2d0000.ufs: outstanding reqs=0x0 tasks=0x0
[   23.141789][   T10] platform 2a2d0000.ufs: saved_err=0x0, saved_uic_err=0x0
[   23.141800][   T10] platform 2a2d0000.ufs: Device power mode=1, UIC link state=0
[   23.141801][   T80] Unable to handle kernel paging request at virtual address ffffffc00f170034
[   23.141804][   T80] Mem abort info:
[   23.147077][   T10] platform 2a2d0000.ufs: PM in progress=0, sys. suspended=0
[   23.147829][   T80]   ESR = 0x0000000096000007
[   23.148134][   T10] platform 2a2d0000.ufs: Auto BKOPS=0, Host self-block=0
[   23.148752][   T80]   EC = 0x25: DABT (current EL), IL = 32 bits

This can be triggered by:
while true
do
  echo "2a2d0000.ufs" > /sys/bus/platform/drivers/ufshcd-rockchip/unbind;
  sleep 2;
  echo "2a2d0000.ufs" > /sys/bus/platform/drivers/ufshcd-rockchip/bind;
  sleep 2;
done

Also we leave reference clk ungate if ufs is removed. Fix them all together.

Change-Id: I785a7c196ddacf2fb51eba441bcdb288441f9c30
Signed-off-by: Shawn Lin <shawn.lin@rock-chips.com>
This commit is contained in:
Shawn Lin
2024-03-14 09:30:51 +08:00
committed by Tao Huang
parent a6a4762e0c
commit 08d7544548

View File

@@ -357,8 +357,14 @@ static int ufs_rockchip_probe(struct platform_device *pdev)
static int ufs_rockchip_remove(struct platform_device *pdev)
{
struct ufs_hba *hba = platform_get_drvdata(pdev);
struct ufs_rockchip_host *host = ufshcd_get_variant(hba);
pm_runtime_forbid(&pdev->dev);
pm_runtime_get_noresume(&pdev->dev);
ufshcd_remove(hba);
ufshcd_dealloc_host(hba);
clk_disable_unprepare(host->ref_out_clk);
return 0;
}