Merge "USB: ehci-msm-hsic: Apply PHY lockup workarounds only for affected cores"
diff --git a/Documentation/devicetree/bindings/usb/msm-ehci-hsic.txt b/Documentation/devicetree/bindings/usb/msm-ehci-hsic.txt
index 1fb2ba9..6ea9e62 100644
--- a/Documentation/devicetree/bindings/usb/msm-ehci-hsic.txt
+++ b/Documentation/devicetree/bindings/usb/msm-ehci-hsic.txt
@@ -38,6 +38,9 @@
STROBE GPIO PAD.
- hsic,data-pad-offset : Offset of TLMM register for configuring HSIC
DATA GPIO PAD.
+- qcom,phy-sof-workaround : If present then HSIC PHY has h/w BUGs related to
+ SOFs. Software workarounds are required for the same.
+
- Refer to "Documentation/devicetree/bindings/arm/msm/msm_bus.txt" for
below optional properties:
- qcom,msm_bus,name
diff --git a/arch/arm/boot/dts/msm8974-v1-cdp.dts b/arch/arm/boot/dts/msm8974-v1-cdp.dts
index 33bd1fb..bbefe88 100644
--- a/arch/arm/boot/dts/msm8974-v1-cdp.dts
+++ b/arch/arm/boot/dts/msm8974-v1-cdp.dts
@@ -25,3 +25,7 @@
status = "ok";
vbus-supply = <&usb2_otg_sw>;
};
+
+&hsic_host {
+ qcom,phy-sof-workaround;
+};
diff --git a/arch/arm/boot/dts/msm9625-v1.dtsi b/arch/arm/boot/dts/msm9625-v1.dtsi
index 54aa02a..ad95601 100644
--- a/arch/arm/boot/dts/msm9625-v1.dtsi
+++ b/arch/arm/boot/dts/msm9625-v1.dtsi
@@ -57,3 +57,7 @@
&ldrex_spinlock {
status = "ok";
};
+
+&hsic_host {
+ qcom,phy-sof-workaround;
+};
diff --git a/arch/arm/boot/dts/msm9625.dtsi b/arch/arm/boot/dts/msm9625.dtsi
index 3dbc95d..5a8a5ae 100644
--- a/arch/arm/boot/dts/msm9625.dtsi
+++ b/arch/arm/boot/dts/msm9625.dtsi
@@ -108,7 +108,7 @@
<87 512 40000 640000>;
};
- hsic@f9a15000 {
+ hsic_host: hsic@f9a15000 {
compatible = "qcom,hsic-host";
reg = <0xf9a15000 0x400>;
interrupts = <0 136 0>, <0 148 0>;
diff --git a/arch/arm/mach-msm/board-8064.c b/arch/arm/mach-msm/board-8064.c
index 42bde8f..623289e 100644
--- a/arch/arm/mach-msm/board-8064.c
+++ b/arch/arm/mach-msm/board-8064.c
@@ -675,6 +675,7 @@
static struct msm_hsic_host_platform_data msm_hsic_pdata = {
.strobe = 88,
.data = 89,
+ .phy_sof_workaround = true,
.bus_scale_table = &hsic_bus_scale_pdata,
};
#else
diff --git a/arch/arm/mach-msm/board-8960.c b/arch/arm/mach-msm/board-8960.c
index 7ef6fed..f3d8a2f 100644
--- a/arch/arm/mach-msm/board-8960.c
+++ b/arch/arm/mach-msm/board-8960.c
@@ -1459,8 +1459,9 @@
#ifdef CONFIG_USB_EHCI_MSM_HSIC
#define HSIC_HUB_RESET_GPIO 91
static struct msm_hsic_host_platform_data msm_hsic_pdata = {
- .strobe = 150,
- .data = 151,
+ .strobe = 150,
+ .data = 151,
+ .phy_sof_workaround = true,
};
static struct smsc_hub_platform_data hsic_hub_pdata = {
diff --git a/arch/arm/mach-msm/board-9615.c b/arch/arm/mach-msm/board-9615.c
index 50f4fd7..b77a3b9 100644
--- a/arch/arm/mach-msm/board-9615.c
+++ b/arch/arm/mach-msm/board-9615.c
@@ -841,6 +841,10 @@
.prv_data = &msm_hsic_peripheral_pdata_private,
};
+static struct msm_hsic_host_platform_data msm_hsic_pdata = {
+ .phy_sof_workaround = true,
+};
+
#define PID_MAGIC_ID 0x71432909
#define SERIAL_NUM_MAGIC_ID 0x61945374
#define SERIAL_NUMBER_LENGTH 127
@@ -1073,6 +1077,7 @@
&msm_peripheral_pdata;
msm_device_hsic_peripheral.dev.platform_data =
&msm_hsic_peripheral_pdata;
+ msm_device_hsic_host.dev.platform_data = &msm_hsic_pdata;
msm_device_usb_bam.dev.platform_data = &msm_usb_bam_pdata;
platform_add_devices(common_devices, ARRAY_SIZE(common_devices));
msm9615_pm8xxx_gpio_mpp_init();
diff --git a/drivers/usb/host/ehci-msm-hsic.c b/drivers/usb/host/ehci-msm-hsic.c
index 9879122..4a085aa 100644
--- a/drivers/usb/host/ehci-msm-hsic.c
+++ b/drivers/usb/host/ehci-msm-hsic.c
@@ -1332,44 +1332,48 @@
if (pdata->resume_gpio)
gpio_direction_output(pdata->resume_gpio, 1);
- mehci->resume_status = 0;
- resume_thread = kthread_run(msm_hsic_resume_thread,
- mehci, "hsic_resume_thread");
- if (IS_ERR(resume_thread)) {
- pr_err("Error creating resume thread:%lu\n",
- PTR_ERR(resume_thread));
- return PTR_ERR(resume_thread);
+ if (!mehci->ehci.resume_sof_bug) {
+ ehci_bus_resume(hcd);
+ } else {
+ mehci->resume_status = 0;
+ resume_thread = kthread_run(msm_hsic_resume_thread,
+ mehci, "hsic_resume_thread");
+ if (IS_ERR(resume_thread)) {
+ pr_err("Error creating resume thread:%lu\n",
+ PTR_ERR(resume_thread));
+ return PTR_ERR(resume_thread);
+ }
+
+ wait_for_completion(&mehci->rt_completion);
+
+ if (mehci->resume_status < 0)
+ return mehci->resume_status;
+
+ dbg_log_event(NULL, "FPR: Wokeup", 0);
+ spin_lock_irq(&ehci->lock);
+ (void) ehci_readl(ehci, &ehci->regs->command);
+
+ temp = 0;
+ if (ehci->async->qh_next.qh)
+ temp |= CMD_ASE;
+ if (ehci->periodic_sched)
+ temp |= CMD_PSE;
+ if (temp) {
+ ehci->command |= temp;
+ ehci_writel(ehci, ehci->command, &ehci->regs->command);
+ }
+
+ ehci->next_statechange = jiffies + msecs_to_jiffies(5);
+ hcd->state = HC_STATE_RUNNING;
+ ehci->rh_state = EHCI_RH_RUNNING;
+ ehci->command |= CMD_RUN;
+
+ /* Now we can safely re-enable irqs */
+ ehci_writel(ehci, INTR_MASK, &ehci->regs->intr_enable);
+
+ spin_unlock_irq(&ehci->lock);
}
- wait_for_completion(&mehci->rt_completion);
-
- if (mehci->resume_status < 0)
- return mehci->resume_status;
-
- dbg_log_event(NULL, "FPR: Wokeup", 0);
- spin_lock_irq(&ehci->lock);
- (void) ehci_readl(ehci, &ehci->regs->command);
-
- temp = 0;
- if (ehci->async->qh_next.qh)
- temp |= CMD_ASE;
- if (ehci->periodic_sched)
- temp |= CMD_PSE;
- if (temp) {
- ehci->command |= temp;
- ehci_writel(ehci, ehci->command, &ehci->regs->command);
- }
-
- ehci->next_statechange = jiffies + msecs_to_jiffies(5);
- hcd->state = HC_STATE_RUNNING;
- ehci->rh_state = EHCI_RH_RUNNING;
- ehci->command |= CMD_RUN;
-
- /* Now we can safely re-enable irqs */
- ehci_writel(ehci, INTR_MASK, &ehci->regs->intr_enable);
-
- spin_unlock_irq(&ehci->lock);
-
if (pdata->resume_gpio)
gpio_direction_output(pdata->resume_gpio, 0);
@@ -1808,6 +1812,8 @@
res_gpio = 0;
pdata->resume_gpio = res_gpio;
+ pdata->phy_sof_workaround = of_property_read_bool(node,
+ "qcom,phy-sof-workaround");
pdata->ignore_cal_pad_config = of_property_read_bool(node,
"hsic,ignore-cal-pad-config");
of_property_read_u32(node, "hsic,strobe-pad-offset",
@@ -1899,10 +1905,12 @@
spin_lock_init(&mehci->wakeup_lock);
- mehci->ehci.susp_sof_bug = 1;
- mehci->ehci.reset_sof_bug = 1;
+ if (pdata->phy_sof_workaround) {
+ mehci->ehci.susp_sof_bug = 1;
+ mehci->ehci.reset_sof_bug = 1;
+ mehci->ehci.resume_sof_bug = 1;
+ }
- mehci->ehci.resume_sof_bug = 1;
mehci->ehci.pool_64_bit_align = pdata->pool_64_bit_align;
mehci->enable_hbm = pdata->enable_hbm;
diff --git a/include/linux/usb/msm_hsusb.h b/include/linux/usb/msm_hsusb.h
index bf6847a..c8a20da 100644
--- a/include/linux/usb/msm_hsusb.h
+++ b/include/linux/usb/msm_hsusb.h
@@ -402,6 +402,7 @@
unsigned strobe;
unsigned data;
bool ignore_cal_pad_config;
+ bool phy_sof_workaround;
int strobe_pad_offset;
int data_pad_offset;