@@ -1627,12 +1627,12 @@ int ufshcd_hold(struct ufs_hba *hba, bool async)
16271627 */
16281628 fallthrough ;
16291629 case CLKS_OFF :
1630- ufshcd_scsi_block_requests (hba );
16311630 hba -> clk_gating .state = REQ_CLKS_ON ;
16321631 trace_ufshcd_clk_gating (dev_name (hba -> dev ),
16331632 hba -> clk_gating .state );
1634- queue_work (hba -> clk_gating .clk_gating_workq ,
1635- & hba -> clk_gating .ungate_work );
1633+ if (queue_work (hba -> clk_gating .clk_gating_workq ,
1634+ & hba -> clk_gating .ungate_work ))
1635+ ufshcd_scsi_block_requests (hba );
16361636 /*
16371637 * fall through to check if we should wait for this
16381638 * work to be done or not.
@@ -2115,10 +2115,20 @@ ufshcd_wait_for_uic_cmd(struct ufs_hba *hba, struct uic_command *uic_cmd)
21152115 unsigned long flags ;
21162116
21172117 if (wait_for_completion_timeout (& uic_cmd -> done ,
2118- msecs_to_jiffies (UIC_CMD_TIMEOUT )))
2118+ msecs_to_jiffies (UIC_CMD_TIMEOUT ))) {
21192119 ret = uic_cmd -> argument2 & MASK_UIC_COMMAND_RESULT ;
2120- else
2120+ } else {
21212121 ret = - ETIMEDOUT ;
2122+ dev_err (hba -> dev ,
2123+ "uic cmd 0x%x with arg3 0x%x completion timeout\n" ,
2124+ uic_cmd -> command , uic_cmd -> argument3 );
2125+
2126+ if (!uic_cmd -> cmd_active ) {
2127+ dev_err (hba -> dev , "%s: UIC cmd has been completed, return the result\n" ,
2128+ __func__ );
2129+ ret = uic_cmd -> argument2 & MASK_UIC_COMMAND_RESULT ;
2130+ }
2131+ }
21222132
21232133 spin_lock_irqsave (hba -> host -> host_lock , flags );
21242134 hba -> active_uic_cmd = NULL ;
@@ -2150,6 +2160,7 @@ __ufshcd_send_uic_cmd(struct ufs_hba *hba, struct uic_command *uic_cmd,
21502160 if (completion )
21512161 init_completion (& uic_cmd -> done );
21522162
2163+ uic_cmd -> cmd_active = 1 ;
21532164 ufshcd_dispatch_uic_cmd (hba , uic_cmd );
21542165
21552166 return 0 ;
@@ -3807,10 +3818,18 @@ static int ufshcd_uic_pwr_ctrl(struct ufs_hba *hba, struct uic_command *cmd)
38073818 dev_err (hba -> dev ,
38083819 "pwr ctrl cmd 0x%x with mode 0x%x completion timeout\n" ,
38093820 cmd -> command , cmd -> argument3 );
3821+
3822+ if (!cmd -> cmd_active ) {
3823+ dev_err (hba -> dev , "%s: Power Mode Change operation has been completed, go check UPMCRS\n" ,
3824+ __func__ );
3825+ goto check_upmcrs ;
3826+ }
3827+
38103828 ret = - ETIMEDOUT ;
38113829 goto out ;
38123830 }
38133831
3832+ check_upmcrs :
38143833 status = ufshcd_get_upmcrs (hba );
38153834 if (status != PWR_LOCAL ) {
38163835 dev_err (hba -> dev ,
@@ -4902,11 +4921,14 @@ static irqreturn_t ufshcd_uic_cmd_compl(struct ufs_hba *hba, u32 intr_status)
49024921 ufshcd_get_uic_cmd_result (hba );
49034922 hba -> active_uic_cmd -> argument3 =
49044923 ufshcd_get_dme_attr_val (hba );
4924+ if (!hba -> uic_async_done )
4925+ hba -> active_uic_cmd -> cmd_active = 0 ;
49054926 complete (& hba -> active_uic_cmd -> done );
49064927 retval = IRQ_HANDLED ;
49074928 }
49084929
49094930 if ((intr_status & UFSHCD_UIC_PWR_MASK ) && hba -> uic_async_done ) {
4931+ hba -> active_uic_cmd -> cmd_active = 0 ;
49104932 complete (hba -> uic_async_done );
49114933 retval = IRQ_HANDLED ;
49124934 }
@@ -8906,6 +8928,7 @@ void ufshcd_remove(struct ufs_hba *hba)
89068928 blk_mq_free_tag_set (& hba -> tmf_tag_set );
89078929 blk_cleanup_queue (hba -> cmd_queue );
89088930 scsi_remove_host (hba -> host );
8931+ destroy_workqueue (hba -> eh_wq );
89098932 /* disable interrupts */
89108933 ufshcd_disable_intr (hba , hba -> intr_mask );
89118934 ufshcd_hba_stop (hba );
@@ -9206,6 +9229,7 @@ int ufshcd_init(struct ufs_hba *hba, void __iomem *mmio_base, unsigned int irq)
92069229exit_gating :
92079230 ufshcd_exit_clk_scaling (hba );
92089231 ufshcd_exit_clk_gating (hba );
9232+ destroy_workqueue (hba -> eh_wq );
92099233out_disable :
92109234 hba -> is_irq_enabled = false;
92119235 ufshcd_hba_exit (hba );
0 commit comments