Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

bus: mhi: core: Remove the system error worker thread

Remove the system error worker thread and instead have the
execution environment worker handle that transition to serialize
processing and avoid any possible race conditions during
shutdown.

Signed-off-by: Hemant Kumar <hemantk@codeaurora.org>
Reviewed-by: Jeffrey Hugo <jhugo@codeaurora.org>
Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
Link: https://lore.kernel.org/r/20200521170249.21795-10-manivannan.sadhasivam@linaro.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

authored by

Hemant Kumar and committed by
Greg Kroah-Hartman
bc7ccce5 0ab9fcd0

+20 -25
+1 -1
drivers/bus/mhi/core/init.c
··· 34 34 [DEV_ST_TRANSITION_READY] = "READY", 35 35 [DEV_ST_TRANSITION_SBL] = "SBL", 36 36 [DEV_ST_TRANSITION_MISSION_MODE] = "MISSION_MODE", 37 + [DEV_ST_TRANSITION_SYS_ERR] = "SYS_ERR", 37 38 }; 38 39 39 40 const char * const mhi_state_str[MHI_STATE_MAX] = { ··· 835 834 spin_lock_init(&mhi_cntrl->transition_lock); 836 835 spin_lock_init(&mhi_cntrl->wlock); 837 836 INIT_WORK(&mhi_cntrl->st_worker, mhi_pm_st_worker); 838 - INIT_WORK(&mhi_cntrl->syserr_worker, mhi_pm_sys_err_worker); 839 837 init_waitqueue_head(&mhi_cntrl->state_event); 840 838 841 839 mhi_cmd = mhi_cntrl->mhi_cmd;
+2 -1
drivers/bus/mhi/core/internal.h
··· 386 386 DEV_ST_TRANSITION_READY, 387 387 DEV_ST_TRANSITION_SBL, 388 388 DEV_ST_TRANSITION_MISSION_MODE, 389 + DEV_ST_TRANSITION_SYS_ERR, 389 390 DEV_ST_TRANSITION_MAX, 390 391 }; 391 392 ··· 588 587 int mhi_queue_state_transition(struct mhi_controller *mhi_cntrl, 589 588 enum dev_st_transition state); 590 589 void mhi_pm_st_worker(struct work_struct *work); 591 - void mhi_pm_sys_err_worker(struct work_struct *work); 590 + void mhi_pm_sys_err_handler(struct mhi_controller *mhi_cntrl); 592 591 void mhi_fw_load_worker(struct work_struct *work); 593 592 int mhi_ready_state_transition(struct mhi_controller *mhi_cntrl); 594 593 void mhi_ctrl_ev_task(unsigned long data);
+3 -3
drivers/bus/mhi/core/main.c
··· 406 406 if (MHI_IN_PBL(ee)) 407 407 mhi_cntrl->status_cb(mhi_cntrl, MHI_CB_FATAL_ERROR); 408 408 else 409 - schedule_work(&mhi_cntrl->syserr_worker); 409 + mhi_pm_sys_err_handler(mhi_cntrl); 410 410 } 411 411 412 412 exit_intvec: ··· 734 734 MHI_PM_SYS_ERR_DETECT); 735 735 write_unlock_irq(&mhi_cntrl->pm_lock); 736 736 if (new_state == MHI_PM_SYS_ERR_DETECT) 737 - schedule_work(&mhi_cntrl->syserr_worker); 737 + mhi_pm_sys_err_handler(mhi_cntrl); 738 738 break; 739 739 } 740 740 default: ··· 920 920 } 921 921 write_unlock_irq(&mhi_cntrl->pm_lock); 922 922 if (pm_state == MHI_PM_SYS_ERR_DETECT) 923 - schedule_work(&mhi_cntrl->syserr_worker); 923 + mhi_pm_sys_err_handler(mhi_cntrl); 924 924 } 925 925 } 926 926
+14 -18
drivers/bus/mhi/core/pm.c
··· 449 449 to_mhi_pm_state_str(transition_state)); 450 450 451 451 /* We must notify MHI control driver so it can clean up first */ 452 - if (transition_state == MHI_PM_SYS_ERR_PROCESS) { 453 - /* 454 - * If controller supports RDDM, we do not process 455 - * SYS error state, instead we will jump directly 456 - * to RDDM state 457 - */ 458 - if (mhi_cntrl->rddm_image) { 459 - dev_dbg(dev, 460 - "Controller supports RDDM, so skip SYS_ERR\n"); 461 - return; 462 - } 452 + if (transition_state == MHI_PM_SYS_ERR_PROCESS) 463 453 mhi_cntrl->status_cb(mhi_cntrl, MHI_CB_SYS_ERROR); 464 - } 465 454 466 455 mutex_lock(&mhi_cntrl->pm_mutex); 467 456 write_lock_irq(&mhi_cntrl->pm_lock); ··· 516 527 mutex_unlock(&mhi_cntrl->pm_mutex); 517 528 dev_dbg(dev, "Waiting for all pending threads to complete\n"); 518 529 wake_up_all(&mhi_cntrl->state_event); 519 - flush_work(&mhi_cntrl->st_worker); 520 530 521 531 dev_dbg(dev, "Reset all active channels and remove MHI devices\n"); 522 532 device_for_each_child(mhi_cntrl->cntrl_dev, NULL, mhi_destroy_device); ··· 595 607 } 596 608 597 609 /* SYS_ERR worker */ 598 - void mhi_pm_sys_err_worker(struct work_struct *work) 610 + void mhi_pm_sys_err_handler(struct mhi_controller *mhi_cntrl) 599 611 { 600 - struct mhi_controller *mhi_cntrl = container_of(work, 601 - struct mhi_controller, 602 - syserr_worker); 612 + struct device *dev = &mhi_cntrl->mhi_dev->dev; 603 613 604 - mhi_pm_disable_transition(mhi_cntrl, MHI_PM_SYS_ERR_PROCESS); 614 + /* skip if controller supports RDDM */ 615 + if (mhi_cntrl->rddm_image) { 616 + dev_dbg(dev, "Controller supports RDDM, skip SYS_ERROR\n"); 617 + return; 618 + } 619 + 620 + mhi_queue_state_transition(mhi_cntrl, DEV_ST_TRANSITION_SYS_ERR); 605 621 } 606 622 607 623 /* Device State Transition worker */ ··· 652 660 break; 653 661 case DEV_ST_TRANSITION_READY: 654 662 mhi_ready_state_transition(mhi_cntrl); 663 + break; 664 + case DEV_ST_TRANSITION_SYS_ERR: 665 + mhi_pm_disable_transition 666 + (mhi_cntrl, MHI_PM_SYS_ERR_PROCESS); 655 667 break; 656 668 default: 657 669 break;
-2
include/linux/mhi.h
··· 331 331 * @wlock: Lock for protecting device wakeup 332 332 * @mhi_link_info: Device bandwidth info 333 333 * @st_worker: State transition worker 334 - * @syserr_worker: System error worker 335 334 * @state_event: State change event 336 335 * @status_cb: CB function to notify power states of the device (required) 337 336 * @wake_get: CB function to assert device wake (optional) ··· 410 411 spinlock_t wlock; 411 412 struct mhi_link_info mhi_link_info; 412 413 struct work_struct st_worker; 413 - struct work_struct syserr_worker; 414 414 wait_queue_head_t state_event; 415 415 416 416 void (*status_cb)(struct mhi_controller *mhi_cntrl,