Skip to content

Commit

Permalink
scsi: ufs: pltfrm: Disable runtime PM during removal of glue drivers
Browse files Browse the repository at this point in the history
commit d3326e6 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: [email protected] # 3.12
Fixes: 6269473 ("[SCSI] ufs: Add runtime PM support for UFS host controller driver")
Signed-off-by: Manivannan Sadhasivam <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
Reviewed-by: Peter Wang <[email protected]>
Reviewed-by: Bean Huo <[email protected]>
Reviewed-by: Bart Van Assche <[email protected]>
Signed-off-by: Martin K. Petersen <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
  • Loading branch information
Mani-Sadhasivam authored and gregkh committed Dec 14, 2024
1 parent f99cb5f commit 8c94257
Show file tree
Hide file tree
Showing 10 changed files with 22 additions and 20 deletions.
4 changes: 1 addition & 3 deletions drivers/ufs/host/cdns-pltfrm.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 = {
Expand Down
4 changes: 1 addition & 3 deletions drivers/ufs/host/tc-dwc-g210-pltfrm.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 = {
Expand Down
2 changes: 1 addition & 1 deletion drivers/ufs/host/ufs-exynos.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
4 changes: 1 addition & 3 deletions drivers/ufs/host/ufs-hisi.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 = {
Expand Down
4 changes: 1 addition & 3 deletions drivers/ufs/host/ufs-mediatek.c
Original file line number Diff line number Diff line change
Expand Up @@ -1869,10 +1869,8 @@ static int ufs_mtk_probe(struct platform_device *pdev)
*/
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
Expand Down
2 changes: 1 addition & 1 deletion drivers/ufs/host/ufs-qcom.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Expand Down
4 changes: 1 addition & 3 deletions drivers/ufs/host/ufs-renesas.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 = {
Expand Down
4 changes: 1 addition & 3 deletions drivers/ufs/host/ufs-sprd.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 = {
Expand Down
13 changes: 13 additions & 0 deletions drivers/ufs/host/ufshcd-pltfrm.c
Original file line number Diff line number Diff line change
Expand Up @@ -524,6 +524,19 @@ int ufshcd_pltfrm_init(struct platform_device *pdev,
}
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 <[email protected]>");
MODULE_AUTHOR("Vinayak Holikatti <[email protected]>");
MODULE_DESCRIPTION("UFS host controller Platform bus based glue driver");
Expand Down
1 change: 1 addition & 0 deletions drivers/ufs/host/ufshcd-pltfrm.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down

0 comments on commit 8c94257

Please sign in to comment.