]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
scsi: ufs: pltfrm: Disable runtime PM during removal of glue drivers
authorManivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
Mon, 11 Nov 2024 17:48:32 +0000 (23:18 +0530)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sat, 14 Dec 2024 19:03:25 +0000 (20:03 +0100)
commit d3326e6a3f9bf1e075be2201fb704c2fdf19e2b7 upstream.

When the UFSHCD platform glue drivers are removed, runtime PM should be
disabled using pm_runtime_disable() to balance the enablement done in
ufshcd_pltfrm_init(). This is also reported by PM core when the glue driver
is removed and inserted again:

ufshcd-qcom 1d84000.ufshc: Unbalanced pm_runtime_enable!

So disable runtime PM using a new helper API ufshcd_pltfrm_remove(), that
also takes care of removing ufshcd. This helper should be called during the
remove() stage of glue drivers.

Cc: stable@vger.kernel.org # 3.12
Fixes: 62694735ca95 ("[SCSI] ufs: Add runtime PM support for UFS host controller driver")
Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
Link: https://lore.kernel.org/r/20241111-ufs_bug_fix-v1-3-45ad8b62f02e@linaro.org
Reviewed-by: Peter Wang <peter.wang@mediatek.com>
Reviewed-by: Bean Huo <beanhuo@micron.com>
Reviewed-by: Bart Van Assche <bvanassche@acm.org>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/ufs/host/cdns-pltfrm.c
drivers/ufs/host/tc-dwc-g210-pltfrm.c
drivers/ufs/host/ufs-exynos.c
drivers/ufs/host/ufs-hisi.c
drivers/ufs/host/ufs-mediatek.c
drivers/ufs/host/ufs-qcom.c
drivers/ufs/host/ufs-renesas.c
drivers/ufs/host/ufs-sprd.c
drivers/ufs/host/ufshcd-pltfrm.c
drivers/ufs/host/ufshcd-pltfrm.h

index 66811d8d1929c135aa43d5cda482464cf37854b4..b31aa84111511bf2d1e2fcb7cf0a90ac14dd076c 100644 (file)
@@ -307,9 +307,7 @@ static int cdns_ufs_pltfrm_probe(struct platform_device *pdev)
  */
 static void cdns_ufs_pltfrm_remove(struct platform_device *pdev)
 {
-       struct ufs_hba *hba =  platform_get_drvdata(pdev);
-
-       ufshcd_remove(hba);
+       ufshcd_pltfrm_remove(pdev);
 }
 
 static const struct dev_pm_ops cdns_ufs_dev_pm_ops = {
index a3877592604d5d659add23f18f1c93c22ef99341..113e0ef7b2cf84d212ae3bff0181aee9db6926a3 100644 (file)
@@ -76,10 +76,8 @@ static int tc_dwc_g210_pltfm_probe(struct platform_device *pdev)
  */
 static void tc_dwc_g210_pltfm_remove(struct platform_device *pdev)
 {
-       struct ufs_hba *hba =  platform_get_drvdata(pdev);
-
        pm_runtime_get_sync(&(pdev)->dev);
-       ufshcd_remove(hba);
+       ufshcd_pltfrm_remove(pdev);
 }
 
 static const struct dev_pm_ops tc_dwc_g210_pltfm_pm_ops = {
index fb550a7c16b34b6f2977fe744125b851a5027734..4ac098b748dc6a68a84ac1a0b136e91c2899361d 100644 (file)
@@ -1964,7 +1964,7 @@ static void exynos_ufs_remove(struct platform_device *pdev)
        struct exynos_ufs *ufs = ufshcd_get_variant(hba);
 
        pm_runtime_get_sync(&(pdev)->dev);
-       ufshcd_remove(hba);
+       ufshcd_pltfrm_remove(pdev);
 
        phy_power_off(ufs->phy);
        phy_exit(ufs->phy);
index 5ee73ff052512b3468adc707ed26e99cd8c3b1ec..501609521b2609077f0688c130aa1bbef39ed784 100644 (file)
@@ -576,9 +576,7 @@ static int ufs_hisi_probe(struct platform_device *pdev)
 
 static void ufs_hisi_remove(struct platform_device *pdev)
 {
-       struct ufs_hba *hba =  platform_get_drvdata(pdev);
-
-       ufshcd_remove(hba);
+       ufshcd_pltfrm_remove(pdev);
 }
 
 static const struct dev_pm_ops ufs_hisi_pm_ops = {
index 9a5919434c4e0d1b4c04c105d08b1a7a9e55f2a6..512b4e43787cb7f094dcc2911f7f263f5fc92eb4 100644 (file)
@@ -1869,10 +1869,8 @@ out:
  */
 static void ufs_mtk_remove(struct platform_device *pdev)
 {
-       struct ufs_hba *hba =  platform_get_drvdata(pdev);
-
        pm_runtime_get_sync(&(pdev)->dev);
-       ufshcd_remove(hba);
+       ufshcd_pltfrm_remove(pdev);
 }
 
 #ifdef CONFIG_PM_SLEEP
index 1bcc538ef8af7ab3ffdbe5dbddeaa91c786ea283..38732dd48331ed968e62d155ba5881de59a8e682 100644 (file)
@@ -1846,7 +1846,7 @@ static void ufs_qcom_remove(struct platform_device *pdev)
        struct ufs_qcom_host *host = ufshcd_get_variant(hba);
 
        pm_runtime_get_sync(&(pdev)->dev);
-       ufshcd_remove(hba);
+       ufshcd_pltfrm_remove(pdev);
        if (host->esi_enabled)
                platform_device_msi_free_irqs_all(hba->dev);
 }
index 8711e5cbc9680a3479a5035f4755b249fa618454..b3a5fc2d44e72a7383f1a71f28376759fa7ff1d7 100644 (file)
@@ -390,9 +390,7 @@ static int ufs_renesas_probe(struct platform_device *pdev)
 
 static void ufs_renesas_remove(struct platform_device *pdev)
 {
-       struct ufs_hba *hba = platform_get_drvdata(pdev);
-
-       ufshcd_remove(hba);
+       ufshcd_pltfrm_remove(pdev);
 }
 
 static struct platform_driver ufs_renesas_platform = {
index d8b165908809d69a7ca6bdd82f07ffc87db9def4..e455890cf7d49e3e49ffb2e4c7f840c62d7d7e2c 100644 (file)
@@ -427,10 +427,8 @@ static int ufs_sprd_probe(struct platform_device *pdev)
 
 static void ufs_sprd_remove(struct platform_device *pdev)
 {
-       struct ufs_hba *hba =  platform_get_drvdata(pdev);
-
        pm_runtime_get_sync(&(pdev)->dev);
-       ufshcd_remove(hba);
+       ufshcd_pltfrm_remove(pdev);
 }
 
 static const struct dev_pm_ops ufs_sprd_pm_ops = {
index 1f4f30d6cb42343da61c800530ae247d9d6f78c6..bad5b1303eb685ce9d7ae36609104ff0b859fb79 100644 (file)
@@ -524,6 +524,19 @@ out:
 }
 EXPORT_SYMBOL_GPL(ufshcd_pltfrm_init);
 
+/**
+ * ufshcd_pltfrm_remove - Remove ufshcd platform
+ * @pdev: pointer to Platform device handle
+ */
+void ufshcd_pltfrm_remove(struct platform_device *pdev)
+{
+       struct ufs_hba *hba =  platform_get_drvdata(pdev);
+
+       ufshcd_remove(hba);
+       pm_runtime_disable(&pdev->dev);
+}
+EXPORT_SYMBOL_GPL(ufshcd_pltfrm_remove);
+
 MODULE_AUTHOR("Santosh Yaragnavi <santosh.sy@samsung.com>");
 MODULE_AUTHOR("Vinayak Holikatti <h.vinayak@samsung.com>");
 MODULE_DESCRIPTION("UFS host controller Platform bus based glue driver");
index df387be5216bd42f6d3adb66761bb9200904960d..3017f8e8f93c678bf4071924ed2ef54395354a5f 100644 (file)
@@ -31,6 +31,7 @@ int ufshcd_negotiate_pwr_params(const struct ufs_host_params *host_params,
 void ufshcd_init_host_params(struct ufs_host_params *host_params);
 int ufshcd_pltfrm_init(struct platform_device *pdev,
                       const struct ufs_hba_variant_ops *vops);
+void ufshcd_pltfrm_remove(struct platform_device *pdev);
 int ufshcd_populate_vreg(struct device *dev, const char *name,
                         struct ufs_vreg **out_vreg, bool skip_current);