usb: ehci: Tegra: Disable parameters for PM QoS
Antti P Miettinen [Tue, 21 Aug 2012 07:56:38 +0000 (10:56 +0300)]
For testing purposes it is useful to be able to disable
CPU frequency boost.

Bug 1359445

Change-Id: I33a0369205a1df5cfe97915442e33511941686a8
Signed-off-by: Antti P Miettinen <amiettinen@nvidia.com>
Reviewed-on: http://git-master/r/273042
(cherry picked from commit 92f065702bfd07ea07b0fcd87edb4af0a3530868)
Reviewed-on: http://git-master/r/273586
Reviewed-by: Automatic_Commit_Validation_User
GVS: Gerrit_Virtual_Submit
Reviewed-by: Juha Tukkinen <jtukkinen@nvidia.com>

drivers/usb/host/ehci-tegra.c

index 0d9cac1..ed0aa9d 100644 (file)
@@ -59,6 +59,8 @@ struct tegra_ehci_hcd {
        bool unaligned_dma_buf_supported;
        bool has_hostpc;
 #ifdef CONFIG_TEGRA_EHCI_BOOST_CPU_FREQ
+       bool boost_enable;
+       bool boost_requested;
        bool cpu_boost_in_work;
        struct delayed_work boost_cpu_freq_work;
        struct pm_qos_request boost_cpu_freq_req;
@@ -165,9 +167,13 @@ 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);
+       if (tegra->cpu_boost_in_work) {
+               tegra->boost_requested = true;
+               if (tegra->boost_enable)
+                       pm_qos_update_request(
+                               &tegra->boost_cpu_freq_req,
+                               (s32)CONFIG_TEGRA_EHCI_BOOST_CPU_FREQ * 1000);
+       }
 }
 #endif
 
@@ -387,7 +393,9 @@ static int tegra_ehci_bus_suspend(struct usb_hcd *hcd)
        EHCI_DBG("%s() BEGIN\n", __func__);
 
 #ifdef CONFIG_TEGRA_EHCI_BOOST_CPU_FREQ
-       if (pm_qos_request_active(&tegra->boost_cpu_freq_req))
+       tegra->boost_requested = false;
+       if (tegra->boost_enable
+           && pm_qos_request_active(&tegra->boost_cpu_freq_req))
                pm_qos_update_request(&tegra->boost_cpu_freq_req,
                        PM_QOS_DEFAULT_VALUE);
        tegra->cpu_boost_in_work = false;
@@ -413,7 +421,9 @@ static int tegra_ehci_bus_resume(struct usb_hcd *hcd)
        EHCI_DBG("%s() BEGIN\n", __func__);
 
 #ifdef CONFIG_TEGRA_EHCI_BOOST_CPU_FREQ
-       if (pm_qos_request_active(&tegra->boost_cpu_freq_req))
+       tegra->boost_requested = true;
+       if (pm_qos_request_active(&tegra->boost_cpu_freq_req)
+           && tegra->boost_enable)
                pm_qos_update_request(&tegra->boost_cpu_freq_req,
                        (s32)CONFIG_TEGRA_EHCI_BOOST_CPU_FREQ * 1000);
        tegra->cpu_boost_in_work = false;
@@ -490,6 +500,44 @@ static int setup_vbus_gpio(struct platform_device *pdev)
 
 static u64 tegra_ehci_dma_mask = DMA_BIT_MASK(32);
 
+#ifdef CONFIG_TEGRA_EHCI_BOOST_CPU_FREQ
+static ssize_t show_boost_enable(struct device *dev,
+                                struct device_attribute *attr,
+                                char *buf)
+{
+       struct tegra_ehci_hcd *tegra = dev_get_drvdata(dev);
+       return scnprintf(buf, PAGE_SIZE, "%s\n",
+                        tegra->boost_enable ? "Y" : "N");
+}
+
+
+static ssize_t store_boost_enable(struct device *dev,
+                                 struct device_attribute *attr,
+                                 const char *buf, size_t count)
+{
+       struct tegra_ehci_hcd *tegra = dev_get_drvdata(dev);
+       bool new_boost;
+       bool old_boost = tegra->boost_enable;
+
+       if (strtobool(buf, &new_boost) == 0) {
+               tegra->boost_enable = new_boost;
+               if (!old_boost && new_boost
+                   && tegra->boost_requested
+                   && pm_qos_request_active(&tegra->boost_cpu_freq_req))
+                       pm_qos_update_request(
+                               &tegra->boost_cpu_freq_req,
+                               (s32)CONFIG_TEGRA_EHCI_BOOST_CPU_FREQ * 1000);
+               else if (old_boost && !new_boost
+                        && pm_qos_request_active(&tegra->boost_cpu_freq_req))
+                       pm_qos_update_request(&tegra->boost_cpu_freq_req,
+                                             PM_QOS_DEFAULT_VALUE);
+       }
+       return count;
+}
+static DEVICE_ATTR(boost_enable, 0644,
+                  show_boost_enable, store_boost_enable);
+#endif
+
 static int tegra_ehci_probe(struct platform_device *pdev)
 {
        struct resource *res;
@@ -527,6 +575,15 @@ static int tegra_ehci_probe(struct platform_device *pdev)
 
        platform_set_drvdata(pdev, tegra);
 
+#ifdef CONFIG_TEGRA_EHCI_BOOST_CPU_FREQ
+       tegra->boost_requested = false;
+       /* Add boost enable/disable knob */
+       tegra->boost_enable = true;
+       err = device_create_file(hcd->self.controller, &dev_attr_boost_enable);
+       if (err < 0)
+               goto fail_sysfs;
+#endif
+
        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
        if (!res) {
                dev_err(&pdev->dev, "failed to get I/O memory\n");
@@ -636,6 +693,10 @@ fail_phy:
 fail_irq:
        iounmap(hcd->regs);
 fail_io:
+#ifdef CONFIG_TEGRA_EHCI_BOOST_CPU_FREQ
+       device_remove_file(hcd->self.controller, &dev_attr_boost_enable);
+fail_sysfs:
+#endif
        usb_put_hcd(hcd);
 
        return err;
@@ -724,6 +785,9 @@ static int tegra_ehci_remove(struct platform_device *pdev)
        tegra_usb_phy_power_off(tegra->phy);
        usb_phy_shutdown(get_usb_phy(tegra->phy));
        iounmap(hcd->regs);
+#ifdef CONFIG_TEGRA_EHCI_BOOST_CPU_FREQ
+       device_remove_file(hcd->self.controller, &dev_attr_boost_enable);
+#endif
        usb_put_hcd(hcd);
 
        return 0;