xhci: tegra: run firmware log thread only if need
JC Kuo [Wed, 20 May 2015 06:19:24 +0000 (14:19 +0800)]
Driver doesn't need to run a kernel thread to collect firmware log
if release build firmware is loaded. Only debug build firmware is
capable of generating logs. This commit checks firmware CFGTBL to
know whether a firmware generates logs or not.

bug 1487603

Change-Id: I8b147710dae58332d68625fedd3173e2d2f6074b
Signed-off-by: JC Kuo <jckuo@nvidia.com>
Reviewed-on: http://git-master/r/663769
(cherry picked from commit bc339c3a63ea18fbbe568c99e33d06d637ad1f71)
Reviewed-on: http://git-master/r/744725
GVS: Gerrit_Virtual_Submit
Tested-by: Mark Kuo <mkuo@nvidia.com>
Reviewed-by: WK Tsai <wtsai@nvidia.com>
Reviewed-by: Bibek Basu <bbasu@nvidia.com>
Reviewed-by: Matthew Pedro <mapedro@nvidia.com>
Reviewed-by: Ashutosh Jha <ajha@nvidia.com>

drivers/usb/host/xhci-tegra.c

index 8a4c53d..2081be4 100644 (file)
@@ -131,6 +131,11 @@ struct log_entry {
        u8 owner;
 };
 
+enum build_info_log {
+       LOG_NONE = 0,
+       LOG_MEMORY
+};
+
 /* Usb3 Firmware Cfg Table */
 struct cfgtbl {
        u32 boot_loadaddr_in_imem;
@@ -181,7 +186,9 @@ struct cfgtbl {
        u32 SS_low_power_entry_timeout;
        u8 num_hsic_port;
        u8 ss_portmap;
-       u8 padding[138]; /* padding bytes to makeup 256-bytes cfgtbl */
+       u8 build_log:4;
+       u8 build_type:4;
+       u8 padding[137]; /* padding bytes to makeup 256-bytes cfgtbl */
 };
 
 struct xusb_save_regs {
@@ -2482,8 +2489,10 @@ static int load_firmware(struct tegra_xhci_hcd *tegra, bool resetARU)
        }
 
        /* update the phys_log_buffer and total_entries here */
-       cfg_tbl->phys_addr_log_buffer = tegra->log.phys_addr;
-       cfg_tbl->total_log_entries = FW_LOG_COUNT;
+       if (test_bit(FW_LOG_CONTEXT_VALID, &tegra->log.flags)) {
+               cfg_tbl->phys_addr_log_buffer = tegra->log.phys_addr;
+               cfg_tbl->total_log_entries = FW_LOG_COUNT;
+       }
 
        phys_addr_lo = tegra->firmware.dma;
        phys_addr_lo += sizeof(struct cfgtbl);
@@ -3504,10 +3513,12 @@ static int tegra_xhci_bus_suspend(struct usb_hcd *hcd)
        tegra_xhci_hs_wake_on_interrupts(tegra->bdata->portmap, true);
 
        /* In ELPG, firmware log context is gone. Rewind shared log buffer. */
-       if (fw_log_wait_empty_timeout(tegra, 100))
-               xhci_warn(xhci, "%s still has logs\n", __func__);
-       tegra->log.dequeue = tegra->log.virt_addr;
-       tegra->log.seq = 0;
+       if (test_bit(FW_LOG_CONTEXT_VALID, &tegra->log.flags)) {
+               if (fw_log_wait_empty_timeout(tegra, 100))
+                       xhci_warn(xhci, "%s still has logs\n", __func__);
+               tegra->log.dequeue = tegra->log.virt_addr;
+               tegra->log.seq = 0;
+       }
 
 done:
        /* pads are disabled only if usb2 root hub in xusb is idle */
@@ -3608,7 +3619,8 @@ static irqreturn_t tegra_xhci_irq(struct usb_hcd *hcd)
                iret = xhci_irq(hcd);
        spin_unlock(&tegra->lock);
 
-       wake_up_interruptible(&tegra->log.intr_wait);
+       if (test_bit(FW_LOG_CONTEXT_VALID, &tegra->log.flags))
+               wake_up_interruptible(&tegra->log.intr_wait);
 
        return iret;
 }
@@ -3794,6 +3806,9 @@ static void init_filesystem_firmware_done(const struct firmware *fw,
        dev_info(&pdev->dev, "Firmware File: %s (%d Bytes)\n",
                        firmware_file, fw_size);
 
+       if (fw_cfgtbl->build_log == LOG_MEMORY)
+               fw_log_init(tegra);
+
        fw_data = dma_alloc_coherent(&pdev->dev, fw_size,
                        &fw_dma, GFP_KERNEL);
        if (!fw_data) {
@@ -4369,7 +4384,6 @@ static int tegra_xhci_probe(struct platform_device *pdev)
                return ret;
        }
 
-       fw_log_init(tegra);
        ret = init_firmware(tegra);
        if (ret < 0) {
                dev_err(&pdev->dev, "failed to init firmware\n");