if (temp & SMI_INTR_STATUS_FW_REINIT)
xhci_err(tegra->xhci, "Firmware reinit.\n");
if (temp & SMI_INTR_STATUS_MBOX)
- schedule_work(&tegra->mbox_work);
+ queue_work(tegra->mbox_wq, &tegra->mbox_work);
spin_unlock(&tegra->lock);
return IRQ_HANDLED;
/* do mailbox related initializations */
tegra->mbox_owner = 0xffff;
INIT_WORK(&tegra->mbox_work, tegra_xhci_process_mbox_message);
+ tegra->mbox_wq = alloc_ordered_workqueue("mbox_wq", 0);
+ if (IS_ERR_OR_NULL(tegra->mbox_wq)) {
+ dev_err(&pdev->dev, "failed to alloc workqueue\n");
+ ret = -ENOMEM;
+ goto err_remove_usb3_hcd;
+ }
/* do ss partition elpg exit related initialization */
INIT_WORK(&tegra->ss_elpg_exit_work, ss_partition_elpg_exit_work);
usb_put_hcd(hcd);
kfree(xhci);
+ flush_workqueue(tegra->mbox_wq);
+ destroy_workqueue(tegra->mbox_wq);
+
#if defined(CONFIG_ARCH_TEGRA_21x_SOC)
/* By default disable the BATTERY_CHRG_OTGPAD for all ports */
for (port = 0; port <= XUSB_UTMI_COUNT; port++)
int vddio_hsic_refcnt;
struct work_struct mbox_work;
+ struct workqueue_struct *mbox_wq;
struct work_struct ss_elpg_exit_work;
struct work_struct host_elpg_exit_work;
struct work_struct xotg_vbus_work;