diff options
Diffstat (limited to 'drivers/scsi/ufs/ufshcd-pltfrm.c')
| -rw-r--r-- | drivers/scsi/ufs/ufshcd-pltfrm.c | 80 |
1 files changed, 69 insertions, 11 deletions
diff --git a/drivers/scsi/ufs/ufshcd-pltfrm.c b/drivers/scsi/ufs/ufshcd-pltfrm.c index f58abfcdfe81..41684dca6baa 100644 --- a/drivers/scsi/ufs/ufshcd-pltfrm.c +++ b/drivers/scsi/ufs/ufshcd-pltfrm.c @@ -40,6 +40,22 @@ #include "ufshcd.h" #include "ufshcd-pltfrm.h" +static int ufshcd_parse_reset_info(struct ufs_hba *hba) +{ + int ret = 0; + + hba->core_reset = devm_reset_control_get(hba->dev, + "core_reset"); + if (IS_ERR(hba->core_reset)) { + ret = PTR_ERR(hba->core_reset); + dev_err(hba->dev, "core_reset unavailable,err = %d\n", + ret); + hba->core_reset = NULL; + } + + return ret; +} + static int ufshcd_parse_clock_info(struct ufs_hba *hba) { int ret = 0; @@ -221,7 +237,34 @@ out: return err; } -#ifdef CONFIG_PM +static void ufshcd_parse_pm_levels(struct ufs_hba *hba) +{ + struct device *dev = hba->dev; + struct device_node *np = dev->of_node; + + if (np) { + if (of_property_read_u32(np, "rpm-level", &hba->rpm_lvl)) + hba->rpm_lvl = -1; + if (of_property_read_u32(np, "spm-level", &hba->spm_lvl)) + hba->spm_lvl = -1; + } +} + +static int ufshcd_parse_pinctrl_info(struct ufs_hba *hba) +{ + int ret = 0; + + /* Try to obtain pinctrl handle */ + hba->pctrl = devm_pinctrl_get(hba->dev); + if (IS_ERR(hba->pctrl)) { + ret = PTR_ERR(hba->pctrl); + hba->pctrl = NULL; + } + + return ret; +} + +#ifdef CONFIG_SMP /** * ufshcd_pltfrm_suspend - suspend power management function * @dev: pointer to device handle @@ -277,12 +320,12 @@ EXPORT_SYMBOL_GPL(ufshcd_pltfrm_shutdown); /** * ufshcd_pltfrm_init - probe routine of the driver * @pdev: pointer to Platform device handle - * @vops: pointer to variant ops + * @var: pointer to variant specific data * * Returns 0 on success, non-zero value on failure */ int ufshcd_pltfrm_init(struct platform_device *pdev, - struct ufs_hba_variant_ops *vops) + struct ufs_hba_variant *var) { struct ufs_hba *hba; void __iomem *mmio_base; @@ -310,7 +353,7 @@ int ufshcd_pltfrm_init(struct platform_device *pdev, goto out; } - hba->vops = vops; + hba->var = var; err = ufshcd_parse_clock_info(hba); if (err) { @@ -325,22 +368,37 @@ int ufshcd_pltfrm_init(struct platform_device *pdev, goto dealloc_host; } - pm_runtime_set_active(&pdev->dev); - pm_runtime_enable(&pdev->dev); + err = ufshcd_parse_reset_info(hba); + if (err) { + dev_err(&pdev->dev, "%s: reset parse failed %d\n", + __func__, err); + goto dealloc_host; + } + + err = ufshcd_parse_pinctrl_info(hba); + if (err) { + dev_dbg(&pdev->dev, "%s: unable to parse pinctrl data %d\n", + __func__, err); + /* let's not fail the probe */ + } + + ufshcd_parse_pm_levels(hba); + + if (!dev->dma_mask) + dev->dma_mask = &dev->coherent_dma_mask; err = ufshcd_init(hba, mmio_base, irq); if (err) { dev_err(dev, "Intialization failed\n"); - goto out_disable_rpm; + goto dealloc_host; } platform_set_drvdata(pdev, hba); - return 0; + pm_runtime_set_active(&pdev->dev); + pm_runtime_enable(&pdev->dev); -out_disable_rpm: - pm_runtime_disable(&pdev->dev); - pm_runtime_set_suspended(&pdev->dev); + return 0; dealloc_host: ufshcd_dealloc_host(hba); out: |
