summaryrefslogtreecommitdiff
path: root/drivers/scsi/ufs/ufshcd-pltfrm.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/ufs/ufshcd-pltfrm.c')
-rw-r--r--drivers/scsi/ufs/ufshcd-pltfrm.c80
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: