From e9898a39fce7db84ae56329d4f90da92af3bd584 Mon Sep 17 00:00:00 2001 From: P33M Date: Wed, 24 Sep 2014 11:57:51 +0100 Subject: [PATCH 091/114] dwc_otg: FIQ support on SMP. Set up FIQ stack and handler on Core 0 only. --- drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c | 96 ++++++++++++++-------------- 1 file changed, 49 insertions(+), 47 deletions(-) diff --git a/drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c b/drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c index 98e1dc5..4d8dd95 100644 --- a/drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c +++ b/drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c @@ -397,7 +397,55 @@ static struct fiq_handler fh = { .name = "usb_fiq", }; +static void hcd_init_fiq(void *cookie) +{ + dwc_otg_device_t *otg_dev = cookie; + dwc_otg_hcd_t *dwc_otg_hcd = otg_dev->hcd; + struct pt_regs regs; + + if (claim_fiq(&fh)) { + DWC_ERROR("Can't claim FIQ"); + BUG(); + } + DWC_WARN("FIQ at 0x%08x", (fiq_fsm_enable ? (int)&dwc_otg_fiq_fsm : (int)&dwc_otg_fiq_nop)); + DWC_WARN("FIQ ASM at 0x%08x length %d", (int)&_dwc_otg_fiq_stub, (int)(&_dwc_otg_fiq_stub_end - &_dwc_otg_fiq_stub)); + set_fiq_handler((void *) &_dwc_otg_fiq_stub, &_dwc_otg_fiq_stub_end - &_dwc_otg_fiq_stub); + memset(®s,0,sizeof(regs)); + + regs.ARM_r8 = (long) dwc_otg_hcd->fiq_state; + if (fiq_fsm_enable) { + regs.ARM_r9 = dwc_otg_hcd->core_if->core_params->host_channels; + //regs.ARM_r10 = dwc_otg_hcd->dma; + regs.ARM_fp = (long) dwc_otg_fiq_fsm; + } else { + regs.ARM_fp = (long) dwc_otg_fiq_nop; + } + regs.ARM_sp = (long) dwc_otg_hcd->fiq_stack + (sizeof(struct fiq_stack) - 4); + +// __show_regs(®s); + set_fiq_regs(®s); + + //Set the mphi periph to the required registers + dwc_otg_hcd->fiq_state->mphi_regs.base = otg_dev->os_dep.mphi_base; + dwc_otg_hcd->fiq_state->mphi_regs.ctrl = otg_dev->os_dep.mphi_base + 0x4c; + dwc_otg_hcd->fiq_state->mphi_regs.outdda = otg_dev->os_dep.mphi_base + 0x28; + dwc_otg_hcd->fiq_state->mphi_regs.outddb = otg_dev->os_dep.mphi_base + 0x2c; + dwc_otg_hcd->fiq_state->mphi_regs.intstat = otg_dev->os_dep.mphi_base + 0x50; + dwc_otg_hcd->fiq_state->dwc_regs_base = otg_dev->os_dep.base; + DWC_WARN("MPHI regs_base at 0x%08x", (int)dwc_otg_hcd->fiq_state->mphi_regs.base); + //Enable mphi peripheral + writel((1<<31),dwc_otg_hcd->fiq_state->mphi_regs.ctrl); +#ifdef DEBUG + if (readl(dwc_otg_hcd->fiq_state->mphi_regs.ctrl) & 0x80000000) + DWC_WARN("MPHI periph has been enabled"); + else + DWC_WARN("MPHI periph has NOT been enabled"); +#endif + // Enable FIQ interrupt from USB peripheral + enable_fiq(INTERRUPT_VC_USB); + local_fiq_enable(); +} /** * Initializes the HCD. This function allocates memory for and initializes the @@ -412,7 +460,6 @@ int hcd_init(dwc_bus_dev_t *_dev) dwc_otg_device_t *otg_dev = DWC_OTG_BUSDRVDATA(_dev); int retval = 0; u64 dmamask; - struct pt_regs regs; DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD INIT otg_dev=%p\n", otg_dev); @@ -464,52 +511,7 @@ int hcd_init(dwc_bus_dev_t *_dev) } if (fiq_enable) - { - if (claim_fiq(&fh)) { - DWC_ERROR("Can't claim FIQ"); - goto error2; - } - - DWC_WARN("FIQ at 0x%08x", (fiq_fsm_enable ? (int)&dwc_otg_fiq_fsm : (int)&dwc_otg_fiq_nop)); - DWC_WARN("FIQ ASM at 0x%08x length %d", (int)&_dwc_otg_fiq_stub, (int)(&_dwc_otg_fiq_stub_end - &_dwc_otg_fiq_stub)); - - set_fiq_handler((void *) &_dwc_otg_fiq_stub, &_dwc_otg_fiq_stub_end - &_dwc_otg_fiq_stub); - memset(®s,0,sizeof(regs)); - - regs.ARM_r8 = (long) dwc_otg_hcd->fiq_state; - if (fiq_fsm_enable) { - regs.ARM_r9 = dwc_otg_hcd->core_if->core_params->host_channels; - //regs.ARM_r10 = dwc_otg_hcd->dma; - regs.ARM_fp = (long) dwc_otg_fiq_fsm; - } else { - regs.ARM_fp = (long) dwc_otg_fiq_nop; - } - - regs.ARM_sp = (long) dwc_otg_hcd->fiq_stack + (sizeof(struct fiq_stack) - 4); - -// __show_regs(®s); - set_fiq_regs(®s); - - //Set the mphi periph to the required registers - dwc_otg_hcd->fiq_state->mphi_regs.base = otg_dev->os_dep.mphi_base; - dwc_otg_hcd->fiq_state->mphi_regs.ctrl = otg_dev->os_dep.mphi_base + 0x4c; - dwc_otg_hcd->fiq_state->mphi_regs.outdda = otg_dev->os_dep.mphi_base + 0x28; - dwc_otg_hcd->fiq_state->mphi_regs.outddb = otg_dev->os_dep.mphi_base + 0x2c; - dwc_otg_hcd->fiq_state->mphi_regs.intstat = otg_dev->os_dep.mphi_base + 0x50; - dwc_otg_hcd->fiq_state->dwc_regs_base = otg_dev->os_dep.base; - DWC_WARN("MPHI regs_base at 0x%08x", (int)dwc_otg_hcd->fiq_state->mphi_regs.base); - //Enable mphi peripheral - writel((1<<31),dwc_otg_hcd->fiq_state->mphi_regs.ctrl); -#ifdef DEBUG - if (readl(dwc_otg_hcd->fiq_state->mphi_regs.ctrl) & 0x80000000) - DWC_WARN("MPHI periph has been enabled"); - else - DWC_WARN("MPHI periph has NOT been enabled"); -#endif - // Enable FIQ interrupt from USB peripheral - enable_fiq(INTERRUPT_VC_USB); - local_fiq_enable(); - } + smp_call_function_single(0, hcd_init_fiq, otg_dev, 1); otg_dev->hcd->otg_dev = otg_dev; -- 1.8.3.2