123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130 |
- From e9898a39fce7db84ae56329d4f90da92af3bd584 Mon Sep 17 00:00:00 2001
- From: P33M <P33M@github.com>
- 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(-)
- --- 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;
|