mirror of
https://github.com/torvalds/linux.git
synced 2026-05-22 22:22:08 +02:00
usb: chipidea: tegra: Add runtime PM and OPP support
The Tegra USB controller belongs to the core power domain and we're going to enable GENPD support for the core domain. Now USB controller must be resumed using runtime PM API in order to initialize the USB power state. We already support runtime PM for the CI device, but CI's PM is separated from the RPM managed by tegra-usb driver. Add runtime PM and OPP support to the driver. Acked-by: Peter Chen <peter.chen@kernel.org> Reviewed-by: Ulf Hansson <ulf.hansson@linaro.org> Signed-off-by: Dmitry Osipenko <digetx@gmail.com> Signed-off-by: Thierry Reding <treding@nvidia.com>
This commit is contained in:
parent
c132bc881f
commit
8b85e11c1a
|
|
@ -7,6 +7,7 @@
|
|||
#include <linux/io.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
#include <linux/reset.h>
|
||||
|
||||
#include <linux/usb.h>
|
||||
|
|
@ -15,6 +16,8 @@
|
|||
#include <linux/usb/of.h>
|
||||
#include <linux/usb/phy.h>
|
||||
|
||||
#include <soc/tegra/common.h>
|
||||
|
||||
#include "../host/ehci.h"
|
||||
|
||||
#include "ci.h"
|
||||
|
|
@ -278,6 +281,8 @@ static int tegra_usb_probe(struct platform_device *pdev)
|
|||
if (!usb)
|
||||
return -ENOMEM;
|
||||
|
||||
platform_set_drvdata(pdev, usb);
|
||||
|
||||
soc = of_device_get_match_data(&pdev->dev);
|
||||
if (!soc) {
|
||||
dev_err(&pdev->dev, "failed to match OF data\n");
|
||||
|
|
@ -296,11 +301,14 @@ static int tegra_usb_probe(struct platform_device *pdev)
|
|||
return err;
|
||||
}
|
||||
|
||||
err = clk_prepare_enable(usb->clk);
|
||||
if (err < 0) {
|
||||
dev_err(&pdev->dev, "failed to enable clock: %d\n", err);
|
||||
err = devm_tegra_core_dev_init_opp_table_common(&pdev->dev);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
pm_runtime_enable(&pdev->dev);
|
||||
err = pm_runtime_resume_and_get(&pdev->dev);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
|
||||
if (device_property_present(&pdev->dev, "nvidia,needs-double-reset"))
|
||||
usb->needs_double_reset = true;
|
||||
|
|
@ -320,8 +328,6 @@ static int tegra_usb_probe(struct platform_device *pdev)
|
|||
if (err)
|
||||
goto fail_power_off;
|
||||
|
||||
platform_set_drvdata(pdev, usb);
|
||||
|
||||
/* setup and register ChipIdea HDRC device */
|
||||
usb->soc = soc;
|
||||
usb->data.name = "tegra-usb";
|
||||
|
|
@ -350,7 +356,9 @@ static int tegra_usb_probe(struct platform_device *pdev)
|
|||
phy_shutdown:
|
||||
usb_phy_shutdown(usb->phy);
|
||||
fail_power_off:
|
||||
clk_disable_unprepare(usb->clk);
|
||||
pm_runtime_put_sync_suspend(&pdev->dev);
|
||||
pm_runtime_force_suspend(&pdev->dev);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
|
|
@ -360,15 +368,46 @@ static int tegra_usb_remove(struct platform_device *pdev)
|
|||
|
||||
ci_hdrc_remove_device(usb->dev);
|
||||
usb_phy_shutdown(usb->phy);
|
||||
|
||||
pm_runtime_put_sync_suspend(&pdev->dev);
|
||||
pm_runtime_force_suspend(&pdev->dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __maybe_unused tegra_usb_runtime_resume(struct device *dev)
|
||||
{
|
||||
struct tegra_usb *usb = dev_get_drvdata(dev);
|
||||
int err;
|
||||
|
||||
err = clk_prepare_enable(usb->clk);
|
||||
if (err < 0) {
|
||||
dev_err(dev, "failed to enable clock: %d\n", err);
|
||||
return err;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __maybe_unused tegra_usb_runtime_suspend(struct device *dev)
|
||||
{
|
||||
struct tegra_usb *usb = dev_get_drvdata(dev);
|
||||
|
||||
clk_disable_unprepare(usb->clk);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct dev_pm_ops tegra_usb_pm = {
|
||||
SET_RUNTIME_PM_OPS(tegra_usb_runtime_suspend, tegra_usb_runtime_resume,
|
||||
NULL)
|
||||
};
|
||||
|
||||
static struct platform_driver tegra_usb_driver = {
|
||||
.driver = {
|
||||
.name = "tegra-usb",
|
||||
.of_match_table = tegra_usb_of_match,
|
||||
.pm = &tegra_usb_pm,
|
||||
},
|
||||
.probe = tegra_usb_probe,
|
||||
.remove = tegra_usb_remove,
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user