diff options
author | Raviv Shvili <rshvili@codeaurora.org> | 2014-09-25 08:32:24 -0400 |
---|---|---|
committer | Christoph Hellwig <hch@lst.de> | 2014-10-01 07:11:20 -0400 |
commit | 6a771a656041f404fae143e5d753d37f5c0688e7 (patch) | |
tree | 13596a256da37823e27f83998c5698e0cbaf0c87 /drivers/scsi | |
parent | c6e79dacd86fd7ddd452fa52b3f4ca996db31e49 (diff) |
ufs: add voting support for host controller power
Add the support for voting of the regulator powering the
host controller logic.
Signed-off-by: Raviv Shvili <rshvili@codeaurora.org>
Signed-off-by: Subhash Jadavani <subhashj@codeaurora.org>
Signed-off-by: Dolev Raviv <draviv@codeaurora.org>
Signed-off-by: Christoph Hellwig <hch@lst.de>
Diffstat (limited to 'drivers/scsi')
-rw-r--r-- | drivers/scsi/ufs/ufs.h | 1 | ||||
-rw-r--r-- | drivers/scsi/ufs/ufshcd-pltfrm.c | 9 | ||||
-rw-r--r-- | drivers/scsi/ufs/ufshcd.c | 42 |
3 files changed, 50 insertions, 2 deletions
diff --git a/drivers/scsi/ufs/ufs.h b/drivers/scsi/ufs/ufs.h index 729ce7d62d1e..9bb691962c47 100644 --- a/drivers/scsi/ufs/ufs.h +++ b/drivers/scsi/ufs/ufs.h | |||
@@ -385,6 +385,7 @@ struct ufs_vreg_info { | |||
385 | struct ufs_vreg *vcc; | 385 | struct ufs_vreg *vcc; |
386 | struct ufs_vreg *vccq; | 386 | struct ufs_vreg *vccq; |
387 | struct ufs_vreg *vccq2; | 387 | struct ufs_vreg *vccq2; |
388 | struct ufs_vreg *vdd_hba; | ||
388 | }; | 389 | }; |
389 | 390 | ||
390 | #endif /* End of Header */ | 391 | #endif /* End of Header */ |
diff --git a/drivers/scsi/ufs/ufshcd-pltfrm.c b/drivers/scsi/ufs/ufshcd-pltfrm.c index 642d80fe1f80..dde4e6e3be70 100644 --- a/drivers/scsi/ufs/ufshcd-pltfrm.c +++ b/drivers/scsi/ufs/ufshcd-pltfrm.c | |||
@@ -147,6 +147,11 @@ static int ufshcd_populate_vreg(struct device *dev, const char *name, | |||
147 | 147 | ||
148 | vreg->name = kstrdup(name, GFP_KERNEL); | 148 | vreg->name = kstrdup(name, GFP_KERNEL); |
149 | 149 | ||
150 | /* if fixed regulator no need further initialization */ | ||
151 | snprintf(prop_name, MAX_PROP_SIZE, "%s-fixed-regulator", name); | ||
152 | if (of_property_read_bool(np, prop_name)) | ||
153 | goto out; | ||
154 | |||
150 | snprintf(prop_name, MAX_PROP_SIZE, "%s-max-microamp", name); | 155 | snprintf(prop_name, MAX_PROP_SIZE, "%s-max-microamp", name); |
151 | ret = of_property_read_u32(np, prop_name, &vreg->max_uA); | 156 | ret = of_property_read_u32(np, prop_name, &vreg->max_uA); |
152 | if (ret) { | 157 | if (ret) { |
@@ -198,6 +203,10 @@ static int ufshcd_parse_regulator_info(struct ufs_hba *hba) | |||
198 | struct device *dev = hba->dev; | 203 | struct device *dev = hba->dev; |
199 | struct ufs_vreg_info *info = &hba->vreg_info; | 204 | struct ufs_vreg_info *info = &hba->vreg_info; |
200 | 205 | ||
206 | err = ufshcd_populate_vreg(dev, "vdd-hba", &info->vdd_hba); | ||
207 | if (err) | ||
208 | goto out; | ||
209 | |||
201 | err = ufshcd_populate_vreg(dev, "vcc", &info->vcc); | 210 | err = ufshcd_populate_vreg(dev, "vcc", &info->vcc); |
202 | if (err) | 211 | if (err) |
203 | goto out; | 212 | goto out; |
diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index b03370292070..26301b8325e8 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c | |||
@@ -3311,6 +3311,16 @@ out: | |||
3311 | return ret; | 3311 | return ret; |
3312 | } | 3312 | } |
3313 | 3313 | ||
3314 | static int ufshcd_setup_hba_vreg(struct ufs_hba *hba, bool on) | ||
3315 | { | ||
3316 | struct ufs_vreg_info *info = &hba->vreg_info; | ||
3317 | |||
3318 | if (info) | ||
3319 | return ufshcd_toggle_vreg(hba->dev, info->vdd_hba, on); | ||
3320 | |||
3321 | return 0; | ||
3322 | } | ||
3323 | |||
3314 | static int ufshcd_get_vreg(struct device *dev, struct ufs_vreg *vreg) | 3324 | static int ufshcd_get_vreg(struct device *dev, struct ufs_vreg *vreg) |
3315 | { | 3325 | { |
3316 | int ret = 0; | 3326 | int ret = 0; |
@@ -3350,6 +3360,16 @@ out: | |||
3350 | return ret; | 3360 | return ret; |
3351 | } | 3361 | } |
3352 | 3362 | ||
3363 | static int ufshcd_init_hba_vreg(struct ufs_hba *hba) | ||
3364 | { | ||
3365 | struct ufs_vreg_info *info = &hba->vreg_info; | ||
3366 | |||
3367 | if (info) | ||
3368 | return ufshcd_get_vreg(hba->dev, info->vdd_hba); | ||
3369 | |||
3370 | return 0; | ||
3371 | } | ||
3372 | |||
3353 | static int ufshcd_setup_clocks(struct ufs_hba *hba, bool on) | 3373 | static int ufshcd_setup_clocks(struct ufs_hba *hba, bool on) |
3354 | { | 3374 | { |
3355 | int ret = 0; | 3375 | int ret = 0; |
@@ -3483,14 +3503,29 @@ static int ufshcd_hba_init(struct ufs_hba *hba) | |||
3483 | { | 3503 | { |
3484 | int err; | 3504 | int err; |
3485 | 3505 | ||
3486 | err = ufshcd_init_clocks(hba); | 3506 | /* |
3507 | * Handle host controller power separately from the UFS device power | ||
3508 | * rails as it will help controlling the UFS host controller power | ||
3509 | * collapse easily which is different than UFS device power collapse. | ||
3510 | * Also, enable the host controller power before we go ahead with rest | ||
3511 | * of the initialization here. | ||
3512 | */ | ||
3513 | err = ufshcd_init_hba_vreg(hba); | ||
3487 | if (err) | 3514 | if (err) |
3488 | goto out; | 3515 | goto out; |
3489 | 3516 | ||
3490 | err = ufshcd_setup_clocks(hba, true); | 3517 | err = ufshcd_setup_hba_vreg(hba, true); |
3491 | if (err) | 3518 | if (err) |
3492 | goto out; | 3519 | goto out; |
3493 | 3520 | ||
3521 | err = ufshcd_init_clocks(hba); | ||
3522 | if (err) | ||
3523 | goto out_disable_hba_vreg; | ||
3524 | |||
3525 | err = ufshcd_setup_clocks(hba, true); | ||
3526 | if (err) | ||
3527 | goto out_disable_hba_vreg; | ||
3528 | |||
3494 | err = ufshcd_init_vreg(hba); | 3529 | err = ufshcd_init_vreg(hba); |
3495 | if (err) | 3530 | if (err) |
3496 | goto out_disable_clks; | 3531 | goto out_disable_clks; |
@@ -3509,6 +3544,8 @@ out_disable_vreg: | |||
3509 | ufshcd_setup_vreg(hba, false); | 3544 | ufshcd_setup_vreg(hba, false); |
3510 | out_disable_clks: | 3545 | out_disable_clks: |
3511 | ufshcd_setup_clocks(hba, false); | 3546 | ufshcd_setup_clocks(hba, false); |
3547 | out_disable_hba_vreg: | ||
3548 | ufshcd_setup_hba_vreg(hba, false); | ||
3512 | out: | 3549 | out: |
3513 | return err; | 3550 | return err; |
3514 | } | 3551 | } |
@@ -3518,6 +3555,7 @@ static void ufshcd_hba_exit(struct ufs_hba *hba) | |||
3518 | ufshcd_variant_hba_exit(hba); | 3555 | ufshcd_variant_hba_exit(hba); |
3519 | ufshcd_setup_vreg(hba, false); | 3556 | ufshcd_setup_vreg(hba, false); |
3520 | ufshcd_setup_clocks(hba, false); | 3557 | ufshcd_setup_clocks(hba, false); |
3558 | ufshcd_setup_hba_vreg(hba, false); | ||
3521 | } | 3559 | } |
3522 | 3560 | ||
3523 | /** | 3561 | /** |