usb: xhci: tegra: clear SMI_INTR when ENABLE_BW msg
Ajay Gupta [Sat, 1 Jun 2013 00:05:37 +0000 (17:05 -0700)]
SMI_INTR also needs to be cleared as part of handling ENABLE_BW
firmware message.

Also fixed a locking related issue in enable_fw_message()

Bug 1297966

Change-Id: Ia4c9ccf0316240b0e966a6510d665a549c8ba711
Signed-off-by: Ajay Gupta <ajayg@nvidia.com>
Reviewed-on: http://git-master/r/234723
Reviewed-by: Harshada Kale <hkale@nvidia.com>
Tested-by: Harshada Kale <hkale@nvidia.com>

drivers/usb/host/xhci-tegra.c

index d740fb3..6fc16db 100644 (file)
@@ -1404,6 +1404,7 @@ static void tegra_xhci_enable_fw_message(struct tegra_xhci_hcd *tegra)
 
        if ((timeout == 0) && (reg != MBOX_OWNER_SW)) {
                dev_err(&pdev->dev, "Failed to set mbox message owner ID\n");
+               mutex_unlock(&tegra->mbox_lock);
                return;
        }
 
@@ -2058,7 +2059,6 @@ tegra_xhci_process_mbox_message(struct work_struct *work)
                                        mbox_work);
        struct xhci_hcd *xhci = tegra->xhci;
        unsigned int freq_khz;
-       bool send_ack_to_fw = true;
 
        mutex_lock(&tegra->mbox_lock);
 
@@ -2111,11 +2111,14 @@ tegra_xhci_process_mbox_message(struct work_struct *work)
                freq_khz = tegra_emc_bw_to_freq_req(tegra->cmd_data << 10);
                clk_set_rate(tegra->emc_clk, freq_khz * 1000);
 
+               /* clear MBOX_SMI_INT_EN bit */
+               cmd = readl(tegra->fpci_base + XUSB_CFG_ARU_MBOX_CMD);
+               cmd &= ~MBOX_SMI_INT_EN;
+               writel(cmd, tegra->fpci_base + XUSB_CFG_ARU_MBOX_CMD);
+
                /* clear mbox owner as ACK will not be sent for this request */
                writel(0, tegra->fpci_base + XUSB_CFG_ARU_MBOX_OWNER);
-               send_ack_to_fw = false;
-
-               goto send_sw_response;
+               break;
        case MBOX_CMD_SAVE_DFE_CTLE_CTX:
                tegra_xhci_save_dfe_ctle_context(tegra, tegra->cmd_data);
                tegra_xhci_restore_dfe_ctle_context(tegra, tegra->cmd_data);
@@ -2137,12 +2140,10 @@ tegra_xhci_process_mbox_message(struct work_struct *work)
        return;
 
 send_sw_response:
-       if (send_ack_to_fw) {
-               writel(sw_resp, tegra->fpci_base + XUSB_CFG_ARU_MBOX_DATA_IN);
-               cmd = readl(tegra->fpci_base + XUSB_CFG_ARU_MBOX_CMD);
-               cmd |= MBOX_INT_EN | MBOX_FALC_INT_EN;
-               writel(cmd, tegra->fpci_base + XUSB_CFG_ARU_MBOX_CMD);
-       }
+       writel(sw_resp, tegra->fpci_base + XUSB_CFG_ARU_MBOX_DATA_IN);
+       cmd = readl(tegra->fpci_base + XUSB_CFG_ARU_MBOX_CMD);
+       cmd |= MBOX_INT_EN | MBOX_FALC_INT_EN;
+       writel(cmd, tegra->fpci_base + XUSB_CFG_ARU_MBOX_CMD);
 
        mutex_unlock(&tegra->mbox_lock);
 }