@@ -744,6 +744,8 @@ static void ufshcd_exit_clk_gating(struct ufs_hba *hba)
744
744
if (!ufshcd_is_clkgating_allowed (hba ))
745
745
return ;
746
746
device_remove_file (hba -> dev , & hba -> clk_gating .delay_attr );
747
+ cancel_work_sync (& hba -> clk_gating .ungate_work );
748
+ cancel_delayed_work_sync (& hba -> clk_gating .gate_work );
747
749
}
748
750
749
751
/* Must be called with host lock acquired */
@@ -2246,6 +2248,22 @@ static int ufshcd_uic_hibern8_exit(struct ufs_hba *hba)
2246
2248
return ret ;
2247
2249
}
2248
2250
2251
+ /**
2252
+ * ufshcd_init_pwr_info - setting the POR (power on reset)
2253
+ * values in hba power info
2254
+ * @hba: per-adapter instance
2255
+ */
2256
+ static void ufshcd_init_pwr_info (struct ufs_hba * hba )
2257
+ {
2258
+ hba -> pwr_info .gear_rx = UFS_PWM_G1 ;
2259
+ hba -> pwr_info .gear_tx = UFS_PWM_G1 ;
2260
+ hba -> pwr_info .lane_rx = 1 ;
2261
+ hba -> pwr_info .lane_tx = 1 ;
2262
+ hba -> pwr_info .pwr_rx = SLOWAUTO_MODE ;
2263
+ hba -> pwr_info .pwr_tx = SLOWAUTO_MODE ;
2264
+ hba -> pwr_info .hs_rate = 0 ;
2265
+ }
2266
+
2249
2267
/**
2250
2268
* ufshcd_get_max_pwr_mode - reads the max power mode negotiated with device
2251
2269
* @hba: per-adapter instance
@@ -2844,8 +2862,13 @@ static void ufshcd_slave_destroy(struct scsi_device *sdev)
2844
2862
hba = shost_priv (sdev -> host );
2845
2863
scsi_deactivate_tcq (sdev , hba -> nutrs );
2846
2864
/* Drop the reference as it won't be needed anymore */
2847
- if (ufshcd_scsi_to_upiu_lun (sdev -> lun ) == UFS_UPIU_UFS_DEVICE_WLUN )
2865
+ if (ufshcd_scsi_to_upiu_lun (sdev -> lun ) == UFS_UPIU_UFS_DEVICE_WLUN ) {
2866
+ unsigned long flags ;
2867
+
2868
+ spin_lock_irqsave (hba -> host -> host_lock , flags );
2848
2869
hba -> sdev_ufs_device = NULL ;
2870
+ spin_unlock_irqrestore (hba -> host -> host_lock , flags );
2871
+ }
2849
2872
}
2850
2873
2851
2874
/**
@@ -4062,6 +4085,8 @@ static void ufshcd_init_icc_levels(struct ufs_hba *hba)
4062
4085
static int ufshcd_scsi_add_wlus (struct ufs_hba * hba )
4063
4086
{
4064
4087
int ret = 0 ;
4088
+ struct scsi_device * sdev_rpmb ;
4089
+ struct scsi_device * sdev_boot ;
4065
4090
4066
4091
hba -> sdev_ufs_device = __scsi_add_device (hba -> host , 0 , 0 ,
4067
4092
ufshcd_upiu_wlun_to_scsi_wlun (UFS_UPIU_UFS_DEVICE_WLUN ), NULL );
@@ -4070,56 +4095,33 @@ static int ufshcd_scsi_add_wlus(struct ufs_hba *hba)
4070
4095
hba -> sdev_ufs_device = NULL ;
4071
4096
goto out ;
4072
4097
}
4098
+ scsi_device_put (hba -> sdev_ufs_device );
4073
4099
4074
- hba -> sdev_boot = __scsi_add_device (hba -> host , 0 , 0 ,
4100
+ sdev_boot = __scsi_add_device (hba -> host , 0 , 0 ,
4075
4101
ufshcd_upiu_wlun_to_scsi_wlun (UFS_UPIU_BOOT_WLUN ), NULL );
4076
- if (IS_ERR (hba -> sdev_boot )) {
4077
- ret = PTR_ERR (hba -> sdev_boot );
4078
- hba -> sdev_boot = NULL ;
4102
+ if (IS_ERR (sdev_boot )) {
4103
+ ret = PTR_ERR (sdev_boot );
4079
4104
goto remove_sdev_ufs_device ;
4080
4105
}
4106
+ scsi_device_put (sdev_boot );
4081
4107
4082
- hba -> sdev_rpmb = __scsi_add_device (hba -> host , 0 , 0 ,
4108
+ sdev_rpmb = __scsi_add_device (hba -> host , 0 , 0 ,
4083
4109
ufshcd_upiu_wlun_to_scsi_wlun (UFS_UPIU_RPMB_WLUN ), NULL );
4084
- if (IS_ERR (hba -> sdev_rpmb )) {
4085
- ret = PTR_ERR (hba -> sdev_rpmb );
4086
- hba -> sdev_rpmb = NULL ;
4110
+ if (IS_ERR (sdev_rpmb )) {
4111
+ ret = PTR_ERR (sdev_rpmb );
4087
4112
goto remove_sdev_boot ;
4088
4113
}
4114
+ scsi_device_put (sdev_rpmb );
4089
4115
goto out ;
4090
4116
4091
4117
remove_sdev_boot :
4092
- scsi_remove_device (hba -> sdev_boot );
4118
+ scsi_remove_device (sdev_boot );
4093
4119
remove_sdev_ufs_device :
4094
4120
scsi_remove_device (hba -> sdev_ufs_device );
4095
4121
out :
4096
4122
return ret ;
4097
4123
}
4098
4124
4099
- /**
4100
- * ufshcd_scsi_remove_wlus - Removes the W-LUs which were added by
4101
- * ufshcd_scsi_add_wlus()
4102
- * @hba: per-adapter instance
4103
- *
4104
- */
4105
- static void ufshcd_scsi_remove_wlus (struct ufs_hba * hba )
4106
- {
4107
- if (hba -> sdev_ufs_device ) {
4108
- scsi_remove_device (hba -> sdev_ufs_device );
4109
- hba -> sdev_ufs_device = NULL ;
4110
- }
4111
-
4112
- if (hba -> sdev_boot ) {
4113
- scsi_remove_device (hba -> sdev_boot );
4114
- hba -> sdev_boot = NULL ;
4115
- }
4116
-
4117
- if (hba -> sdev_rpmb ) {
4118
- scsi_remove_device (hba -> sdev_rpmb );
4119
- hba -> sdev_rpmb = NULL ;
4120
- }
4121
- }
4122
-
4123
4125
/**
4124
4126
* ufshcd_probe_hba - probe hba to detect device and initialize
4125
4127
* @hba: per-adapter instance
@@ -4134,6 +4136,8 @@ static int ufshcd_probe_hba(struct ufs_hba *hba)
4134
4136
if (ret )
4135
4137
goto out ;
4136
4138
4139
+ ufshcd_init_pwr_info (hba );
4140
+
4137
4141
/* UniPro link is active now */
4138
4142
ufshcd_set_link_active (hba );
4139
4143
@@ -4264,12 +4268,18 @@ static int ufshcd_config_vreg_load(struct device *dev, struct ufs_vreg *vreg,
4264
4268
static inline int ufshcd_config_vreg_lpm (struct ufs_hba * hba ,
4265
4269
struct ufs_vreg * vreg )
4266
4270
{
4271
+ if (!vreg )
4272
+ return 0 ;
4273
+
4267
4274
return ufshcd_config_vreg_load (hba -> dev , vreg , UFS_VREG_LPM_LOAD_UA );
4268
4275
}
4269
4276
4270
4277
static inline int ufshcd_config_vreg_hpm (struct ufs_hba * hba ,
4271
4278
struct ufs_vreg * vreg )
4272
4279
{
4280
+ if (!vreg )
4281
+ return 0 ;
4282
+
4273
4283
return ufshcd_config_vreg_load (hba -> dev , vreg , vreg -> max_uA );
4274
4284
}
4275
4285
@@ -4471,7 +4481,7 @@ static int __ufshcd_setup_clocks(struct ufs_hba *hba, bool on,
4471
4481
if (!IS_ERR_OR_NULL (clki -> clk ) && clki -> enabled )
4472
4482
clk_disable_unprepare (clki -> clk );
4473
4483
}
4474
- } else if (! ret && on ) {
4484
+ } else if (on ) {
4475
4485
spin_lock_irqsave (hba -> host -> host_lock , flags );
4476
4486
hba -> clk_gating .state = CLKS_ON ;
4477
4487
spin_unlock_irqrestore (hba -> host -> host_lock , flags );
@@ -4675,11 +4685,25 @@ static int ufshcd_set_dev_pwr_mode(struct ufs_hba *hba,
4675
4685
{
4676
4686
unsigned char cmd [6 ] = { START_STOP };
4677
4687
struct scsi_sense_hdr sshdr ;
4678
- struct scsi_device * sdp = hba -> sdev_ufs_device ;
4688
+ struct scsi_device * sdp ;
4689
+ unsigned long flags ;
4679
4690
int ret ;
4680
4691
4681
- if (!sdp || !scsi_device_online (sdp ))
4682
- return - ENODEV ;
4692
+ spin_lock_irqsave (hba -> host -> host_lock , flags );
4693
+ sdp = hba -> sdev_ufs_device ;
4694
+ if (sdp ) {
4695
+ ret = scsi_device_get (sdp );
4696
+ if (!ret && !scsi_device_online (sdp )) {
4697
+ ret = - ENODEV ;
4698
+ scsi_device_put (sdp );
4699
+ }
4700
+ } else {
4701
+ ret = - ENODEV ;
4702
+ }
4703
+ spin_unlock_irqrestore (hba -> host -> host_lock , flags );
4704
+
4705
+ if (ret )
4706
+ return ret ;
4683
4707
4684
4708
/*
4685
4709
* If scsi commands fail, the scsi mid-layer schedules scsi error-
@@ -4718,6 +4742,7 @@ static int ufshcd_set_dev_pwr_mode(struct ufs_hba *hba,
4718
4742
if (!ret )
4719
4743
hba -> curr_dev_pwr_mode = pwr_mode ;
4720
4744
out :
4745
+ scsi_device_put (sdp );
4721
4746
hba -> host -> eh_noresume = 0 ;
4722
4747
return ret ;
4723
4748
}
@@ -5087,7 +5112,7 @@ int ufshcd_system_suspend(struct ufs_hba *hba)
5087
5112
int ret = 0 ;
5088
5113
5089
5114
if (!hba || !hba -> is_powered )
5090
- goto out ;
5115
+ return 0 ;
5091
5116
5092
5117
if (pm_runtime_suspended (hba -> dev )) {
5093
5118
if (hba -> rpm_lvl == hba -> spm_lvl )
@@ -5231,7 +5256,6 @@ EXPORT_SYMBOL(ufshcd_shutdown);
5231
5256
void ufshcd_remove (struct ufs_hba * hba )
5232
5257
{
5233
5258
scsi_remove_host (hba -> host );
5234
- ufshcd_scsi_remove_wlus (hba );
5235
5259
/* disable interrupts */
5236
5260
ufshcd_disable_intr (hba , hba -> intr_mask );
5237
5261
ufshcd_hba_stop (hba );
0 commit comments