diff options
author | Rohith Seelaboyina <rseelaboyina@nvidia.com> | 2013-05-09 09:53:23 +0530 |
---|---|---|
committer | Dan Willemsen <dwillemsen@nvidia.com> | 2013-09-14 13:13:47 -0700 |
commit | da2322653548d8bacfb4f6a853d17b9717b1ddb3 (patch) | |
tree | be670087efcbb5d276fac981cb369ea60c6b07d5 /drivers/usb | |
parent | 19692dca9441729d5ae0a78be657d0e75ab6b9e2 (diff) |
usb: host: tegra: boost cpu frequency when bus is active
Boost cpu frequency (based upon TEGRA_EHCI_BOOST_CPU_FREQ)
when the usb bus is active and remove the boost when usb
bus is suspended.
Bug 1266414
Change-Id: Ic5b7b1ecc923caf7da458383112ed0e647448a57
Signed-off-by: Rohith Seelaboyina <rseelaboyina@nvidia.com>
Reviewed-on: http://git-master/r/226914
(cherry picked from commit 85c49d81cd5c6760567a44878fedbc09c422841d)
Reviewed-on: http://git-master/r/227803
Reviewed-by: Automatic_Commit_Validation_User
Reviewed-by: Venkat Moganty <vmoganty@nvidia.com>
Diffstat (limited to 'drivers/usb')
-rw-r--r-- | drivers/usb/host/ehci-tegra.c | 47 |
1 files changed, 47 insertions, 0 deletions
diff --git a/drivers/usb/host/ehci-tegra.c b/drivers/usb/host/ehci-tegra.c index 1253db2a0c4a..f715aafcd3dc 100644 --- a/drivers/usb/host/ehci-tegra.c +++ b/drivers/usb/host/ehci-tegra.c @@ -29,6 +29,7 @@ #include <linux/usb/tegra_usb_phy.h> #include <mach/pm_domains.h> +#include <linux/pm_qos.h> /* HACK! This needs to come from DT */ #include "../../../arch/arm/mach-tegra/iomap.h" @@ -62,6 +63,11 @@ struct tegra_ehci_hcd { bool bus_suspended_fail; bool unaligned_dma_buf_supported; bool has_hostpc; +#ifdef CONFIG_TEGRA_EHCI_BOOST_CPU_FREQ + bool cpu_boost_in_work; + struct delayed_work boost_cpu_freq_work; + struct pm_qos_request boost_cpu_freq_req; +#endif }; struct dma_align_buffer { @@ -161,6 +167,17 @@ static void tegra_ehci_unmap_urb_for_dma(struct usb_hcd *hcd, free_align_buffer(urb, hcd); } +#ifdef CONFIG_TEGRA_EHCI_BOOST_CPU_FREQ +static void tegra_ehci_boost_cpu_frequency_work(struct work_struct *work) +{ + struct tegra_ehci_hcd *tegra = container_of(work, + struct tegra_ehci_hcd, boost_cpu_freq_work.work); + if (tegra->cpu_boost_in_work) + pm_qos_update_request(&tegra->boost_cpu_freq_req, + (s32)CONFIG_TEGRA_EHCI_BOOST_CPU_FREQ * 1000); +} +#endif + static irqreturn_t tegra_ehci_irq(struct usb_hcd *hcd) { struct tegra_ehci_hcd *tegra = dev_get_drvdata(hcd->self.controller); @@ -359,6 +376,13 @@ static int tegra_ehci_bus_suspend(struct usb_hcd *hcd) struct tegra_ehci_hcd *tegra = dev_get_drvdata(hcd->self.controller); int err = 0; EHCI_DBG("%s() BEGIN\n", __func__); + +#ifdef CONFIG_TEGRA_EHCI_BOOST_CPU_FREQ + pm_qos_update_request(&tegra->boost_cpu_freq_req, + PM_QOS_DEFAULT_VALUE); + tegra->cpu_boost_in_work = false; +#endif + mutex_lock(&tegra->sync_lock); tegra->bus_suspended_fail = false; err = ehci_bus_suspend(hcd); @@ -378,6 +402,13 @@ static int tegra_ehci_bus_resume(struct usb_hcd *hcd) int err = 0; EHCI_DBG("%s() BEGIN\n", __func__); +#ifdef CONFIG_TEGRA_EHCI_BOOST_CPU_FREQ + pm_qos_update_request(&tegra->boost_cpu_freq_req, + (s32)CONFIG_TEGRA_EHCI_BOOST_CPU_FREQ * 1000); + tegra->cpu_boost_in_work = false; + +#endif + mutex_lock(&tegra->sync_lock); usb_phy_set_suspend(get_usb_phy(tegra->phy), 0); err = ehci_bus_resume(hcd); @@ -581,6 +612,15 @@ static int tegra_ehci_probe(struct platform_device *pdev) tegra_pd_add_device(&pdev->dev); pm_runtime_enable(&pdev->dev); +#ifdef CONFIG_TEGRA_EHCI_BOOST_CPU_FREQ + INIT_DELAYED_WORK(&tegra->boost_cpu_freq_work, + tegra_ehci_boost_cpu_frequency_work); + pm_qos_add_request(&tegra->boost_cpu_freq_req, PM_QOS_CPU_FREQ_MIN, + PM_QOS_DEFAULT_VALUE); + schedule_delayed_work(&tegra->boost_cpu_freq_work, 4000); + tegra->cpu_boost_in_work = true; +#endif + return err; fail_phy: @@ -624,6 +664,13 @@ static int tegra_ehci_remove(struct platform_device *pdev) struct tegra_ehci_hcd *tegra = platform_get_drvdata(pdev); struct usb_hcd *hcd = ehci_to_hcd(tegra->ehci); +#ifdef CONFIG_TEGRA_EHCI_BOOST_CPU_FREQ + cancel_delayed_work(&tegra->boost_cpu_freq_work); + pm_qos_update_request(&tegra->boost_cpu_freq_req, + PM_QOS_DEFAULT_VALUE); + tegra->cpu_boost_in_work = false; +#endif + if (!IS_ERR(tegra->transceiver)) otg_set_host(tegra->transceiver->otg, NULL); |