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.
8 drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c | 96 ++++++++++++++--------------
9 1 file changed, 49 insertions(+), 47 deletions(-)
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 = {
19 +static void hcd_init_fiq(void *cookie)
21 + dwc_otg_device_t *otg_dev = cookie;
22 + dwc_otg_hcd_t *dwc_otg_hcd = otg_dev->hcd;
23 + struct pt_regs regs;
25 + if (claim_fiq(&fh)) {
26 + DWC_ERROR("Can't claim FIQ");
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(®s,0,sizeof(regs));
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;
40 + regs.ARM_fp = (long) dwc_otg_fiq_nop;
43 + regs.ARM_sp = (long) dwc_otg_hcd->fiq_stack + (sizeof(struct fiq_stack) - 4);
45 +// __show_regs(®s);
46 + set_fiq_regs(®s);
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);
59 + if (readl(dwc_otg_hcd->fiq_state->mphi_regs.ctrl) & 0x80000000)
60 + DWC_WARN("MPHI periph has been enabled");
62 + DWC_WARN("MPHI periph has NOT been enabled");
64 + // Enable FIQ interrupt from USB peripheral
65 + enable_fiq(INTERRUPT_VC_USB);
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);
75 - struct pt_regs regs;
77 DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD INIT otg_dev=%p\n", otg_dev);
79 @@ -464,52 +511,7 @@ int hcd_init(dwc_bus_dev_t *_dev)
84 - if (claim_fiq(&fh)) {
85 - DWC_ERROR("Can't claim FIQ");
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));
92 - set_fiq_handler((void *) &_dwc_otg_fiq_stub, &_dwc_otg_fiq_stub_end - &_dwc_otg_fiq_stub);
93 - memset(®s,0,sizeof(regs));
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;
101 - regs.ARM_fp = (long) dwc_otg_fiq_nop;
104 - regs.ARM_sp = (long) dwc_otg_hcd->fiq_stack + (sizeof(struct fiq_stack) - 4);
106 -// __show_regs(®s);
107 - set_fiq_regs(®s);
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);
120 - if (readl(dwc_otg_hcd->fiq_state->mphi_regs.ctrl) & 0x80000000)
121 - DWC_WARN("MPHI periph has been enabled");
123 - DWC_WARN("MPHI periph has NOT been enabled");
125 - // Enable FIQ interrupt from USB peripheral
126 - enable_fiq(INTERRUPT_VC_USB);
127 - local_fiq_enable();
129 + smp_call_function_single(0, hcd_init_fiq, otg_dev, 1);
132 otg_dev->hcd->otg_dev = otg_dev;