brcm2708: update to v3.18
[openwrt.git] / target / linux / brcm2708 / patches-3.18 / 0091-dwc_otg-FIQ-support-on-SMP.-Set-up-FIQ-stack-and-han.patch
1 From e9898a39fce7db84ae56329d4f90da92af3bd584 Mon Sep 17 00:00:00 2001
2 From: P33M <P33M@github.com>
3 Date: Wed, 24 Sep 2014 11:57:51 +0100
4 Subject: [PATCH 091/114] dwc_otg: FIQ support on SMP. Set up FIQ stack and
5  handler on Core 0 only.
6
7 ---
8  drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c | 96 ++++++++++++++--------------
9  1 file changed, 49 insertions(+), 47 deletions(-)
10
11 diff --git a/drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c b/drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c
12 index 98e1dc5..4d8dd95 100644
13 --- a/drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c
14 +++ b/drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c
15 @@ -397,7 +397,55 @@ static struct fiq_handler fh = {
16    .name = "usb_fiq",
17  };
18  
19 +static void hcd_init_fiq(void *cookie)
20 +{
21 +       dwc_otg_device_t *otg_dev = cookie;
22 +       dwc_otg_hcd_t *dwc_otg_hcd = otg_dev->hcd;
23 +       struct pt_regs regs;
24 +
25 +       if (claim_fiq(&fh)) {
26 +               DWC_ERROR("Can't claim FIQ");
27 +               BUG();
28 +       }
29 +       DWC_WARN("FIQ at 0x%08x", (fiq_fsm_enable ? (int)&dwc_otg_fiq_fsm : (int)&dwc_otg_fiq_nop));
30 +       DWC_WARN("FIQ ASM at 0x%08x length %d", (int)&_dwc_otg_fiq_stub, (int)(&_dwc_otg_fiq_stub_end - &_dwc_otg_fiq_stub));
31 +               set_fiq_handler((void *) &_dwc_otg_fiq_stub, &_dwc_otg_fiq_stub_end - &_dwc_otg_fiq_stub);
32 +       memset(&regs,0,sizeof(regs));
33 +
34 +       regs.ARM_r8 = (long) dwc_otg_hcd->fiq_state;
35 +       if (fiq_fsm_enable) {
36 +               regs.ARM_r9 = dwc_otg_hcd->core_if->core_params->host_channels;
37 +               //regs.ARM_r10 = dwc_otg_hcd->dma;
38 +               regs.ARM_fp = (long) dwc_otg_fiq_fsm;
39 +       } else {
40 +               regs.ARM_fp = (long) dwc_otg_fiq_nop;
41 +       }
42  
43 +       regs.ARM_sp = (long) dwc_otg_hcd->fiq_stack + (sizeof(struct fiq_stack) - 4);
44 +
45 +//             __show_regs(&regs);
46 +       set_fiq_regs(&regs);
47 +
48 +       //Set the mphi periph to  the required registers
49 +       dwc_otg_hcd->fiq_state->mphi_regs.base    = otg_dev->os_dep.mphi_base;
50 +       dwc_otg_hcd->fiq_state->mphi_regs.ctrl    = otg_dev->os_dep.mphi_base + 0x4c;
51 +       dwc_otg_hcd->fiq_state->mphi_regs.outdda  = otg_dev->os_dep.mphi_base + 0x28;
52 +       dwc_otg_hcd->fiq_state->mphi_regs.outddb  = otg_dev->os_dep.mphi_base + 0x2c;
53 +       dwc_otg_hcd->fiq_state->mphi_regs.intstat = otg_dev->os_dep.mphi_base + 0x50;
54 +       dwc_otg_hcd->fiq_state->dwc_regs_base = otg_dev->os_dep.base;
55 +       DWC_WARN("MPHI regs_base at 0x%08x", (int)dwc_otg_hcd->fiq_state->mphi_regs.base);
56 +       //Enable mphi peripheral
57 +       writel((1<<31),dwc_otg_hcd->fiq_state->mphi_regs.ctrl);
58 +#ifdef DEBUG
59 +       if (readl(dwc_otg_hcd->fiq_state->mphi_regs.ctrl) & 0x80000000)
60 +               DWC_WARN("MPHI periph has been enabled");
61 +       else
62 +               DWC_WARN("MPHI periph has NOT been enabled");
63 +#endif
64 +       // Enable FIQ interrupt from USB peripheral
65 +       enable_fiq(INTERRUPT_VC_USB);
66 +       local_fiq_enable();
67 +}
68  
69  /**
70   * Initializes the HCD. This function allocates memory for and initializes the
71 @@ -412,7 +460,6 @@ int hcd_init(dwc_bus_dev_t *_dev)
72         dwc_otg_device_t *otg_dev = DWC_OTG_BUSDRVDATA(_dev);
73         int retval = 0;
74          u64 dmamask;
75 -       struct pt_regs regs;
76  
77         DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD INIT otg_dev=%p\n", otg_dev);
78  
79 @@ -464,52 +511,7 @@ int hcd_init(dwc_bus_dev_t *_dev)
80         }
81  
82         if (fiq_enable)
83 -       {
84 -               if (claim_fiq(&fh)) {
85 -                       DWC_ERROR("Can't claim FIQ");
86 -                       goto error2;
87 -               }
88 -
89 -               DWC_WARN("FIQ at 0x%08x", (fiq_fsm_enable ? (int)&dwc_otg_fiq_fsm : (int)&dwc_otg_fiq_nop));
90 -               DWC_WARN("FIQ ASM at 0x%08x length %d", (int)&_dwc_otg_fiq_stub, (int)(&_dwc_otg_fiq_stub_end - &_dwc_otg_fiq_stub));
91 -
92 -               set_fiq_handler((void *) &_dwc_otg_fiq_stub, &_dwc_otg_fiq_stub_end - &_dwc_otg_fiq_stub);
93 -               memset(&regs,0,sizeof(regs));
94 -
95 -               regs.ARM_r8 = (long) dwc_otg_hcd->fiq_state;
96 -               if (fiq_fsm_enable) {
97 -                       regs.ARM_r9 = dwc_otg_hcd->core_if->core_params->host_channels;
98 -                       //regs.ARM_r10 = dwc_otg_hcd->dma;
99 -                       regs.ARM_fp = (long) dwc_otg_fiq_fsm;
100 -               } else {
101 -                       regs.ARM_fp = (long) dwc_otg_fiq_nop;
102 -               }
103 -
104 -               regs.ARM_sp = (long) dwc_otg_hcd->fiq_stack + (sizeof(struct fiq_stack) - 4);
105 -
106 -//             __show_regs(&regs);
107 -               set_fiq_regs(&regs);
108 -
109 -               //Set the mphi periph to  the required registers
110 -               dwc_otg_hcd->fiq_state->mphi_regs.base    = otg_dev->os_dep.mphi_base;
111 -               dwc_otg_hcd->fiq_state->mphi_regs.ctrl    = otg_dev->os_dep.mphi_base + 0x4c;
112 -               dwc_otg_hcd->fiq_state->mphi_regs.outdda  = otg_dev->os_dep.mphi_base + 0x28;
113 -               dwc_otg_hcd->fiq_state->mphi_regs.outddb  = otg_dev->os_dep.mphi_base + 0x2c;
114 -               dwc_otg_hcd->fiq_state->mphi_regs.intstat = otg_dev->os_dep.mphi_base + 0x50;
115 -               dwc_otg_hcd->fiq_state->dwc_regs_base = otg_dev->os_dep.base;
116 -               DWC_WARN("MPHI regs_base at 0x%08x", (int)dwc_otg_hcd->fiq_state->mphi_regs.base);
117 -               //Enable mphi peripheral
118 -               writel((1<<31),dwc_otg_hcd->fiq_state->mphi_regs.ctrl);
119 -#ifdef DEBUG
120 -               if (readl(dwc_otg_hcd->fiq_state->mphi_regs.ctrl) & 0x80000000)
121 -                       DWC_WARN("MPHI periph has been enabled");
122 -               else
123 -                       DWC_WARN("MPHI periph has NOT been enabled");
124 -#endif
125 -               // Enable FIQ interrupt from USB peripheral
126 -               enable_fiq(INTERRUPT_VC_USB);
127 -               local_fiq_enable();
128 -       }
129 +               smp_call_function_single(0, hcd_init_fiq, otg_dev, 1);
130  
131  
132         otg_dev->hcd->otg_dev = otg_dev;
133 -- 
134 1.8.3.2
135