ae8e3adf9da8102e08da86ede9b6dfe0029b6111
[15.05/openwrt.git] / target / linux / brcm2708 / patches-3.18 / 0045-dwc_otg-Fix-various-issues-with-root-port-and-transa.patch
1 From 8eb79690a70cce34e9a1c35cf165716f78301d2e Mon Sep 17 00:00:00 2001
2 From: P33M <P33M@github.com>
3 Date: Fri, 20 Jun 2014 16:03:12 +0100
4 Subject: [PATCH 045/114] dwc_otg: Fix various issues with root port and
5  transaction errors
6
7 Process the host port interrupts correctly (and don't trample them).
8 Root port hotplug now functional again.
9
10 Fix a few thinkos with the transaction error passthrough for fiq_fsm.
11 ---
12  drivers/usb/host/dwc_otg/dwc_otg_cil_intr.c | 7 +++----
13  drivers/usb/host/dwc_otg/dwc_otg_fiq_fsm.c  | 6 +++++-
14  drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c | 2 +-
15  3 files changed, 9 insertions(+), 6 deletions(-)
16
17 diff --git a/drivers/usb/host/dwc_otg/dwc_otg_cil_intr.c b/drivers/usb/host/dwc_otg/dwc_otg_cil_intr.c
18 index 065807f..96c76e3 100644
19 --- a/drivers/usb/host/dwc_otg/dwc_otg_cil_intr.c
20 +++ b/drivers/usb/host/dwc_otg/dwc_otg_cil_intr.c
21 @@ -1348,10 +1348,9 @@ static inline uint32_t dwc_otg_read_common_intr(dwc_otg_core_if_t * core_if, gin
22                 local_fiq_disable();
23                 /* Pull in the interrupts that the FIQ has masked */
24                 gintmsk.d32 |= ~(hcd->fiq_state->gintmsk_saved.d32);
25 +               gintmsk.d32 |= gintmsk_common.d32;
26                 /* for the upstairs function to reenable - have to read it here in case FIQ triggers again */
27 -               reenable_gintmsk->d32 |= gintmsk.d32;
28 -               reenable_gintmsk->d32 |= ~(hcd->fiq_state->gintmsk_saved.d32);
29 -               reenable_gintmsk->d32 &= gintmsk_common.d32;
30 +               reenable_gintmsk->d32 = gintmsk.d32;
31                 local_fiq_enable();
32         }
33  
34 @@ -1535,7 +1534,7 @@ int32_t dwc_otg_handle_common_intr(void *dev)
35  //             fiq_print(FIQDBG_INT, otg_dev->hcd->fiq_state, "CILOUT %1d", retval);
36  //             fiq_print(FIQDBG_INT, otg_dev->hcd->fiq_state, "%08x", gintsts.d32);
37  //             fiq_print(FIQDBG_INT, otg_dev->hcd->fiq_state, "%08x", gintmsk_reenable.d32);
38 -               if (retval) {
39 +               if (retval && fiq_enable) {
40                         DWC_WRITE_REG32(&core_if->core_global_regs->gintmsk, gintmsk_reenable.d32);
41                 }
42  
43 diff --git a/drivers/usb/host/dwc_otg/dwc_otg_fiq_fsm.c b/drivers/usb/host/dwc_otg/dwc_otg_fiq_fsm.c
44 index 1be6e71..284f902 100644
45 --- a/drivers/usb/host/dwc_otg/dwc_otg_fiq_fsm.c
46 +++ b/drivers/usb/host/dwc_otg/dwc_otg_fiq_fsm.c
47 @@ -696,7 +696,11 @@ static int notrace noinline fiq_fsm_do_hcintr(struct fiq_state *state, int num_c
48                 fiq_print(FIQDBG_ERR, state, "ERRST %02d", n);
49                 if (hcint_probe.b.nak || hcint_probe.b.ack || hcint_probe.b.datatglerr) {
50                         fiq_print(FIQDBG_ERR, state, "RESET %02d", n);
51 -                       st->nr_errors = 0;
52 +                       /* In some random cases we can get a NAK interrupt coincident with a Xacterr
53 +                        * interrupt, after the device has disappeared.
54 +                        */
55 +                       if (!hcint.b.xacterr)
56 +                               st->nr_errors = 0;
57                         hcintmsk.b.nak = 0;
58                         hcintmsk.b.ack = 0;
59                         hcintmsk.b.datatglerr = 0;
60 diff --git a/drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c b/drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c
61 index 4195ff2..a5566bc 100644
62 --- a/drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c
63 +++ b/drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c
64 @@ -2619,7 +2619,7 @@ int32_t dwc_otg_hcd_handle_hc_n_intr(dwc_otg_hcd_t * dwc_otg_hcd, uint32_t num)
65                         case FIQ_PASSTHROUGH_ERRORSTATE:
66                                 /* Hook into the error count */
67                                 fiq_print(FIQDBG_ERR, dwc_otg_hcd->fiq_state, "HCDERR%02d", num);
68 -                               if (dwc_otg_hcd->fiq_state->channel[num].nr_errors) {
69 +                               if (!dwc_otg_hcd->fiq_state->channel[num].nr_errors) {
70                                         qtd->error_count = 0;
71                                         fiq_print(FIQDBG_ERR, dwc_otg_hcd->fiq_state, "RESET   ");
72                                 }
73 -- 
74 1.8.3.2
75