xhci: tegra: fix ACK/NACK mbox message processing
JC Kuo [Wed, 16 Oct 2013 10:47:41 +0000 (18:47 +0800)]
Driver should not write 0 to XUSB_CFG_ARU_MAILBOX_CMD register,
because clearing USB_CFG_ARU_MAILBOX_CMD_INT_EN bit means disabling
mailbox messaging from firmware's perspective.

bug 1389380

Change-Id: I7b9d860c3069ef0342066f5a1823a99d271c2ec8
Signed-off-by: JC Kuo <jckuo@nvidia.com>
Reviewed-on: http://git-master/r/299941
Reviewed-by: Bharat Nihalani <bnihalani@nvidia.com>
Tested-by: Bharat Nihalani <bnihalani@nvidia.com>

drivers/usb/host/xhci-tegra.c

index ce2108d..3ee60a3 100644 (file)
@@ -3148,19 +3148,13 @@ tegra_xhci_process_mbox_message(struct work_struct *work)
                        xhci_err(xhci, "%s: could not set required ss rate.\n",
                                __func__);
                goto send_sw_response;
+
        case MBOX_CMD_SET_BW:
                /* fw sends BW request in MByte/sec */
                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);
                break;
+
        case MBOX_CMD_SAVE_DFE_CTLE_CTX:
                tegra_xhci_save_dfe_context(tegra, tegra->cmd_data);
                tegra_xhci_save_ctle_context(tegra, tegra->cmd_data);
@@ -3205,17 +3199,24 @@ tegra_xhci_process_mbox_message(struct work_struct *work)
                goto send_sw_response;
 
        case MBOX_CMD_ACK:
-               writel(0, tegra->fpci_base + XUSB_CFG_ARU_MBOX_CMD);
-               writel(0, tegra->fpci_base + XUSB_CFG_ARU_MBOX_OWNER);
+               xhci_dbg(xhci, "%s firmware responds with ACK\n", __func__);
                break;
        case MBOX_CMD_NACK:
-               writel(0, tegra->fpci_base + XUSB_CFG_ARU_MBOX_CMD);
-               writel(0, tegra->fpci_base + XUSB_CFG_ARU_MBOX_OWNER);
+               xhci_warn(xhci, "%s firmware responds with NACK\n", __func__);
                break;
        default:
                xhci_err(xhci, "%s: invalid cmdtype %d\n",
                                __func__, tegra->cmd_type);
        }
+
+       /* 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 mailbox ownership */
+       writel(0, tegra->fpci_base + XUSB_CFG_ARU_MBOX_OWNER);
+
        mutex_unlock(&tegra->mbox_lock);
        return;