Merge "Update EdgeTPU PCIe registers in the device tree"
diff --git a/drivers/soc/imx/gpc-psci.c b/drivers/soc/imx/gpc-psci.c
index d3867e1..0505bce 100644
--- a/drivers/soc/imx/gpc-psci.c
+++ b/drivers/soc/imx/gpc-psci.c
@@ -52,6 +52,9 @@
static DEFINE_SPINLOCK(gpc_psci_lock);
static DEFINE_MUTEX(gpc_pd_mutex);
+/* USB1 port power domain */
+static bool usb1_on = false;
+
static void imx_gpc_psci_irq_unmask(struct irq_data *d)
{
struct arm_smccc_res res;
@@ -202,6 +205,9 @@
struct arm_smccc_res res;
int index, ret = 0;
+ if (usb1_on && pd->gpc_domain_id == 3)
+ return 0;
+
/* power on the external supply */
if (pd->reg) {
ret = regulator_enable(pd->reg);
@@ -222,6 +228,9 @@
GPC_PD_STATE_ON, 0, 0, 0, 0, &res);
mutex_unlock(&gpc_pd_mutex);
+ if (pd->gpc_domain_id == 3)
+ usb1_on = true;
+
return 0;
}
@@ -231,6 +240,9 @@
struct arm_smccc_res res;
int index, ret = 0;
+ if (pd->gpc_domain_id == 3)
+ return 0;
+
mutex_lock(&gpc_pd_mutex);
arm_smccc_smc(FSL_SIP_GPC, FSL_SIP_CONFIG_GPC_PM_DOMAIN, pd->gpc_domain_id,
GPC_PD_STATE_OFF, 0, 0, 0, 0, &res);
diff --git a/drivers/soc/imx/sc/main/ipc.c b/drivers/soc/imx/sc/main/ipc.c
index c070089..be1e265 100644
--- a/drivers/soc/imx/sc/main/ipc.c
+++ b/drivers/soc/imx/sc/main/ipc.c
@@ -7,6 +7,7 @@
/* Includes */
#include <linux/arm-smccc.h>
+#include <linux/completion.h>
#include <linux/err.h>
#include <linux/kernel.h>
#include <linux/of.h>
@@ -18,6 +19,7 @@
#include <linux/irq.h>
#include <linux/mx8_mu.h>
#include <linux/syscore_ops.h>
+#include <linux/suspend.h>
#include <soc/imx/fsl_hvc.h>
#include <soc/imx8/sc/svc/irq/api.h>
@@ -39,7 +41,9 @@
/* Local variables */
static uint32_t gIPCport;
+static sc_rpc_msg_t *rx_msg;
static bool scu_mu_init;
+struct completion rx_completion;
DEFINE_MUTEX(scu_mu_mutex);
@@ -57,6 +61,7 @@
void sc_call_rpc(sc_ipc_t handle, sc_rpc_msg_t *msg, sc_bool_t no_resp)
{
struct arm_smccc_res res;
+ unsigned long timeout;
if (in_interrupt()) {
pr_warn("Cannot make SC IPC calls from an interrupt context\n");
@@ -65,6 +70,8 @@
}
mutex_lock(&scu_mu_mutex);
+ reinit_completion(&rx_completion);
+ rx_msg = msg;
if (xen_initial_domain()) {
arm_smccc_hvc(FSL_HVC_SC, (uint64_t)msg, no_resp, 0, 0, 0, 0,
0, &res);
@@ -72,8 +79,14 @@
printk("Error FSL_HVC_SC %ld\n", res.a0);
} else {
sc_ipc_write(handle, msg);
- if (!no_resp)
- sc_ipc_read(handle, msg);
+ if (!no_resp) {
+ timeout = wait_for_completion_timeout(&rx_completion, HZ / 10);
+ if (!timeout) {
+ pr_err("Timeout for IPC response!\n");
+ mutex_unlock(&scu_mu_mutex);
+ return;
+ }
+ }
}
mutex_unlock(&scu_mu_mutex);
@@ -285,12 +298,19 @@
{
u32 irqs;
+ irqs = (readl_relaxed(mu_base_virtaddr + 0x20) & (0xf << 24));
+ if (irqs) {
+ sc_ipc_read(mu_ipcHandle, rx_msg);
+ complete(&rx_completion);
+ }
+
irqs = (readl_relaxed(mu_base_virtaddr + 0x20) & (0xf << 28));
if (irqs) {
/* Clear the General Interrupt */
writel_relaxed(irqs, mu_base_virtaddr + 0x20);
/* Setup a bottom-half to handle the irq work. */
schedule_delayed_work(&scu_mu_work, 0);
+ pm_system_wakeup();
}
return IRQ_HANDLED;
}
@@ -300,6 +320,7 @@
int i;
MU_Init(mu_base_virtaddr);
+ MU_EnableRxFullInt(mu_base_virtaddr, 0);
for (i = 0; i < MU_RR_COUNT; i++)
MU_EnableGeneralInt(mu_base_virtaddr, i);
}
@@ -338,7 +359,7 @@
pr_warn("imx8_mu_init: no irq: %d\n", irq);
} else {
err = request_irq(irq, imx8_scu_mu_isr,
- IRQF_EARLY_RESUME, "imx8_mu_isr", NULL);
+ IRQF_NO_SUSPEND, "imx8_mu_isr", NULL);
if (err) {
pr_err("imx8_mu_init: request_irq %d failed: %d\n",
irq, err);
@@ -355,6 +376,7 @@
/* Init MU */
MU_Init(mu_base_virtaddr);
+ MU_EnableRxFullInt(mu_base_virtaddr, 0);
#if 1
/* Enable all RX interrupts */
@@ -363,6 +385,7 @@
#endif
gIPCport = scu_mu_id;
scu_mu_init = true;
+ init_completion(&rx_completion);
}
sciErr = sc_ipc_open(&mu_ipcHandle, scu_mu_id);
diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h
index 090c864..f7e0891 100644
--- a/drivers/usb/dwc3/core.h
+++ b/drivers/usb/dwc3/core.h
@@ -45,6 +45,7 @@
#define DWC3_EP0_SETUP_SIZE 512
#define DWC3_ENDPOINTS_NUM 32
#define DWC3_XHCI_RESOURCES_NUM 2
+#define DWC3_ISOC_MAX_RETRIES 5
#define DWC3_SCRATCHBUF_SIZE 4096 /* each buffer is assumed to be 4KiB */
#define DWC3_EVENT_BUFFERS_SIZE 4096
diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
index 9d91a8c..23d461a 100644
--- a/drivers/usb/dwc3/gadget.c
+++ b/drivers/usb/dwc3/gadget.c
@@ -36,6 +36,9 @@
#include "gadget.h"
#include "io.h"
+#define DWC3_ALIGN_FRAME(d, uf, n) ((uf + ((d)->interval * (n))) \
+ & ~((d)->interval - 1))
+
/**
* dwc3_gadget_set_test_mode - enables usb2 test modes
* @dwc: pointer to our context structure
@@ -1272,7 +1275,7 @@
static void __dwc3_gadget_start_isoc(struct dwc3 *dwc,
struct dwc3_ep *dep, u32 cur_uf)
{
- u32 uf;
+ int ret, i;
if (list_empty(&dep->pending_list)) {
dev_info(dwc->dev, "%s: ran out of requests\n",
@@ -1281,13 +1284,13 @@
return;
}
- /*
- * Schedule the first trb for one interval in the future or at
- * least 4 microframes.
- */
- uf = cur_uf + max_t(u32, 4, dep->interval);
-
- __dwc3_gadget_kick_transfer(dep, uf);
+ for (i = 0; i < DWC3_ISOC_MAX_RETRIES; i++) {
+ /* always start isochronous aligned to dep->interval */
+ cur_uf = DWC3_ALIGN_FRAME(dep, cur_uf, i + 1);
+ ret = __dwc3_gadget_kick_transfer(dep, cur_uf);
+ if (ret != -EAGAIN)
+ break;
+ }
}
static void dwc3_gadget_start_isoc(struct dwc3 *dwc,
diff --git a/drivers/usb/host/xhci-plat.c b/drivers/usb/host/xhci-plat.c
index eaed46b..2d56c1e 100644
--- a/drivers/usb/host/xhci-plat.c
+++ b/drivers/usb/host/xhci-plat.c
@@ -301,6 +301,7 @@
if (ret)
goto dealloc_usb2_hcd;
+ device_set_wakeup_capable(&pdev->dev, true);
device_enable_async_suspend(&pdev->dev);
pm_runtime_put_noidle(&pdev->dev);
@@ -364,7 +365,7 @@
{
struct usb_hcd *hcd = dev_get_drvdata(dev);
struct xhci_hcd *xhci = hcd_to_xhci(hcd);
-
+#if 0
/*
* xhci_suspend() needs `do_wakeup` to know whether host is allowed
* to do wakeup during suspend. Since xhci_plat_suspend is currently
@@ -374,6 +375,11 @@
* also applies to runtime suspend.
*/
return xhci_suspend(xhci, device_may_wakeup(dev));
+#endif
+ if (device_may_wakeup(dev))
+ enable_irq_wake(hcd->irq);
+
+ return 0;
}
static int __maybe_unused xhci_plat_resume(struct device *dev)
@@ -382,11 +388,17 @@
struct xhci_hcd *xhci = hcd_to_xhci(hcd);
int ret;
+#if 0
ret = xhci_priv_resume_quirk(hcd);
if (ret)
return ret;
return xhci_resume(xhci, 0);
+#endif
+ if (device_may_wakeup(dev))
+ disable_irq_wake(hcd->irq);
+
+ return 0;
}
static int __maybe_unused xhci_plat_runtime_suspend(struct device *dev)