Skip to content

Commit b294ff3

Browse files
Asutosh Dasmartinkpetersen
authored andcommitted
scsi: ufs: core: Enable power management for wlun
During runtime-suspend of ufs host, the SCSI devices are already suspended and so are the queues associated with them. However, the ufs host sends SSU (START_STOP_UNIT) to the wlun during runtime-suspend. During the process blk_queue_enter() checks if the queue is not in suspended state. If so, it waits for the queue to resume, and never comes out of it. Commit 52abca6 ("scsi: block: Do not accept any requests while suspended") adds the check to see if the queue is in suspended state in blk_queue_enter(). Call trace: __switch_to+0x174/0x2c4 __schedule+0x478/0x764 schedule+0x9c/0xe0 blk_queue_enter+0x158/0x228 blk_mq_alloc_request+0x40/0xa4 blk_get_request+0x2c/0x70 __scsi_execute+0x60/0x1c4 ufshcd_set_dev_pwr_mode+0x124/0x1e4 ufshcd_suspend+0x208/0x83c ufshcd_runtime_suspend+0x40/0x154 ufshcd_pltfrm_runtime_suspend+0x14/0x20 pm_generic_runtime_suspend+0x28/0x3c __rpm_callback+0x80/0x2a4 rpm_suspend+0x308/0x614 rpm_idle+0x158/0x228 pm_runtime_work+0x84/0xac process_one_work+0x1f0/0x470 worker_thread+0x26c/0x4c8 kthread+0x13c/0x320 ret_from_fork+0x10/0x18 Fix this by registering ufs device wlun as a SCSI driver and registering it for block runtime-pm. Also make this a supplier for all other LUNs. This way the wlun device suspends after all the consumers and resumes after HBA resumes. This also registers a new SCSI driver for rpmb wlun. This new driver is mostly used to clear rpmb uac. [mkp: resolve merge conflict with 5.13-rc1 and fix doc warning] Fixed smatch warnings: Reported-by: kernel test robot <[email protected]> Reported-by: Dan Carpenter <[email protected]> Link: https://lore.kernel.org/r/4662c462e79e3e7f541f54f88f8993f421026d83.1619223249.git.asutoshd@codeaurora.org Reviewed-by: Adrian Hunter <[email protected]> Co-developed-by: Can Guo <[email protected]> Signed-off-by: Can Guo <[email protected]> Signed-off-by: Asutosh Das <[email protected]> Signed-off-by: Martin K. Petersen <[email protected]>
1 parent ed26297 commit b294ff3

File tree

13 files changed

+573
-255
lines changed

13 files changed

+573
-255
lines changed

drivers/scsi/ufs/cdns-pltfrm.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -323,6 +323,8 @@ static const struct dev_pm_ops cdns_ufs_dev_pm_ops = {
323323
.runtime_suspend = ufshcd_pltfrm_runtime_suspend,
324324
.runtime_resume = ufshcd_pltfrm_runtime_resume,
325325
.runtime_idle = ufshcd_pltfrm_runtime_idle,
326+
.prepare = ufshcd_suspend_prepare,
327+
.complete = ufshcd_resume_complete,
326328
};
327329

328330
static struct platform_driver cdns_ufs_pltfrm_driver = {

drivers/scsi/ufs/tc-dwc-g210-pci.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,8 @@ static const struct dev_pm_ops tc_dwc_g210_pci_pm_ops = {
148148
.runtime_suspend = tc_dwc_g210_pci_runtime_suspend,
149149
.runtime_resume = tc_dwc_g210_pci_runtime_resume,
150150
.runtime_idle = tc_dwc_g210_pci_runtime_idle,
151+
.prepare = ufshcd_suspend_prepare,
152+
.complete = ufshcd_resume_complete,
151153
};
152154

153155
static const struct pci_device_id tc_dwc_g210_pci_tbl[] = {

drivers/scsi/ufs/ufs-debugfs.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ void __init ufs_debugfs_init(void)
1313
ufs_debugfs_root = debugfs_create_dir("ufshcd", NULL);
1414
}
1515

16-
void __exit ufs_debugfs_exit(void)
16+
void ufs_debugfs_exit(void)
1717
{
1818
debugfs_remove_recursive(ufs_debugfs_root);
1919
}
@@ -60,14 +60,14 @@ __acquires(&hba->host_sem)
6060
up(&hba->host_sem);
6161
return -EBUSY;
6262
}
63-
pm_runtime_get_sync(hba->dev);
63+
ufshcd_rpm_get_sync(hba);
6464
return 0;
6565
}
6666

6767
static void ufs_debugfs_put_user_access(struct ufs_hba *hba)
6868
__releases(&hba->host_sem)
6969
{
70-
pm_runtime_put_sync(hba->dev);
70+
ufshcd_rpm_put_sync(hba);
7171
up(&hba->host_sem);
7272
}
7373

drivers/scsi/ufs/ufs-debugfs.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ struct ufs_hba;
99

1010
#ifdef CONFIG_DEBUG_FS
1111
void __init ufs_debugfs_init(void);
12-
void __exit ufs_debugfs_exit(void);
12+
void ufs_debugfs_exit(void);
1313
void ufs_debugfs_hba_init(struct ufs_hba *hba);
1414
void ufs_debugfs_hba_exit(struct ufs_hba *hba);
1515
void ufs_debugfs_exception_event(struct ufs_hba *hba, u16 status);

drivers/scsi/ufs/ufs-exynos.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1267,6 +1267,8 @@ static const struct dev_pm_ops exynos_ufs_pm_ops = {
12671267
.runtime_suspend = ufshcd_pltfrm_runtime_suspend,
12681268
.runtime_resume = ufshcd_pltfrm_runtime_resume,
12691269
.runtime_idle = ufshcd_pltfrm_runtime_idle,
1270+
.prepare = ufshcd_suspend_prepare,
1271+
.complete = ufshcd_resume_complete,
12701272
};
12711273

12721274
static struct platform_driver exynos_ufs_pltform = {

drivers/scsi/ufs/ufs-hisi.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -574,6 +574,8 @@ static const struct dev_pm_ops ufs_hisi_pm_ops = {
574574
.runtime_suspend = ufshcd_pltfrm_runtime_suspend,
575575
.runtime_resume = ufshcd_pltfrm_runtime_resume,
576576
.runtime_idle = ufshcd_pltfrm_runtime_idle,
577+
.prepare = ufshcd_suspend_prepare,
578+
.complete = ufshcd_resume_complete,
577579
};
578580

579581
static struct platform_driver ufs_hisi_pltform = {

drivers/scsi/ufs/ufs-mediatek.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -810,12 +810,10 @@ static int ufs_mtk_post_link(struct ufs_hba *hba)
810810
/* enable unipro clock gating feature */
811811
ufs_mtk_cfg_unipro_cg(hba, true);
812812

813-
/* configure auto-hibern8 timer to 10ms */
814-
if (ufshcd_is_auto_hibern8_supported(hba)) {
815-
ufshcd_auto_hibern8_update(hba,
816-
FIELD_PREP(UFSHCI_AHIBERN8_TIMER_MASK, 10) |
817-
FIELD_PREP(UFSHCI_AHIBERN8_SCALE_MASK, 3));
818-
}
813+
/* will be configured during probe hba */
814+
if (ufshcd_is_auto_hibern8_supported(hba))
815+
hba->ahit = FIELD_PREP(UFSHCI_AHIBERN8_TIMER_MASK, 10) |
816+
FIELD_PREP(UFSHCI_AHIBERN8_SCALE_MASK, 3);
819817

820818
ufs_mtk_setup_clk_gating(hba);
821819

@@ -1097,6 +1095,8 @@ static const struct dev_pm_ops ufs_mtk_pm_ops = {
10971095
.runtime_suspend = ufshcd_pltfrm_runtime_suspend,
10981096
.runtime_resume = ufshcd_pltfrm_runtime_resume,
10991097
.runtime_idle = ufshcd_pltfrm_runtime_idle,
1098+
.prepare = ufshcd_suspend_prepare,
1099+
.complete = ufshcd_resume_complete,
11001100
};
11011101

11021102
static struct platform_driver ufs_mtk_pltform = {

drivers/scsi/ufs/ufs-qcom.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1551,6 +1551,8 @@ static const struct dev_pm_ops ufs_qcom_pm_ops = {
15511551
.runtime_suspend = ufshcd_pltfrm_runtime_suspend,
15521552
.runtime_resume = ufshcd_pltfrm_runtime_resume,
15531553
.runtime_idle = ufshcd_pltfrm_runtime_idle,
1554+
.prepare = ufshcd_suspend_prepare,
1555+
.complete = ufshcd_resume_complete,
15541556
};
15551557

15561558
static struct platform_driver ufs_qcom_pltform = {

drivers/scsi/ufs/ufs_bsg.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ static int ufs_bsg_request(struct bsg_job *job)
9797

9898
bsg_reply->reply_payload_rcv_len = 0;
9999

100-
pm_runtime_get_sync(hba->dev);
100+
ufshcd_rpm_get_sync(hba);
101101

102102
msgcode = bsg_request->msgcode;
103103
switch (msgcode) {
@@ -106,7 +106,7 @@ static int ufs_bsg_request(struct bsg_job *job)
106106
ret = ufs_bsg_alloc_desc_buffer(hba, job, &desc_buff,
107107
&desc_len, desc_op);
108108
if (ret) {
109-
pm_runtime_put_sync(hba->dev);
109+
ufshcd_rpm_put_sync(hba);
110110
goto out;
111111
}
112112

@@ -138,7 +138,7 @@ static int ufs_bsg_request(struct bsg_job *job)
138138
break;
139139
}
140140

141-
pm_runtime_put_sync(hba->dev);
141+
ufshcd_rpm_put_sync(hba);
142142

143143
if (!desc_buff)
144144
goto out;

drivers/scsi/ufs/ufshcd-pci.c

Lines changed: 5 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -410,29 +410,6 @@ static int ufshcd_pci_resume(struct device *dev)
410410
return ufshcd_system_resume(dev_get_drvdata(dev));
411411
}
412412

413-
/**
414-
* ufshcd_pci_poweroff - suspend-to-disk poweroff function
415-
* @dev: pointer to PCI device handle
416-
*
417-
* Returns 0 if successful
418-
* Returns non-zero otherwise
419-
*/
420-
static int ufshcd_pci_poweroff(struct device *dev)
421-
{
422-
struct ufs_hba *hba = dev_get_drvdata(dev);
423-
int spm_lvl = hba->spm_lvl;
424-
int ret;
425-
426-
/*
427-
* For poweroff we need to set the UFS device to PowerDown mode.
428-
* Force spm_lvl to ensure that.
429-
*/
430-
hba->spm_lvl = 5;
431-
ret = ufshcd_system_suspend(hba);
432-
hba->spm_lvl = spm_lvl;
433-
return ret;
434-
}
435-
436413
#endif /* !CONFIG_PM_SLEEP */
437414

438415
#ifdef CONFIG_PM
@@ -533,17 +510,14 @@ ufshcd_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
533510
}
534511

535512
static const struct dev_pm_ops ufshcd_pci_pm_ops = {
536-
#ifdef CONFIG_PM_SLEEP
537-
.suspend = ufshcd_pci_suspend,
538-
.resume = ufshcd_pci_resume,
539-
.freeze = ufshcd_pci_suspend,
540-
.thaw = ufshcd_pci_resume,
541-
.poweroff = ufshcd_pci_poweroff,
542-
.restore = ufshcd_pci_resume,
543-
#endif
544513
SET_RUNTIME_PM_OPS(ufshcd_pci_runtime_suspend,
545514
ufshcd_pci_runtime_resume,
546515
ufshcd_pci_runtime_idle)
516+
SET_SYSTEM_SLEEP_PM_OPS(ufshcd_pci_suspend, ufshcd_pci_resume)
517+
#ifdef CONFIG_PM_SLEEP
518+
.prepare = ufshcd_suspend_prepare,
519+
.complete = ufshcd_resume_complete,
520+
#endif
547521
};
548522

549523
static const struct pci_device_id ufshcd_pci_tbl[] = {

0 commit comments

Comments
 (0)