Skip to content

Commit fb276f7

Browse files
Can Guomartinkpetersen
authored andcommitted
scsi: ufs: Enable block layer runtime PM for well-known logical units
Block layer RPM is enabled for the genernal UFS SCSI devices when they are probed by their driver. However block layer RPM is not enabled for UFS well-known SCSI devices. As UFS SCSI devices have their corresponding BSG char devices, accessing a BSG char device via IOCTL may send requests to its corresponding SCSI device through its request queue. If BSG IOCTL sends a request to a well-known SCSI device when HBA is not runtime active, due to block layer RPM not being enabled for the well-known SCSI devices, the HBA, which is at the top of a SCSI device's parent chain, will not be resumed. This change enables block layer RPM for the well-known SCSI devices so that block layer can handle RPM for the well-known SCSI devices just like for the general SCSI devices. Reviewed-by: Avri Altman <[email protected]> Reviewed-by: Stanley Chu <[email protected]> Signed-off-by: Can Guo <[email protected]> Signed-off-by: Martin K. Petersen <[email protected]>
1 parent 80b2100 commit fb276f7

File tree

1 file changed

+17
-2
lines changed

1 file changed

+17
-2
lines changed

drivers/scsi/ufs/ufshcd.c

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
#include <linux/nls.h>
4343
#include <linux/of.h>
4444
#include <linux/bitfield.h>
45+
#include <linux/blk-pm.h>
4546
#include "ufshcd.h"
4647
#include "ufs_quirks.h"
4748
#include "unipro.h"
@@ -6512,6 +6513,16 @@ static void ufshcd_init_icc_levels(struct ufs_hba *hba)
65126513
kfree(desc_buf);
65136514
}
65146515

6516+
static inline void ufshcd_blk_pm_runtime_init(struct scsi_device *sdev)
6517+
{
6518+
scsi_autopm_get_device(sdev);
6519+
blk_pm_runtime_init(sdev->request_queue, &sdev->sdev_gendev);
6520+
if (sdev->rpm_autosuspend)
6521+
pm_runtime_set_autosuspend_delay(&sdev->sdev_gendev,
6522+
RPM_AUTOSUSPEND_DELAY_MS);
6523+
scsi_autopm_put_device(sdev);
6524+
}
6525+
65156526
/**
65166527
* ufshcd_scsi_add_wlus - Adds required W-LUs
65176528
* @hba: per-adapter instance
@@ -6551,6 +6562,7 @@ static int ufshcd_scsi_add_wlus(struct ufs_hba *hba)
65516562
hba->sdev_ufs_device = NULL;
65526563
goto out;
65536564
}
6565+
ufshcd_blk_pm_runtime_init(hba->sdev_ufs_device);
65546566
scsi_device_put(hba->sdev_ufs_device);
65556567

65566568
sdev_rpmb = __scsi_add_device(hba->host, 0, 0,
@@ -6559,14 +6571,17 @@ static int ufshcd_scsi_add_wlus(struct ufs_hba *hba)
65596571
ret = PTR_ERR(sdev_rpmb);
65606572
goto remove_sdev_ufs_device;
65616573
}
6574+
ufshcd_blk_pm_runtime_init(sdev_rpmb);
65626575
scsi_device_put(sdev_rpmb);
65636576

65646577
sdev_boot = __scsi_add_device(hba->host, 0, 0,
65656578
ufshcd_upiu_wlun_to_scsi_wlun(UFS_UPIU_BOOT_WLUN), NULL);
6566-
if (IS_ERR(sdev_boot))
6579+
if (IS_ERR(sdev_boot)) {
65676580
dev_err(hba->dev, "%s: BOOT WLUN not found\n", __func__);
6568-
else
6581+
} else {
6582+
ufshcd_blk_pm_runtime_init(sdev_boot);
65696583
scsi_device_put(sdev_boot);
6584+
}
65706585
goto out;
65716586

65726587
remove_sdev_ufs_device:

0 commit comments

Comments
 (0)