Loading drivers/scsi/ufs/ufshcd.c +21 −6 Original line number Diff line number Diff line Loading @@ -5261,7 +5261,7 @@ static int ufshcd_link_recovery(struct ufs_hba *hba) hba->ufshcd_state = UFSHCD_STATE_ERROR; hba->force_host_reset = true; ufshcd_set_eh_in_progress(hba); schedule_work(&hba->eh_work); queue_work(hba->recovery_wq, &hba->eh_work); /* wait for the reset work to finish */ do { Loading Loading @@ -6299,7 +6299,8 @@ ufshcd_transfer_rsp_status(struct ufs_hba *hba, struct ufshcd_lrb *lrbp) * to avoid deadlock between ufshcd_suspend * and exception event handler. */ if (schedule_work(&hba->eeh_work)) if (queue_work(hba->recovery_wq, &hba->eeh_work)) pm_runtime_get_noresume(hba->dev); } break; Loading Loading @@ -6408,7 +6409,7 @@ static irqreturn_t ufshcd_uic_cmd_compl(struct ufs_hba *hba, u32 intr_status) * to printout the debug messages. */ hba->auto_h8_err = true; schedule_work(&hba->eh_work); queue_work(hba->recovery_wq, &hba->eh_work); retval = IRQ_HANDLED; } } Loading Loading @@ -7428,7 +7429,7 @@ static irqreturn_t ufshcd_update_uic_error(struct ufs_hba *hba) } } if (!hba->full_init_linereset) schedule_work(&hba->rls_work); queue_work(hba->recovery_wq, &hba->rls_work); } retval |= IRQ_HANDLED; } Loading Loading @@ -7534,7 +7535,7 @@ static irqreturn_t ufshcd_check_errors(struct ufs_hba *hba) hba->ufshcd_state = UFSHCD_STATE_EH_SCHEDULED; schedule_work(&hba->eh_work); queue_work(hba->recovery_wq, &hba->eh_work); } retval |= IRQ_HANDLED; } Loading Loading @@ -8172,7 +8173,7 @@ static int ufshcd_eh_host_reset_handler(struct scsi_cmnd *cmd) */ hba->ufshcd_state = UFSHCD_STATE_ERROR; hba->force_host_reset = true; schedule_work(&hba->eh_work); queue_work(hba->recovery_wq, &hba->eh_work); /* wait for the reset work to finish */ do { Loading Loading @@ -9936,6 +9937,9 @@ static void ufshcd_hba_exit(struct ufs_hba *hba) destroy_workqueue(hba->clk_scaling.workq); ufshcd_devfreq_remove(hba); } if (hba->recovery_wq) destroy_workqueue(hba->recovery_wq); ufshcd_disable_clocks(hba, false); ufshcd_setup_hba_vreg(hba, false); hba->is_powered = false; Loading Loading @@ -10845,6 +10849,7 @@ int ufshcd_init(struct ufs_hba *hba, void __iomem *mmio_base, unsigned int irq) int err; struct Scsi_Host *host = hba->host; struct device *dev = hba->dev; char recovery_wq_name[sizeof("ufs_recovery_00")]; if (!mmio_base) { dev_err(hba->dev, Loading Loading @@ -10916,6 +10921,16 @@ int ufshcd_init(struct ufs_hba *hba, void __iomem *mmio_base, unsigned int irq) init_waitqueue_head(&hba->tm_tag_wq); /* Initialize work queues */ snprintf(recovery_wq_name, ARRAY_SIZE(recovery_wq_name), "%s_%d", "ufs_recovery_wq", host->host_no); hba->recovery_wq = create_singlethread_workqueue(recovery_wq_name); if (!hba->recovery_wq) { dev_err(hba->dev, "%s: failed to create the workqueue\n", __func__); err = -ENOMEM; goto out_disable; } INIT_WORK(&hba->eh_work, ufshcd_err_handler); INIT_WORK(&hba->eeh_work, ufshcd_exception_event_handler); INIT_WORK(&hba->rls_work, ufshcd_rls_handler); Loading drivers/scsi/ufs/ufshcd.h +2 −0 Original line number Diff line number Diff line Loading @@ -745,6 +745,7 @@ struct ufshcd_cmd_log { * @intr_mask: Interrupt Mask Bits * @ee_ctrl_mask: Exception event control mask * @is_powered: flag to check if HBA is powered * @recovery_wq: Work queue for all recovery workers * @eh_work: Worker to handle UFS errors that require s/w attention * @eeh_work: Worker to handle exception events * @errors: HBA errors Loading Loading @@ -941,6 +942,7 @@ struct ufs_hba { bool is_powered; /* Work Queues */ struct workqueue_struct *recovery_wq; struct work_struct eh_work; struct work_struct eeh_work; struct work_struct rls_work; Loading Loading
drivers/scsi/ufs/ufshcd.c +21 −6 Original line number Diff line number Diff line Loading @@ -5261,7 +5261,7 @@ static int ufshcd_link_recovery(struct ufs_hba *hba) hba->ufshcd_state = UFSHCD_STATE_ERROR; hba->force_host_reset = true; ufshcd_set_eh_in_progress(hba); schedule_work(&hba->eh_work); queue_work(hba->recovery_wq, &hba->eh_work); /* wait for the reset work to finish */ do { Loading Loading @@ -6299,7 +6299,8 @@ ufshcd_transfer_rsp_status(struct ufs_hba *hba, struct ufshcd_lrb *lrbp) * to avoid deadlock between ufshcd_suspend * and exception event handler. */ if (schedule_work(&hba->eeh_work)) if (queue_work(hba->recovery_wq, &hba->eeh_work)) pm_runtime_get_noresume(hba->dev); } break; Loading Loading @@ -6408,7 +6409,7 @@ static irqreturn_t ufshcd_uic_cmd_compl(struct ufs_hba *hba, u32 intr_status) * to printout the debug messages. */ hba->auto_h8_err = true; schedule_work(&hba->eh_work); queue_work(hba->recovery_wq, &hba->eh_work); retval = IRQ_HANDLED; } } Loading Loading @@ -7428,7 +7429,7 @@ static irqreturn_t ufshcd_update_uic_error(struct ufs_hba *hba) } } if (!hba->full_init_linereset) schedule_work(&hba->rls_work); queue_work(hba->recovery_wq, &hba->rls_work); } retval |= IRQ_HANDLED; } Loading Loading @@ -7534,7 +7535,7 @@ static irqreturn_t ufshcd_check_errors(struct ufs_hba *hba) hba->ufshcd_state = UFSHCD_STATE_EH_SCHEDULED; schedule_work(&hba->eh_work); queue_work(hba->recovery_wq, &hba->eh_work); } retval |= IRQ_HANDLED; } Loading Loading @@ -8172,7 +8173,7 @@ static int ufshcd_eh_host_reset_handler(struct scsi_cmnd *cmd) */ hba->ufshcd_state = UFSHCD_STATE_ERROR; hba->force_host_reset = true; schedule_work(&hba->eh_work); queue_work(hba->recovery_wq, &hba->eh_work); /* wait for the reset work to finish */ do { Loading Loading @@ -9936,6 +9937,9 @@ static void ufshcd_hba_exit(struct ufs_hba *hba) destroy_workqueue(hba->clk_scaling.workq); ufshcd_devfreq_remove(hba); } if (hba->recovery_wq) destroy_workqueue(hba->recovery_wq); ufshcd_disable_clocks(hba, false); ufshcd_setup_hba_vreg(hba, false); hba->is_powered = false; Loading Loading @@ -10845,6 +10849,7 @@ int ufshcd_init(struct ufs_hba *hba, void __iomem *mmio_base, unsigned int irq) int err; struct Scsi_Host *host = hba->host; struct device *dev = hba->dev; char recovery_wq_name[sizeof("ufs_recovery_00")]; if (!mmio_base) { dev_err(hba->dev, Loading Loading @@ -10916,6 +10921,16 @@ int ufshcd_init(struct ufs_hba *hba, void __iomem *mmio_base, unsigned int irq) init_waitqueue_head(&hba->tm_tag_wq); /* Initialize work queues */ snprintf(recovery_wq_name, ARRAY_SIZE(recovery_wq_name), "%s_%d", "ufs_recovery_wq", host->host_no); hba->recovery_wq = create_singlethread_workqueue(recovery_wq_name); if (!hba->recovery_wq) { dev_err(hba->dev, "%s: failed to create the workqueue\n", __func__); err = -ENOMEM; goto out_disable; } INIT_WORK(&hba->eh_work, ufshcd_err_handler); INIT_WORK(&hba->eeh_work, ufshcd_exception_event_handler); INIT_WORK(&hba->rls_work, ufshcd_rls_handler); Loading
drivers/scsi/ufs/ufshcd.h +2 −0 Original line number Diff line number Diff line Loading @@ -745,6 +745,7 @@ struct ufshcd_cmd_log { * @intr_mask: Interrupt Mask Bits * @ee_ctrl_mask: Exception event control mask * @is_powered: flag to check if HBA is powered * @recovery_wq: Work queue for all recovery workers * @eh_work: Worker to handle UFS errors that require s/w attention * @eeh_work: Worker to handle exception events * @errors: HBA errors Loading Loading @@ -941,6 +942,7 @@ struct ufs_hba { bool is_powered; /* Work Queues */ struct workqueue_struct *recovery_wq; struct work_struct eh_work; struct work_struct eeh_work; struct work_struct rls_work; Loading