diff options
author | Thierry Reding <treding@nvidia.com> | 2019-02-21 10:46:33 -0500 |
---|---|---|
committer | Kishon Vijay Abraham I <kishon@ti.com> | 2019-04-17 04:42:45 -0400 |
commit | a630d54dfa937a937e3faf172ca41b9bd2647c72 (patch) | |
tree | 99cd9693ea66fc0134fa452b1659b6d16dc57839 | |
parent | 5311a7b89502592045812f97294f756b1fca132b (diff) |
phy: tegra: xusb: Add support for power supplies
Support enabling various supplies needed to provide power to the PLLs
and logic used to drive the USB, PCI and SATA pads.
Reviewed-by: JC Kuo <jckuo@nvidia.com>
Signed-off-by: Thierry Reding <treding@nvidia.com>
Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
-rw-r--r-- | drivers/phy/tegra/xusb.c | 34 | ||||
-rw-r--r-- | drivers/phy/tegra/xusb.h | 5 |
2 files changed, 38 insertions, 1 deletions
diff --git a/drivers/phy/tegra/xusb.c b/drivers/phy/tegra/xusb.c index 57a2d08ef6da..e510629f4f1c 100644 --- a/drivers/phy/tegra/xusb.c +++ b/drivers/phy/tegra/xusb.c | |||
@@ -864,6 +864,7 @@ static int tegra_xusb_padctl_probe(struct platform_device *pdev) | |||
864 | struct tegra_xusb_padctl *padctl; | 864 | struct tegra_xusb_padctl *padctl; |
865 | const struct of_device_id *match; | 865 | const struct of_device_id *match; |
866 | struct resource *res; | 866 | struct resource *res; |
867 | unsigned int i; | ||
867 | int err; | 868 | int err; |
868 | 869 | ||
869 | /* for backwards compatibility with old device trees */ | 870 | /* for backwards compatibility with old device trees */ |
@@ -901,14 +902,38 @@ static int tegra_xusb_padctl_probe(struct platform_device *pdev) | |||
901 | goto remove; | 902 | goto remove; |
902 | } | 903 | } |
903 | 904 | ||
905 | padctl->supplies = devm_kcalloc(&pdev->dev, padctl->soc->num_supplies, | ||
906 | sizeof(*padctl->supplies), GFP_KERNEL); | ||
907 | if (!padctl->supplies) { | ||
908 | err = -ENOMEM; | ||
909 | goto remove; | ||
910 | } | ||
911 | |||
912 | for (i = 0; i < padctl->soc->num_supplies; i++) | ||
913 | padctl->supplies[i].supply = padctl->soc->supply_names[i]; | ||
914 | |||
915 | err = devm_regulator_bulk_get(&pdev->dev, padctl->soc->num_supplies, | ||
916 | padctl->supplies); | ||
917 | if (err < 0) { | ||
918 | dev_err(&pdev->dev, "failed to get regulators: %d\n", err); | ||
919 | goto remove; | ||
920 | } | ||
921 | |||
904 | err = reset_control_deassert(padctl->rst); | 922 | err = reset_control_deassert(padctl->rst); |
905 | if (err < 0) | 923 | if (err < 0) |
906 | goto remove; | 924 | goto remove; |
907 | 925 | ||
926 | err = regulator_bulk_enable(padctl->soc->num_supplies, | ||
927 | padctl->supplies); | ||
928 | if (err < 0) { | ||
929 | dev_err(&pdev->dev, "failed to enable supplies: %d\n", err); | ||
930 | goto reset; | ||
931 | } | ||
932 | |||
908 | err = tegra_xusb_setup_pads(padctl); | 933 | err = tegra_xusb_setup_pads(padctl); |
909 | if (err < 0) { | 934 | if (err < 0) { |
910 | dev_err(&pdev->dev, "failed to setup pads: %d\n", err); | 935 | dev_err(&pdev->dev, "failed to setup pads: %d\n", err); |
911 | goto reset; | 936 | goto power_down; |
912 | } | 937 | } |
913 | 938 | ||
914 | err = tegra_xusb_setup_ports(padctl); | 939 | err = tegra_xusb_setup_ports(padctl); |
@@ -921,6 +946,8 @@ static int tegra_xusb_padctl_probe(struct platform_device *pdev) | |||
921 | 946 | ||
922 | remove_pads: | 947 | remove_pads: |
923 | tegra_xusb_remove_pads(padctl); | 948 | tegra_xusb_remove_pads(padctl); |
949 | power_down: | ||
950 | regulator_bulk_disable(padctl->soc->num_supplies, padctl->supplies); | ||
924 | reset: | 951 | reset: |
925 | reset_control_assert(padctl->rst); | 952 | reset_control_assert(padctl->rst); |
926 | remove: | 953 | remove: |
@@ -936,6 +963,11 @@ static int tegra_xusb_padctl_remove(struct platform_device *pdev) | |||
936 | tegra_xusb_remove_ports(padctl); | 963 | tegra_xusb_remove_ports(padctl); |
937 | tegra_xusb_remove_pads(padctl); | 964 | tegra_xusb_remove_pads(padctl); |
938 | 965 | ||
966 | err = regulator_bulk_disable(padctl->soc->num_supplies, | ||
967 | padctl->supplies); | ||
968 | if (err < 0) | ||
969 | dev_err(&pdev->dev, "failed to disable supplies: %d\n", err); | ||
970 | |||
939 | err = reset_control_assert(padctl->rst); | 971 | err = reset_control_assert(padctl->rst); |
940 | if (err < 0) | 972 | if (err < 0) |
941 | dev_err(&pdev->dev, "failed to assert reset: %d\n", err); | 973 | dev_err(&pdev->dev, "failed to assert reset: %d\n", err); |
diff --git a/drivers/phy/tegra/xusb.h b/drivers/phy/tegra/xusb.h index bb60fc09c752..5d5d22f6cb41 100644 --- a/drivers/phy/tegra/xusb.h +++ b/drivers/phy/tegra/xusb.h | |||
@@ -370,6 +370,9 @@ struct tegra_xusb_padctl_soc { | |||
370 | } ports; | 370 | } ports; |
371 | 371 | ||
372 | const struct tegra_xusb_padctl_ops *ops; | 372 | const struct tegra_xusb_padctl_ops *ops; |
373 | |||
374 | const char * const *supply_names; | ||
375 | unsigned int num_supplies; | ||
373 | }; | 376 | }; |
374 | 377 | ||
375 | struct tegra_xusb_padctl { | 378 | struct tegra_xusb_padctl { |
@@ -393,6 +396,8 @@ struct tegra_xusb_padctl { | |||
393 | unsigned int enable; | 396 | unsigned int enable; |
394 | 397 | ||
395 | struct clk *clk; | 398 | struct clk *clk; |
399 | |||
400 | struct regulator_bulk_data *supplies; | ||
396 | }; | 401 | }; |
397 | 402 | ||
398 | static inline void padctl_writel(struct tegra_xusb_padctl *padctl, u32 value, | 403 | static inline void padctl_writel(struct tegra_xusb_padctl *padctl, u32 value, |