Message ID | 20171109091633.2433-1-michalx.potomski@intel.com (mailing list archive) |
---|---|
State | Changes Requested |
Headers | show |
Hi Michał, Thank you for the patch! Yet something to improve: [auto build test ERROR on scsi/for-next] [also build test ERROR on v4.14-rc8 next-20171109] [if your patch is applied to the wrong git tree, please drop us a note to help improve the system] url: https://github.com/0day-ci/linux/commits/Michal-Potomski/scsi-ufs-Fix-Runtime-PM/20171110-191314 base: https://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi.git for-next config: m68k-allyesconfig (attached as .config) compiler: m68k-linux-gnu-gcc (Debian 7.2.0-11) 7.2.0 reproduce: wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross # save the attached .config to linux build tree make.cross ARCH=m68k All errors (new ones prefixed by >>): drivers/scsi/ufs/ufshcd.c: In function 'ufshcd_pm_runtime_get': >> drivers/scsi/ufs/ufshcd.c:246:16: error: 'struct dev_pm_info' has no member named 'runtime_status' if (dev->power.runtime_status == RPM_RESUMING || ^ drivers/scsi/ufs/ufshcd.c:247:16: error: 'struct dev_pm_info' has no member named 'runtime_status' dev->power.runtime_status == RPM_SUSPENDING) ^ drivers/scsi/ufs/ufshcd.c: In function 'ufshcd_pm_runtime_put': drivers/scsi/ufs/ufshcd.c:258:16: error: 'struct dev_pm_info' has no member named 'runtime_status' if (dev->power.runtime_status == RPM_RESUMING || ^ drivers/scsi/ufs/ufshcd.c:259:16: error: 'struct dev_pm_info' has no member named 'runtime_status' dev->power.runtime_status == RPM_SUSPENDING) ^ vim +246 drivers/scsi/ufs/ufshcd.c 242 243 static void ufshcd_pm_runtime_get(struct device *dev) 244 { 245 // Don't trigger PM events while in transition states > 246 if (dev->power.runtime_status == RPM_RESUMING || 247 dev->power.runtime_status == RPM_SUSPENDING) 248 pm_runtime_get_noresume(dev); 249 else 250 pm_runtime_get_sync(dev); 251 } 252 --- 0-DAY kernel test infrastructure Open Source Technology Center https://lists.01.org/pipermail/kbuild-all Intel Corporation
Hi Michał, Thank you for the patch! Perhaps something to improve: [auto build test WARNING on scsi/for-next] [also build test WARNING on v4.14-rc8 next-20171109] [if your patch is applied to the wrong git tree, please drop us a note to help improve the system] url: https://github.com/0day-ci/linux/commits/Michal-Potomski/scsi-ufs-Fix-Runtime-PM/20171110-191314 base: https://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi.git for-next config: x86_64-randconfig-v0-11102116 (attached as .config) compiler: gcc-6 (Debian 6.4.0-9) 6.4.0 20171026 reproduce: # save the attached .config to linux build tree make ARCH=x86_64 All warnings (new ones prefixed by >>): In file included from include/uapi/linux/stddef.h:1:0, from include/linux/stddef.h:4, from include/uapi/linux/posix_types.h:4, from include/uapi/linux/types.h:13, from include/linux/types.h:5, from include/linux/async.h:15, from drivers/scsi/ufs/ufshcd.c:40: drivers/scsi/ufs/ufshcd.c: In function 'ufshcd_pm_runtime_get': drivers/scsi/ufs/ufshcd.c:246:16: error: 'struct dev_pm_info' has no member named 'runtime_status' if (dev->power.runtime_status == RPM_RESUMING || ^ include/linux/compiler.h:156:30: note: in definition of macro '__trace_if' if (__builtin_constant_p(!!(cond)) ? !!(cond) : \ ^~~~ >> drivers/scsi/ufs/ufshcd.c:246:2: note: in expansion of macro 'if' if (dev->power.runtime_status == RPM_RESUMING || ^~ drivers/scsi/ufs/ufshcd.c:247:16: error: 'struct dev_pm_info' has no member named 'runtime_status' dev->power.runtime_status == RPM_SUSPENDING) ^ include/linux/compiler.h:156:30: note: in definition of macro '__trace_if' if (__builtin_constant_p(!!(cond)) ? !!(cond) : \ ^~~~ >> drivers/scsi/ufs/ufshcd.c:246:2: note: in expansion of macro 'if' if (dev->power.runtime_status == RPM_RESUMING || ^~ drivers/scsi/ufs/ufshcd.c:246:16: error: 'struct dev_pm_info' has no member named 'runtime_status' if (dev->power.runtime_status == RPM_RESUMING || ^ include/linux/compiler.h:156:42: note: in definition of macro '__trace_if' if (__builtin_constant_p(!!(cond)) ? !!(cond) : \ ^~~~ >> drivers/scsi/ufs/ufshcd.c:246:2: note: in expansion of macro 'if' if (dev->power.runtime_status == RPM_RESUMING || ^~ drivers/scsi/ufs/ufshcd.c:247:16: error: 'struct dev_pm_info' has no member named 'runtime_status' dev->power.runtime_status == RPM_SUSPENDING) ^ include/linux/compiler.h:156:42: note: in definition of macro '__trace_if' if (__builtin_constant_p(!!(cond)) ? !!(cond) : \ ^~~~ >> drivers/scsi/ufs/ufshcd.c:246:2: note: in expansion of macro 'if' if (dev->power.runtime_status == RPM_RESUMING || ^~ drivers/scsi/ufs/ufshcd.c:246:16: error: 'struct dev_pm_info' has no member named 'runtime_status' if (dev->power.runtime_status == RPM_RESUMING || ^ include/linux/compiler.h:167:16: note: in definition of macro '__trace_if' ______r = !!(cond); \ ^~~~ >> drivers/scsi/ufs/ufshcd.c:246:2: note: in expansion of macro 'if' if (dev->power.runtime_status == RPM_RESUMING || ^~ drivers/scsi/ufs/ufshcd.c:247:16: error: 'struct dev_pm_info' has no member named 'runtime_status' dev->power.runtime_status == RPM_SUSPENDING) ^ include/linux/compiler.h:167:16: note: in definition of macro '__trace_if' ______r = !!(cond); \ ^~~~ >> drivers/scsi/ufs/ufshcd.c:246:2: note: in expansion of macro 'if' if (dev->power.runtime_status == RPM_RESUMING || ^~ drivers/scsi/ufs/ufshcd.c: In function 'ufshcd_pm_runtime_put': drivers/scsi/ufs/ufshcd.c:258:16: error: 'struct dev_pm_info' has no member named 'runtime_status' if (dev->power.runtime_status == RPM_RESUMING || ^ include/linux/compiler.h:156:30: note: in definition of macro '__trace_if' if (__builtin_constant_p(!!(cond)) ? !!(cond) : \ ^~~~ drivers/scsi/ufs/ufshcd.c:258:2: note: in expansion of macro 'if' if (dev->power.runtime_status == RPM_RESUMING || ^~ drivers/scsi/ufs/ufshcd.c:259:16: error: 'struct dev_pm_info' has no member named 'runtime_status' dev->power.runtime_status == RPM_SUSPENDING) ^ include/linux/compiler.h:156:30: note: in definition of macro '__trace_if' if (__builtin_constant_p(!!(cond)) ? !!(cond) : \ ^~~~ drivers/scsi/ufs/ufshcd.c:258:2: note: in expansion of macro 'if' if (dev->power.runtime_status == RPM_RESUMING || ^~ drivers/scsi/ufs/ufshcd.c:258:16: error: 'struct dev_pm_info' has no member named 'runtime_status' if (dev->power.runtime_status == RPM_RESUMING || ^ include/linux/compiler.h:156:42: note: in definition of macro '__trace_if' if (__builtin_constant_p(!!(cond)) ? !!(cond) : \ ^~~~ drivers/scsi/ufs/ufshcd.c:258:2: note: in expansion of macro 'if' if (dev->power.runtime_status == RPM_RESUMING || ^~ drivers/scsi/ufs/ufshcd.c:259:16: error: 'struct dev_pm_info' has no member named 'runtime_status' dev->power.runtime_status == RPM_SUSPENDING) ^ include/linux/compiler.h:156:42: note: in definition of macro '__trace_if' if (__builtin_constant_p(!!(cond)) ? !!(cond) : \ ^~~~ drivers/scsi/ufs/ufshcd.c:258:2: note: in expansion of macro 'if' if (dev->power.runtime_status == RPM_RESUMING || ^~ drivers/scsi/ufs/ufshcd.c:258:16: error: 'struct dev_pm_info' has no member named 'runtime_status' if (dev->power.runtime_status == RPM_RESUMING || ^ include/linux/compiler.h:167:16: note: in definition of macro '__trace_if' ______r = !!(cond); \ ^~~~ drivers/scsi/ufs/ufshcd.c:258:2: note: in expansion of macro 'if' if (dev->power.runtime_status == RPM_RESUMING || ^~ drivers/scsi/ufs/ufshcd.c:259:16: error: 'struct dev_pm_info' has no member named 'runtime_status' dev->power.runtime_status == RPM_SUSPENDING) ^ include/linux/compiler.h:167:16: note: in definition of macro '__trace_if' ______r = !!(cond); \ ^~~~ drivers/scsi/ufs/ufshcd.c:258:2: note: in expansion of macro 'if' if (dev->power.runtime_status == RPM_RESUMING || ^~ vim +/if +246 drivers/scsi/ufs/ufshcd.c 242 243 static void ufshcd_pm_runtime_get(struct device *dev) 244 { 245 // Don't trigger PM events while in transition states > 246 if (dev->power.runtime_status == RPM_RESUMING || 247 dev->power.runtime_status == RPM_SUSPENDING) 248 pm_runtime_get_noresume(dev); 249 else 250 pm_runtime_get_sync(dev); 251 } 252 --- 0-DAY kernel test infrastructure Open Source Technology Center https://lists.01.org/pipermail/kbuild-all Intel Corporation
> -----Original Message----- > From: linux-scsi-owner@vger.kernel.org [mailto:linux-scsi- > owner@vger.kernel.org] On Behalf Of Michal Potomski > Sent: Thursday, November 09, 2017 11:17 AM > To: linux-scsi@vger.kernel.org > Cc: vinholikatti@gmail.com; martin.petersen@oracle.com; > jejb@linux.vnet.ibm.com; subhashj@codeaurora.org; > szymonx.mielczarek@intel.com > Subject: [PATCH] scsi: ufs: Fix Runtime PM > > From: Michał Potomski <michalx.potomski@intel.com> > > Recent testing of Runtime PM for UFS has shown it's not working as intended. > To acheive fully working Runtime PM, first we have to put back scsi_device > autopm reference counter. > > Existing implementation was prone to races and not working for tranfsers to > sleeping devices. Wouldn't calling pm_runtime_mark_last_busy() just before pm_runtime_put_autosuspend() suffice? This commit aims to fix this to acheive fully working > environment. Due to runtime PM being previously disabled by not putting > scsi_device autopm counter, the Runtime PM is set to be forbidden as > default, to not cause problems with hosts and devices, which do not fully > support different Device and Link states. > > It can be still enabled through sysFS power/control attribute. > > Signed-off-by: Michał Potomski <michalx.potomski@intel.com> > --- > drivers/scsi/ufs/ufshcd-pci.c | 4 +++- > drivers/scsi/ufs/ufshcd.c | 55 ++++++++++++++++++++++++++++++++++------- > -- > 2 files changed, 47 insertions(+), 12 deletions(-) > > diff --git a/drivers/scsi/ufs/ufshcd-pci.c b/drivers/scsi/ufs/ufshcd-pci.c index > 925b0ec7ec54..4fffb1123876 100644 > --- a/drivers/scsi/ufs/ufshcd-pci.c > +++ b/drivers/scsi/ufs/ufshcd-pci.c > @@ -184,8 +184,10 @@ ufshcd_pci_probe(struct pci_dev *pdev, const struct > pci_device_id *id) > } > > pci_set_drvdata(pdev, hba); > + pm_runtime_set_autosuspend_delay(&pdev->dev, 3000); > + pm_runtime_use_autosuspend(&pdev->dev); > pm_runtime_put_noidle(&pdev->dev); > - pm_runtime_allow(&pdev->dev); > + pm_runtime_forbid(&pdev->dev); > > return 0; > } > diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index > 011c3369082c..e7c7ed9bf8a5 100644 > --- a/drivers/scsi/ufs/ufshcd.c > +++ b/drivers/scsi/ufs/ufshcd.c > @@ -240,6 +240,28 @@ static inline bool ufshcd_valid_tag(struct ufs_hba > *hba, int tag) > return tag >= 0 && tag < hba->nutrs; > } > > +static void ufshcd_pm_runtime_get(struct device *dev) { > + // Don't trigger PM events while in transition states > + if (dev->power.runtime_status == RPM_RESUMING || > + dev->power.runtime_status == RPM_SUSPENDING) > + pm_runtime_get_noresume(dev); > + else > + pm_runtime_get_sync(dev); > +} > + > +static void ufshcd_pm_runtime_put(struct device *dev) { > + pm_runtime_mark_last_busy(dev); > + > + // Don't trigger PM events while in transition states > + if (dev->power.runtime_status == RPM_RESUMING || > + dev->power.runtime_status == RPM_SUSPENDING) > + pm_runtime_put_noidle(dev); > + else > + pm_runtime_put_autosuspend(dev); > +} > + > static inline int ufshcd_enable_irq(struct ufs_hba *hba) { > int ret = 0; > @@ -1345,7 +1367,7 @@ static ssize_t ufshcd_clkscale_enable_store(struct > device *dev, > if (value == hba->clk_scaling.is_allowed) > goto out; > > - pm_runtime_get_sync(hba->dev); > + ufshcd_pm_runtime_get(hba->dev); > ufshcd_hold(hba, false); > > cancel_work_sync(&hba->clk_scaling.suspend_work); > @@ -1364,7 +1386,7 @@ static ssize_t ufshcd_clkscale_enable_store(struct > device *dev, > } > > ufshcd_release(hba); > - pm_runtime_put_sync(hba->dev); > + ufshcd_pm_runtime_put(hba->dev); > out: > return count; > } > @@ -1948,6 +1970,7 @@ ufshcd_send_uic_cmd(struct ufs_hba *hba, struct > uic_command *uic_cmd) > unsigned long flags; > > ufshcd_hold(hba, false); > + ufshcd_pm_runtime_get(hba->dev); > mutex_lock(&hba->uic_cmd_mutex); > ufshcd_add_delay_before_dme_cmd(hba); > > @@ -1959,6 +1982,7 @@ ufshcd_send_uic_cmd(struct ufs_hba *hba, struct > uic_command *uic_cmd) > > mutex_unlock(&hba->uic_cmd_mutex); > > + ufshcd_pm_runtime_put(hba->dev); > ufshcd_release(hba); > return ret; > } > @@ -2345,6 +2369,7 @@ static int ufshcd_queuecommand(struct Scsi_Host > *host, struct scsi_cmnd *cmd) > clear_bit_unlock(tag, &hba->lrb_in_use); > goto out; > } > + ufshcd_pm_runtime_get(hba->dev); > WARN_ON(hba->clk_gating.state != CLKS_ON); > > lrbp = &hba->lrb[tag]; > @@ -3555,6 +3580,7 @@ static int ufshcd_uic_pwr_ctrl(struct ufs_hba *hba, > struct uic_command *cmd) > int ret; > bool reenable_intr = false; > > + ufshcd_pm_runtime_get(hba->dev); > mutex_lock(&hba->uic_cmd_mutex); > init_completion(&uic_async_done); > ufshcd_add_delay_before_dme_cmd(hba); > @@ -3609,6 +3635,7 @@ static int ufshcd_uic_pwr_ctrl(struct ufs_hba *hba, > struct uic_command *cmd) > ufshcd_enable_intr(hba, UIC_COMMAND_COMPL); > spin_unlock_irqrestore(hba->host->host_lock, flags); > mutex_unlock(&hba->uic_cmd_mutex); > + ufshcd_pm_runtime_put(hba->dev); > > return ret; > } > @@ -4386,6 +4413,7 @@ static int ufshcd_slave_configure(struct scsi_device > *sdev) > > blk_queue_update_dma_pad(q, PRDT_DATA_BYTE_COUNT_PAD - 1); > blk_queue_max_segment_size(q, PRDT_DATA_BYTE_COUNT_MAX); > + scsi_autopm_put_device(sdev); > > return 0; > } > @@ -4622,6 +4650,7 @@ static void __ufshcd_transfer_req_compl(struct > ufs_hba *hba, > /* Do not touch lrbp after scsi done */ > cmd->scsi_done(cmd); > __ufshcd_release(hba); > + ufshcd_pm_runtime_put(hba->dev); > } else if (lrbp->command_type == > UTP_CMD_TYPE_DEV_MANAGE || > lrbp->command_type == > UTP_CMD_TYPE_UFS_STORAGE) { > if (hba->dev_cmd.complete) { > @@ -4951,7 +4980,7 @@ static void ufshcd_exception_event_handler(struct > work_struct *work) > u32 status = 0; > hba = container_of(work, struct ufs_hba, eeh_work); > > - pm_runtime_get_sync(hba->dev); > + ufshcd_pm_runtime_get(hba->dev); > err = ufshcd_get_ee_status(hba, &status); > if (err) { > dev_err(hba->dev, "%s: failed to get exception status %d\n", > @@ -4965,7 +4994,7 @@ static void ufshcd_exception_event_handler(struct > work_struct *work) > ufshcd_bkops_exception_event_handler(hba); > > out: > - pm_runtime_put_sync(hba->dev); > + ufshcd_pm_runtime_put(hba->dev); > return; > } > > @@ -5065,7 +5094,7 @@ static void ufshcd_err_handler(struct work_struct > *work) > > hba = container_of(work, struct ufs_hba, eh_work); > > - pm_runtime_get_sync(hba->dev); > + ufshcd_pm_runtime_get(hba->dev); > ufshcd_hold(hba, false); > > spin_lock_irqsave(hba->host->host_lock, flags); @@ -5177,7 +5206,7 > @@ static void ufshcd_err_handler(struct work_struct *work) > spin_unlock_irqrestore(hba->host->host_lock, flags); > scsi_unblock_requests(hba->host); > ufshcd_release(hba); > - pm_runtime_put_sync(hba->dev); > + ufshcd_pm_runtime_put(hba->dev); > } > > static void ufshcd_update_uic_reg_hist(struct ufs_uic_err_reg_hist *reg_hist, > @@ -6425,7 +6454,7 @@ static int ufshcd_probe_hba(struct ufs_hba *hba) > } > > scsi_scan_host(hba->host); > - pm_runtime_put_sync(hba->dev); > + ufshcd_pm_runtime_put(hba->dev); > } > > if (!hba->is_init_prefetch) > @@ -6437,7 +6466,7 @@ static int ufshcd_probe_hba(struct ufs_hba *hba) > * present, turn off the power/clocks etc. > */ > if (ret && !ufshcd_eh_in_progress(hba) && !hba- > >pm_op_in_progress) { > - pm_runtime_put_sync(hba->dev); > + ufshcd_pm_runtime_put(hba->dev); > ufshcd_hba_exit(hba); > } > > @@ -7747,6 +7776,8 @@ EXPORT_SYMBOL(ufshcd_shutdown); void > ufshcd_remove(struct ufs_hba *hba) { > ufshcd_remove_sysfs_nodes(hba); > + // Resume if suspended for sync > + ufshcd_pm_runtime_get(hba->dev); > scsi_remove_host(hba->host); > /* disable interrupts */ > ufshcd_disable_intr(hba, hba->intr_mask); @@ -7756,6 +7787,8 @@ > void ufshcd_remove(struct ufs_hba *hba) > if (ufshcd_is_clkscaling_supported(hba)) > device_remove_file(hba->dev, &hba->clk_scaling.enable_attr); > ufshcd_hba_exit(hba); > + // Final sync finished - put it back > + ufshcd_pm_runtime_put(hba->dev); > } > EXPORT_SYMBOL_GPL(ufshcd_remove); > > @@ -7978,11 +8011,11 @@ int ufshcd_init(struct ufs_hba *hba, void > __iomem *mmio_base, unsigned int irq) > UFS_SLEEP_PWR_MODE, > UIC_LINK_HIBERN8_STATE); > hba->spm_lvl = ufs_get_desired_pm_lvl_for_dev_link_state( > - UFS_SLEEP_PWR_MODE, > - UIC_LINK_HIBERN8_STATE); > + > UFS_POWERDOWN_PWR_MODE, > + UIC_LINK_OFF_STATE); > > /* Hold auto suspend until async scan completes */ > - pm_runtime_get_sync(dev); > + ufshcd_pm_runtime_get(dev); > > /* > * We are assuming that device wasn't put in sleep/power-down > -- > 2.13.0.67.g10c78a1 > > -------------------------------------------------------------------- > > Intel Technology Poland sp. z o.o. > ul. Slowackiego 173 | 80-298 Gdansk | Sad Rejonowy Gdansk Polnoc | VII > Wydzial Gospodarczy Krajowego Rejestru Sadowego - KRS 101882 | NIP 957- > 07-52-316 | Kapital zakladowy 200.000 PLN. > > Ta wiadomosc wraz z zalacznikami jest przeznaczona dla okreslonego adresata > i moze zawierac informacje poufne. W razie przypadkowego otrzymania tej > wiadomosci, prosimy o powiadomienie nadawcy oraz trwale jej usuniecie; > jakiekolwiek przegladanie lub rozpowszechnianie jest zabronione. > This e-mail and any attachments may contain confidential material for the > sole use of the intended recipient(s). If you are not the intended recipient, > please contact the sender and delete all copies; any review or distribution by > others is strictly prohibited.
diff --git a/drivers/scsi/ufs/ufshcd-pci.c b/drivers/scsi/ufs/ufshcd-pci.c index 925b0ec7ec54..4fffb1123876 100644 --- a/drivers/scsi/ufs/ufshcd-pci.c +++ b/drivers/scsi/ufs/ufshcd-pci.c @@ -184,8 +184,10 @@ ufshcd_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) } pci_set_drvdata(pdev, hba); + pm_runtime_set_autosuspend_delay(&pdev->dev, 3000); + pm_runtime_use_autosuspend(&pdev->dev); pm_runtime_put_noidle(&pdev->dev); - pm_runtime_allow(&pdev->dev); + pm_runtime_forbid(&pdev->dev); return 0; } diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index 011c3369082c..e7c7ed9bf8a5 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c @@ -240,6 +240,28 @@ static inline bool ufshcd_valid_tag(struct ufs_hba *hba, int tag) return tag >= 0 && tag < hba->nutrs; } +static void ufshcd_pm_runtime_get(struct device *dev) +{ + // Don't trigger PM events while in transition states + if (dev->power.runtime_status == RPM_RESUMING || + dev->power.runtime_status == RPM_SUSPENDING) + pm_runtime_get_noresume(dev); + else + pm_runtime_get_sync(dev); +} + +static void ufshcd_pm_runtime_put(struct device *dev) +{ + pm_runtime_mark_last_busy(dev); + + // Don't trigger PM events while in transition states + if (dev->power.runtime_status == RPM_RESUMING || + dev->power.runtime_status == RPM_SUSPENDING) + pm_runtime_put_noidle(dev); + else + pm_runtime_put_autosuspend(dev); +} + static inline int ufshcd_enable_irq(struct ufs_hba *hba) { int ret = 0; @@ -1345,7 +1367,7 @@ static ssize_t ufshcd_clkscale_enable_store(struct device *dev, if (value == hba->clk_scaling.is_allowed) goto out; - pm_runtime_get_sync(hba->dev); + ufshcd_pm_runtime_get(hba->dev); ufshcd_hold(hba, false); cancel_work_sync(&hba->clk_scaling.suspend_work); @@ -1364,7 +1386,7 @@ static ssize_t ufshcd_clkscale_enable_store(struct device *dev, } ufshcd_release(hba); - pm_runtime_put_sync(hba->dev); + ufshcd_pm_runtime_put(hba->dev); out: return count; } @@ -1948,6 +1970,7 @@ ufshcd_send_uic_cmd(struct ufs_hba *hba, struct uic_command *uic_cmd) unsigned long flags; ufshcd_hold(hba, false); + ufshcd_pm_runtime_get(hba->dev); mutex_lock(&hba->uic_cmd_mutex); ufshcd_add_delay_before_dme_cmd(hba); @@ -1959,6 +1982,7 @@ ufshcd_send_uic_cmd(struct ufs_hba *hba, struct uic_command *uic_cmd) mutex_unlock(&hba->uic_cmd_mutex); + ufshcd_pm_runtime_put(hba->dev); ufshcd_release(hba); return ret; } @@ -2345,6 +2369,7 @@ static int ufshcd_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmd) clear_bit_unlock(tag, &hba->lrb_in_use); goto out; } + ufshcd_pm_runtime_get(hba->dev); WARN_ON(hba->clk_gating.state != CLKS_ON); lrbp = &hba->lrb[tag]; @@ -3555,6 +3580,7 @@ static int ufshcd_uic_pwr_ctrl(struct ufs_hba *hba, struct uic_command *cmd) int ret; bool reenable_intr = false; + ufshcd_pm_runtime_get(hba->dev); mutex_lock(&hba->uic_cmd_mutex); init_completion(&uic_async_done); ufshcd_add_delay_before_dme_cmd(hba); @@ -3609,6 +3635,7 @@ static int ufshcd_uic_pwr_ctrl(struct ufs_hba *hba, struct uic_command *cmd) ufshcd_enable_intr(hba, UIC_COMMAND_COMPL); spin_unlock_irqrestore(hba->host->host_lock, flags); mutex_unlock(&hba->uic_cmd_mutex); + ufshcd_pm_runtime_put(hba->dev); return ret; } @@ -4386,6 +4413,7 @@ static int ufshcd_slave_configure(struct scsi_device *sdev) blk_queue_update_dma_pad(q, PRDT_DATA_BYTE_COUNT_PAD - 1); blk_queue_max_segment_size(q, PRDT_DATA_BYTE_COUNT_MAX); + scsi_autopm_put_device(sdev); return 0; } @@ -4622,6 +4650,7 @@ static void __ufshcd_transfer_req_compl(struct ufs_hba *hba, /* Do not touch lrbp after scsi done */ cmd->scsi_done(cmd); __ufshcd_release(hba); + ufshcd_pm_runtime_put(hba->dev); } else if (lrbp->command_type == UTP_CMD_TYPE_DEV_MANAGE || lrbp->command_type == UTP_CMD_TYPE_UFS_STORAGE) { if (hba->dev_cmd.complete) { @@ -4951,7 +4980,7 @@ static void ufshcd_exception_event_handler(struct work_struct *work) u32 status = 0; hba = container_of(work, struct ufs_hba, eeh_work); - pm_runtime_get_sync(hba->dev); + ufshcd_pm_runtime_get(hba->dev); err = ufshcd_get_ee_status(hba, &status); if (err) { dev_err(hba->dev, "%s: failed to get exception status %d\n", @@ -4965,7 +4994,7 @@ static void ufshcd_exception_event_handler(struct work_struct *work) ufshcd_bkops_exception_event_handler(hba); out: - pm_runtime_put_sync(hba->dev); + ufshcd_pm_runtime_put(hba->dev); return; } @@ -5065,7 +5094,7 @@ static void ufshcd_err_handler(struct work_struct *work) hba = container_of(work, struct ufs_hba, eh_work); - pm_runtime_get_sync(hba->dev); + ufshcd_pm_runtime_get(hba->dev); ufshcd_hold(hba, false); spin_lock_irqsave(hba->host->host_lock, flags); @@ -5177,7 +5206,7 @@ static void ufshcd_err_handler(struct work_struct *work) spin_unlock_irqrestore(hba->host->host_lock, flags); scsi_unblock_requests(hba->host); ufshcd_release(hba); - pm_runtime_put_sync(hba->dev); + ufshcd_pm_runtime_put(hba->dev); } static void ufshcd_update_uic_reg_hist(struct ufs_uic_err_reg_hist *reg_hist, @@ -6425,7 +6454,7 @@ static int ufshcd_probe_hba(struct ufs_hba *hba) } scsi_scan_host(hba->host); - pm_runtime_put_sync(hba->dev); + ufshcd_pm_runtime_put(hba->dev); } if (!hba->is_init_prefetch) @@ -6437,7 +6466,7 @@ static int ufshcd_probe_hba(struct ufs_hba *hba) * present, turn off the power/clocks etc. */ if (ret && !ufshcd_eh_in_progress(hba) && !hba->pm_op_in_progress) { - pm_runtime_put_sync(hba->dev); + ufshcd_pm_runtime_put(hba->dev); ufshcd_hba_exit(hba); } @@ -7747,6 +7776,8 @@ EXPORT_SYMBOL(ufshcd_shutdown); void ufshcd_remove(struct ufs_hba *hba) { ufshcd_remove_sysfs_nodes(hba); + // Resume if suspended for sync + ufshcd_pm_runtime_get(hba->dev); scsi_remove_host(hba->host); /* disable interrupts */ ufshcd_disable_intr(hba, hba->intr_mask); @@ -7756,6 +7787,8 @@ void ufshcd_remove(struct ufs_hba *hba) if (ufshcd_is_clkscaling_supported(hba)) device_remove_file(hba->dev, &hba->clk_scaling.enable_attr); ufshcd_hba_exit(hba); + // Final sync finished - put it back + ufshcd_pm_runtime_put(hba->dev); } EXPORT_SYMBOL_GPL(ufshcd_remove); @@ -7978,11 +8011,11 @@ int ufshcd_init(struct ufs_hba *hba, void __iomem *mmio_base, unsigned int irq) UFS_SLEEP_PWR_MODE, UIC_LINK_HIBERN8_STATE); hba->spm_lvl = ufs_get_desired_pm_lvl_for_dev_link_state( - UFS_SLEEP_PWR_MODE, - UIC_LINK_HIBERN8_STATE); + UFS_POWERDOWN_PWR_MODE, + UIC_LINK_OFF_STATE); /* Hold auto suspend until async scan completes */ - pm_runtime_get_sync(dev); + ufshcd_pm_runtime_get(dev); /* * We are assuming that device wasn't put in sleep/power-down