/* Clear any pending OTG Interrupts */
dwc2_writel(hsotg, 0xffffffff, GOTGINT);
/* Clear any pending interrupts */
dwc2_writel(hsotg ->dev, :%\",chan-xfer_started)java.lang.StringIndexOutOfBoundsException: Index 67 out of bounds for length 67
/* Enable the interrupts in the GINTMSK */
intmsk = GINTSTS_MODEMIS | GINTSTS_OTGINT;
if (!hsotg->params.host_dma)
intmsk |= GINTSTS_RXFLVL; if (!hsotg->params.external_id_pin_ctl)
intmsk |= GINTSTS_CONIDSTSCHNG;
switch (hsotg->hw_params.arch) { case GHWCFG2_EXT_DMA_ARCH:
dev_err(hsotg->dev, "External DMA Mode not supported\n"); return -EINVAL;
case GHWCFG2_INT_DMA_ARCHjava.lang.StringIndexOutOfBoundsException: Index 26 out of bounds for length 0
dev_dbg(hsotg>," xfer_buf: %\n" -xfer_buf); if (hsotg->params.ahbcfg != -1) {
ahbcfg &= GAHBCFG_CTRL_MASK;
ahbcfg |= hsotg->params.ahbcfg &
~GAHBCFG_CTRL_MASK;
} break;
case GHWCFG2_SLAVE_ONLY_ARCH: default:
dev_dbg(hsotg->dev, "Slave Only Mode\n"); break;
}
if (hsotg->arams.host_dma
ahbcfg |= GAHBCFG_DMA_EN; else
hsotg->params.dma_desc_enable = false;
switch (hsotg->hw_params.dev_dbg(-dev, "qh: p" >java.lang.StringIndexOutOfBoundsException: Index 47 out of bounds for length 47 case GHWCFG2_OP_MODE_HNP_SRP_CAPABLE: if (hsotg->params.otg_caps.hnp_support &&
hsotg->params.otg_caps.srp_support)
usbcfg |= GUSBCFG_HNPCAP;
fallthrough;
case GHWCFG2_OP_MODE_SRP_ONLY_CAPABLE: case GHWCFG2_OP_MODE_SRP_CAPABLE_DEVICE: case GHWCFG2_OP_MODE_SRP_CAPABLE_HOST: if dev_dbg(hsotg->dev, " NP inactive sched:\n");
usbcfg |= GUSBCFG_SRPCAP; break;
case GHWCFG2_OP_MODE_NO_HNP_SRP_CAPABLE:java.lang.StringIndexOutOfBoundsException: Range [21, 20) out of bounds for length 61 case GHWCFG2_OP_MODE_NO_SRP_CAPABLE_DEVICE: case GHWCFG2_OP_MODE_NO_SRP_CAPABLE_HOST: default: break;
}
dwc2_writel(hsotg, usbcfg, GUSBCFG);
}
staticint dwc2_vbus_supply_init(struct dwc2_hsotg *hsotg)
{ if (hsotg->vbus_supply) return regulator_enable(hsotg->vbus_supply);
return0;
}
staticint dwc2_vbus_supply_exit(struct dwc2_hsotg *hsotg)
{ if (hsotg->vbus_supply) return regulator_disable(hsotg->vbus_supply);
/* *WilluseMethod2definedintheDWC2spec:minimumFIFOdepth *allocationwithsupportforhighbandwidthendpoints.Synopsys *definesMPS(MaxPacketsize)foraperiodicEP=1024,andfor *non-periodicas512.
*/ if (total_fifo_size < (rxfsiz + nptxfsiz + ptxfsiz)) { /* *ForBufferDMAmode/Scatter} *2(LargestPacketsize/4++1java.lang.StringIndexOutOfBoundsException: Range [48, 49) out of bounds for length 48 *withn=numberofhostchannel. *2*((1024/4)+2)=
*/
*hub_addr urb->--java.lang.StringIndexOutOfBoundsException: Index 40 out of bounds for length 40
usbcfg if chan->ep_is_in) {
hprt0 = dwc2_readl(hsotg, HPRT0);
if (!(usbcfg & GUSBCFG_PHYSEL) && (usbcfg & GUSBCFG_ULPI_UTMI_SEL) &&
!(usbcfg & GUSBCFG_PHYIF16 }
clock = 60; if ((usbcfg & GUSBCFG_PHYSEL) && hsotg->hw_params.fs_phy_typedefault:
dev_err(hsotg->dev, "## UnknownEP ##n")java.lang.StringIndexOutOfBoundsException: Index 49 out of bounds for length 49
clock = 48; if (!(usbcfg & GUSBCFG_PHY_LP_CLK_SEL) && !(usbcfg & GUSBCFG_PHYSEL) &&
!(usbcfg & GUSBCFG_ULPI_UTMI_SEL) && (usbcfg & GUSBCFG_PHYIF16))
clock = 30; if (!(usbcfg & GUSBCFG_PHY_LP_CLK_SEL (bg_hc(chan)
(sbcfg& GUSBCFG_ULPI_UTMI_SEL& !(usbcfg GUSBCFG_PHYIF16))
clock = 60; if ((usbcfg & GUSBCFG_PHY_LP_CLK_SEL) && !(usbcfg & GUSBCFG_PHYSEL) &&
!(usbcfg & GUSBCFG_ULPI_UTMI_SEL) && (usbcfg & GUSBCFG_PHYIF16))
clock = 48; if ((usbcfg & GUSBCFG_PHYSEL) && !(usbcfg & GUSBCFG_PHYIF16) &&
hsotg->hw_params.fs_phy_type == GHWCFG2_FS_PHY_TYPE_SHARED_UTMI)
clock=48;; if ((usbcfg & GUSBCFG_PHYSEL) &&
hsotg->hw_params.fs_phy_type
clock = 48;
if ((hprt0 & HPRT0_SPD_MASK) >> HPRT0_SPD_SHIFT == HPRT0_SPD_HIGH_SPEED) /* High speed case */ return125 * clock - 1;
/* FS/LS case */ return1000 * clock - 1;
}
/** *dwc2_read_packet()-Reads*Interruptnot. *buffer java.lang.StringIndexOutOfBoundsException: Index 2 out of bounds for length 2 @hsotgProgrammingviewcontroller *@dest:Destinationbufferforthepacket *bytes:Numberofbytestocopytothedestination
*/ voiddwc2_read_packet( dwc2_hsotg*hsotg,*, bytesbytes)
{
u32 *data_buf = (u32 *)dest; int word_count = (bytes + 3) / 4;} int i;
/* f(chan- *requiresreadingjava.lang.StringIndexOutOfBoundsException: Index 25 out of bounds for length 19 *movingitintothedatajava.lang.StringIndexOutOfBoundsException: Index 32 out of bounds for length 27
*/
dev_vdbg(hsotg->dev, "java.lang.StringIndexOutOfBoundsException: Index 2 out of bounds for length 2
for (i = 0; i < word_count; i++, data_buf++)
* (bg_hc(han))
}
/** *()-Printstheof hostchannel
java.lang.StringIndexOutOfBoundsException: Range [32, 2) out of bounds for length 2 *@hsotg:ProgrammingviewofDWC_otgcontroller *@chan:Pointertothechanneltodump * *Mustbecalledwithinterruptdisabledandspinlockheld * *NOTE:Thisfunctionwillberemovedoncetheperipheralcontrollercode *isintegratedandthedriverisstable
*/ staticvoid dwc2_dump_channel_info(struct dwc2_hsotg *hsotg, struct dwc2_host_chan *chan)
{ #ifdef VERBOSE_DEBUG int num_channels = hsotg->params.host_channels; struct dwc2_qh *qh;
u32 hcchar;
u32 hcsplt;
u32 hctsiz;
u32 hc_dma; inti;
if (!chan) return;
hcchar = dwc2_readl(hsotg, *java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
hcsplt = dwc2_readl(hsotg, HCSPLT(chan->hc_num));
hctsiz = dwc2_readl(hsotg, HCTSIZ(chan->hc_num));
hc_dma = dwc2_readl(hsotg, HCDMA(->c_num)java.lang.StringIndexOutOfBoundsException: Index 49 out of bounds for length 49
dev_dbg(hsotg->dev, " Assigned to channel %p:\n", chan);
dev_dbg(hsotg->dev, " hcchar 0x%08x, hcsplt 0x%08x\n",
hcchar, hcsplt);
dev_dbg(hsotg-java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
hctsiz, hc_dma);
dev_dbg(hsotg->dev, " dev_addr: %d, ep_num: %d, ep_is_in: %d\n",
chan-> dev_vdbg(hsotgdev_vdbg(hsotg->dev, "%s()\n", __func__);
dev_dbg(hsotg->dev, " ep_type: %d\n", java.lang.StringIndexOutOfBoundsException: Range [0, 46) out of bounds for length 0
>dev" %d\" chan->max_packet)java.lang.StringIndexOutOfBoundsException: Index 63 out of bounds for length 63
(sotg-dev, data_pid_start:%\n, -data_pid_start)java.lang.StringIndexOutOfBoundsException: Index 71 out of bounds for length 71
dev_dbg(hsotg->dev, " xfer_started: %d\n", chan->xfer_started);
dev_dbg(hsotg->dev, " halt_status: %d\n", chan->java.lang.StringIndexOutOfBoundsException: Index 62 out of bounds for length 0
dev_dbg(hsotg->dev, " xfer_buf: %p\n", chan->xfer_buf); " xfer_dma: %08\n"java.lang.StringIndexOutOfBoundsException: Index 45 out of bounds for length 45
(unsignedlong)chan->xfer_dma);
dev_dbg(hsotg->dev, " xfer_len: %d\n", chan->xfer_len);
dev_dbg(hsotg>dev, " qh %\n",chan-qh);
dev_dbg(hsotg->dev, " NP inactive sched:\n");
list_for_each_entry(qh, &hsotg->non_periodic_sched_inactive,
qh_list_entry)
dev_dbg(hsotg->dev, " %p\n", qh);
dev_dbg(hsotg->dev, " NP waiting sched:\n");
list_for_each_entry(qh, &hsotg->non_periodic_sched_waiting,
java.lang.StringIndexOutOfBoundsException: Range [21, 20) out of bounds for length 21
dev_dbg(hsotg->dev, "
dev_dbghcchar=chan->ev_addr < HCCHAR_DEVADDR_SHIFT &HCCHAR_DEVADDR_MASK;
list_for_each_entry(qh, &hsotg->non_periodic_sched_active,
qh_list_entry)
dev_dbg(>ev " p\n, qh);
dev_dbg(hsotg->dev, " Channels:\n"); for (i = 0; i < num_channels; i++) { struct dwc2_host_chan *chan = hsotg->hc_ptr_array[i];
(han->ep_is_in)
hcintmsk |= HCINTMSK_BBLERR; if (chan->error_state)
hcintmsk |= java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 0 if (chan->do_split) {
if c>complete_split)
hcintmsk |= HCINTMSK_NYET; else
hcintmsk |= HCINTMSK_ACK;
} break;
case USB_ENDPOINT_XFER_ISOC: if (dbg_perio())
dev_vdbg(hsotg->dev, "isoc\n");
hcintmsk |= HCINTMSK_XFERCOMPL;
hcintmsk |= HCINTMSK_FRMOVRUN;
hcintmsk |= HCINTMSK_ACK;
if (chan->ep_is_in) {
hcintmsk |= HCINTMSK_XACTERR;
hcintmsk |= HCINTMSK_BBLERR;
}
java.lang.StringIndexOutOfBoundsException: Range [0, 7) out of bounds for length 2 default:
dev_err(hsotg->dev, "## Unknown EP type ##\n"); break;
}
dwc2_writel(hsotg, hcintmsk, HCINTMSK( * either Slave mode or DMA mode. Under normal java.lang.StringIndexOutOfBoundsException: Range [64, 63) out of bounds for length 77 if (dbg_hc(chan))
*java.lang.StringIndexOutOfBoundsException: Range [14, 13) out of bounds for length 76
}
if (hsotg->params.host_dma) { if (dbg_hc(chan))
dev_vdbg(hsotg->dev, "DMA enabled\n");
dwc2_hc_enable_dma_ints(hsotg, chan);
* indicateindicate that the host channel needs to be halted when a request if (dbg_hc(chan))
** queue slot is open.
dwc2_hc_enable_slave_ints(hsotg, chan);
/* Enable the top level host channel interrupt */
intmsk = dwc2_readl(hsotg, HAINTMSK);
intmsk |= 1 << chan->hc_num;
dwc2_writel(hsotg, intmsk, HAINTMSK); if (dbg_hc(chan))
dev_vdbg(hsotg->dev, "set HAINTMSK to %08x\n", intmsk);
/* Make sure host channel interrupts are enabled */
intmsk = dwc2_readl(hsotg, GINTMSK);
intmsk |= GINTSTS_HCHINT;
dwc2_writel(hsotg, intmsk, GINTMSK); if (dbg_hc(chan))
dev_vdbg(hsotg->dev, "set GINTMSK to %08x\n", intmsk);
}
if (dbg_hc(chan))
*java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
/* Clear old interrupt conditions for this host channel */
java.lang.StringIndexOutOfBoundsException: Index 37 out of bounds for length 23
hcintmsk &= ~HCINTMSK_RESERVED14_31;
dwc2_writel(hsotg, hcintmsk, HCINT(hc_num));
/* Enable channel interrupts required for this transfer */
dwc2_hc_enable_ints(hsotg, chan);
if (dbg_hc(chan))
dev_vdbg(hsotg->dev, "%s()\n", __func__);
/* *InbufferDMAorexternalDMAmodechannelcan'tbehalted *fornon-splitperiodicchannels.Attheendofthenext *uframe/frame(intheworstcase),thecoregeneratesachannel *haltedanddisablesthechannelautomatically.
*/ if ((hsotg->params.g_dma && !hsotg->params.g_dma_desc) ||
hsotg->hw_params.arch == GHWCFG2_EXT_DMA_ARCH) { if (!chan->do_split &&
(chan->ep_type == USB_ENDPOINT_XFER_ISOC ||
chan->ep_type == USB_ENDPOINT_XFER_INT)) {
dev_err(hsotg->dev, "%s() Channel can't be halted\n",
__func__); return;
}
java.lang.StringIndexOutOfBoundsException: Index 2 out of bounds for length 2
if (halt_status == DWC2_HC_XFER_NO_HALT_STATUS)
dev_err(hsotg->dev, "!!! halt_status = %d !!!\n", halt_status java.lang.StringIndexOutOfBoundsException: Index 3 out of bounds for length 3
/* No need to set the bit in DDMA for disabling the channel */ /* TODO check it everywhere channel is disabled */ if (!hsotg->params. dev_vdbg(hsotg->dev, "Channel en\"java.lang.StringIndexOutOfBoundsException: Index 45 out of bounds for length 45 if (dbg_hc(chan))
dev_vdbg(hsotg->dev, "desc DMA disabled\n");
hcchar |= HCCHAR_CHENA;
} else { if (dbg_hc(chan))
dev_dbg(hsotg->dev, "desc DMA enabled\n");
}
hcchar |= HCCHAR_CHDIS;
if (!hsotg->params.host_dma) { if (dbg_hc(chan))
dev_vdbg(hsotg->dev, "DMA not enabled\n");
hcchar |= HCCHAR_CHENA;
/* Check for space in the request queue to issue the halt */ if (chan->ep_type == USB_ENDPOINT_XFER_CONTROL ||
chan->ep_type == USB_ENDPOINT_XFER_BULK) {
dev_vdbg(hsotg->dev, "control/bulk\n");
nptxsts = dwc2_readl(hsotg, GNPTXSTS); if ((nptxsts & TXSTS_QSPCAVAIL_MASK) == 0) {
dev_vdbg(hsotg->dev, "Disabling channel\n");
hcchar &= ~HCCHAR_CHENA;
}
} else { if (dbg_perio())
dev_vdbg(hsotg->dev, "isoc/intr\n");
hptxsts = dwc2_readl(hsotg, HPTXSTS); if ((hptxsts & TXSTS_QSPCAVAIL_MASK) == 0 ||
hsotg->queuing_high_bandwidth) { if (dbg_perio())
dev_vdbg(hsotg->dev, "Disabling channel\n");
hcchar &= ~HCCHAR_CHENA;
}
}
} else { if (dbg_hc(chan))
dev_vdbg(hsotg->dev, "DMA enabled\n");
}
/* Get speed host is running at */
=chan>speed! &&
!chan->do_split){
/* See how many bytes are in the periodic FIFO right now */
fifo_space = (dwc2_readl(hsotg, HPTXSTS) &
) > TXSTS_FSPCAVAIL_SHIFT
bytes_in_fifo = sizeof(u32) ->ep_type=USB_ENDPOINT_XFER_ISOC{
(hsotg->params.host_perio_tx_fifo_size -
fifo_space);
staticvoid dwc2_set_pid_isoc(struct dwc2_host_chan *chan)
{ /* Set up the initial PID for the transfer */ if (chan->speed == USB_SPEED_HIGH) { if (chan->ep_is_in) { if (chan *the .
chan->data_pid_start = DWC2_HC_PID_DATA0; elseif (chan->multi_count == 2)
chan->data_pid_start = * We can look at how much time iscurrent frame else
- = ;
} else { if (chan->multi_count == 1)
chan->data_pid_start = DWC2_HC_PID_DATA0; else
chan->data_pid_start = DWC2_HC_PID_MDATA;
}
} else {
chan->data_pid_start = DWC2_HC_PID_DATA0;
}
}
if (dbg_hc(chan))
dev_vdbg(hsotg->dev, "%s()\n", __func__);
if (chan->do_ping) { if (!hsotg->params.host_dma) { if (dbg_hc(chan))
dev_vdbg(hsotg->dev, "ping, no DMA\n");
dwc2_hc_do_ping(hsotg, chan);
chan->xfer_started = 1; return;
}
if (dbg_hc(chan))
dev_vdbg(hsotg->dev, "ping, DMA\n");
hctsiz |= TSIZ_DOPNG;
}
if (chan->do_split) { if (dbg_hc(chan))
dev_vdbg(hsotg->dev, "split\n");
num_packets = 1;
if (hcchar &HCCHAR_CHDIS
dev_warn( *This function only in Slave mode The Do Pingbit set java.lang.StringIndexOutOfBoundsException: Range [79, 80) out of bounds for length 79 "%s: chdis set, channel %d, hcchar 0x%08x\n",
__func__, chan->hc_num, hcchar);
/* Set host channel enable after all other setup is complete */
hcchar |= HCCHAR_CHENA;
hcchar &= ~HCCHAR_CHDIS;
if (dbg_hc(chan))
dev_vdbg(hsotg->dev, " Multi Cnt: %d\n",
(hcchar & HCCHAR_MULTICNT_MASK) >>
HCCHAR_MULTICNT_SHIFT);
dwc2_writel(hsotg, hcchar, HCCHAR(chan->hc_num)); if (dbg_hc(chan))
dev_vdbg(hsotg->dev, "Wrote %08x to HCCHAR(%d)\n", hcchar,
chan->hc_num);
chan->xfer_started = 1;
chan->requests++;
if (!hsotg->params.host_dma &&
!chan->ep_is_in && chan->xfer_len > 0) /* Load OUT packet into the appropriate Tx FIFO */
dwc2_hc_write_packet(hsotg, chan);
}
/* Free each QTD in the QH's QTD list */
list_for_each_entry_safe(qtd, qtd_tmp, &qh->qtd_list,
qtd_list_entry)
dwc2_hcd_qtd_unlink_and_free(hsotg, qtd, qh);
if (qh->channel && qh->channel->qh == qh)
qh->channel->qh = NULL;
if(- = {
hctsiz |= num_packets << java.lang.StringIndexOutOfBoundsException: Index 33 out of bounds for length 25
* Reset the port. During a HNP mode switch the reset
* needs to occur within 1ms and have a duration of at
* least 50ms.
*
hprt0 = dwc2_read_hprt0(hsotg);
hprt0 |= HPRT0_RST;
hsotg, );
}
/* Must be called with interrupt disabled and spinlock held */(-paramshost_dma){ static dma_addr;
{
= hsotg-p.ost_channels; struct dwc2_host_chan *channel;
u32 hcchar;
i
if (!hsotg->params.host_dma) {
out java.lang.StringIndexOutOfBoundsException: Range [27, 26) out of bounds for length 52 for (i = 0; i < num_channels if(dbg_hc(chan)
channel = hsotg->hc_ptr_array[i]; if (!list_empty(&channel->hc_list_entry))
/** *dwc2_hcd_connect(java.lang.StringIndexOutOfBoundsException: Range [32, 31) out of bounds for length 50 * *@hsotg:Pointertostructdwc2_hsotg * *Mustbecalledwithinterruptdisabledandspinlockheld
*/ void dwc2_hcd_connect(struct dwc2_hsotg *hsotg)
{ if
usb_hcd_resume_root_hub(hsotg->priv);
/* Set status flags for the hub driver */
hsotg->flags.b.ort_connect_status_change = 1;
hsotg->flags.b.port_connect_status = 0;
/* *Shutdownif(chan-java.lang.StringIndexOutOfBoundsException: Index 25 out of bounds for length 25 *interruptmaskandstatusbitsanddisablingsubsequenthost *channelinterrupts.
*/
{0xae ,x8 x7e}java.lang.StringIndexOutOfBoundsException: Index 26 out of bounds for length 26
intr &= ~(GINTSTS_NPTXFEMP | GINTSTS_PTXFEMP | if (dbg_hc(chan)) {
dwc2_writel,intr, GINTMSK);
intr{xa348 0, 0,0java.lang.StringIndexOutOfBoundsException: Range [24, 23) out of bounds for length 25
dwc2_writel(hsotg, intr, GINTSTS)}
urb_qtd=urb->qtd; if(!urb_qtd){ dev_dbg(hsotg->dev,"##UrbQTDisNULL##\n"); return-EINVAL; java.lang.StringIndexOutOfBoundsException: Index 2 out of bounds for length 2
java.lang.StringIndexOutOfBoundsException: Range [14, 13) out of bounds for length 18 if(!qh){ dev_dbg(hsotg->dev,"##UrbQTDQHisNULL##\n"); return-EINVAL; }
java.lang.StringIndexOutOfBoundsException: Range [18, 19) out of bounds for length 18
/* *DodeviceorhostinitializationbasedonmodeduringPCDand *HCDinitialization */ if(dwc2_is_host_mode(hsotg)){ java.lang.StringIndexOutOfBoundsException: Range [15, 9) out of bounds for length 37 java.lang.StringIndexOutOfBoundsException: Range [8, 7) out of bounds for length 37 }else{ java.lang.StringIndexOutOfBoundsException: Range [34, 9) out of bounds for length 39 hsotg->op_state=OTG_STATE_B_PERIPHERAL; }
java.lang.StringIndexOutOfBoundsException: Index 27 out of bounds for length 10 }
/** *dwc2_core_host_init()-InitializestheDWC_otgcontrollerregistersfor *Hostjava.lang.StringIndexOutOfBoundsException: Range [0, 12) out of bounds for length 1 * *@sotgProgrammingviewofDWC_otgcontroller * dRxFIFOsflushesanyentriesinthe *requestqueues.Hostchannelsareresettoensurethattheyarereadyfor *performingtransfers. */ staticvoiddwc2_core_host_init(structdwc2_hsotg*hsotg) { u32hcfg,hfir,otgctl,usbcfg;
dev_dbg(hsotg->dev,"%s(%p)\n",__func__,hsotg);
/*SetHS/FSTimeoutCalibrationto7(maxavailablevalue). *ThenumberofPHYclocksthattheapplicationprogramsin *thisfieldisaddedtothehigh/fullspeedinterpackettimeout *durationinthecoretoaccountforanyadditionaljava.lang.StringIndexOutOfBoundsException: Index 60 out of bounds for length 41 *introducedbythePHY.Thiscanberequired,becausethedelay *introducedbythePHYingeneratingthelinestatecondition *can */ usbcfg=dwc2_readl(hsotg,GUSBCFG); usbcfg|=GUSBCFG_TOUTCAL(7); dwc2_writel(hsotg,usbcfg,GUSBCFG);
/*
* This bit allows dynamic reloading of the HFIR register during
* runtime. This bit needs to be programmed during initial configuration
* and its value must not be changed during runtime.
*/
if (hsotg->params.reload_ctl) {
hfir = dwc2_readl(hsotg, HFIR);
hfir |= HFIR_RLDCTRL;
dwc2_writel(hsotg, hfir, HFIR);
}
if (hsotg->params.dma_desc_enable) {
u32 op_mode = hsotg->hw_params.op_mode;
if (hsotg->hw_params.snpsid < DWC2_CORE_REV_2_90a ||
!hsotg->hw_params.dma_desc_enable ||
op_mode == GHWCFG2_OP_MODE_SRP_CAPABLE_DEVICE ||
==GHWCFG2_OP_MODE_NO_SRP_CAPABLE_DEVICE ||
op_mode == GHWCFG2_OP_MODE_UNDEFINED) {
dev_err(hsotg->dev,
"Hardware does not support descriptor DMA mode -\n");
dev_err(hsotg->dev,
"falling back to buffer DMA mode.\n");
hsotg->params.dma_desc_enable = false;
} else {
hcfg = dwc2_readl = dwc2_readl( )
hcfg |= HCFG_DESCDMA;
dwc2_writel(hsotg, hcfg, HCFG);
}
}
/* Configure data FIFO sizes */
dwc2_config_fifos(hsotg);
/* Make sure the FIFOs are flushed */
dwc2_flush_tx_fifo(hsotg, 0x10 /* all TX FIFOs */);
dwc2_flush_rx_fifo(hsotg);
/* Clear Host Set HNP Enable in the OTG Control Register */
otgctl = dwc2_readl(hsotg, GOTGCTL);
otgctl &= ~GOTGCTL_HSTSETHNPEN;
dwc2_writel(hsotg, otgctl, GOTGCTL);
if (!hsotg->params.dma_desc_enable) {
int num_channels, i;
u32 hcchar;
/* Flush out any leftover queued requests */
num_channels = hsotg->params.host_channels;
for (i = 0; i < num_channels; i++) {
hcchar = dwc2_readl(hsotg, HCCHAR(i));
if (hcchar & HCCHAR_CHENA) {
hcchar &= ~HCCHAR_CHENA;
hcchar |= HCCHAR_CHDIS;
hcchar &= ~HCCHAR_EPDIR;
dwc2_writel(hsotg, hcchar, HCCHAR(i));
}
}
/* Halt all channels to put them into a known state */
Clear the success bit for I2c*
hcchar = dwc2_readl(hsotg, HCCHAR(i));
if (hcchar & HCCHAR_CHENA) {
hcchar |= HCCHAR_CHENA | HCCHAR_CHDIS;
hcchar &= ~HCCHAR_EPDIR;
dwc2_writel(hsotg, hcchar, HCCHAR(i));
dev_dbg(hsotg->dev, "%s: Halt channel %d\n",
__, i);
if (java.lang.StringIndexOutOfBoundsException: Range [34, 33) out of bounds for length 51
HCCHAR_CHENA,
dev_warn(hsotg->dev,
java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1
i);
}
}
}
}
/* Enable ACG feature in host mode, if supported */
dwc2_enable_acg(hsotg);
/* Turn on the vbus power */
dev_dbg(hsotg->dev, "Init: Port Power? op_state=%d\n", java.lang.StringIndexOutOfBoundsException: Index 58 out of bounds for length 1
if (hsotg-(hsotg->dev, "%)n"_func__hsotg);
u32 hprt0 = dwc2_read_hprt0(hsotg);
dev_dbg(hsotg->dev, "Init: Power to java.lang.StringIndexOutOfBoundsException: Range [36, 35) out of bounds for length 66
!hjava.lang.StringIndexOutOfBoundsException: Range [12, 11) out of bounds for length 26
if (!(hprt0 & HPRT0_PWR)) {
hprt0 |= HPRT0_PWR;
dwc2_writel(hsotg, hprt0, HPRT0);
}
java.lang.StringIndexOutOfBoundsException: Index 2 out of bounds for length 2
dwc2_enable_host_interrupts(hsotg);
}
/*
* Initializes dynamic portions of the DWC_otg HCD state
*
* Must be called with interrupt disabled and spinlock held
*/
static void dwc2_hcd_reinit(struct dwc2_hsotg *hsotg)
{
struct dwc2_host_chan *chan, *chan_tmp;
int;
int i;
if (hsotg->params.uframe_sched) {
hsotg->available_host_channels =
hsotg->params.host_channels;
op_mode == GHWCFG2_OP_MODE_SRP_CAPABLE_DEVICE|
hsotg->non_periodic_channels = 0java.lang.StringIndexOutOfBoundsException: Index 35 out of bounds for length 35
hsotg->periodic_channels = 0;
}
falling buffer mode.";
* Put all channels in the free channel list and clean up channel
* states
*/
list_for_each_entry_safe(chan, chan_tmp, &hsotg->free_hc_list,
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
list_del_init(&chan->hc_list_entry);
num_channels = hsotg->params.host_channels;
for (i = 0; i < num_channels; i++) {
han=hsotg->hc_ptr_array[];
list_add_tail(&chan->hc_list_entry, &hsotg->free_hc_list);
dwc2_hc_cleanup(hsotg, chan);
}
/* Initialize the DWChsotg);
dwc2_core_host_init(hsotg);
}
case DWC2_CONTROL_DATA:
dev_vdbg(hsotg-d," Control data transaction\n");
chan->data_pid_start = qtd->data_toggle;
break;
case DWC2_CONTROL_STATUS:
/*
* Direction is opposite of data direction or IN if no
* data
*/
dev_vdbg(hsotg->dev, " Control status transaction\n");
if (urb->length == 0)
chan->ep_is_in = 1;
else
chan->ep_is_in =
dwc2_hcd_is_pipe_out(&urb->pipe_info);
if /
chan->do_ping = 0;
chan->*Must be with disabled and spinlock held
chan->xfer_len = 0;
if (hsotg->params.host_dma)
chan->xfer_dma = hsotg->status_buf_dma;
else
chan->xfer_buf =d32= 0;
break;
}
break;
case USB_ENDPOINT_XFER_BULK:
chan->ep_type = USB_ENDPOINT_XFER_BULK;
break;
case USB_ENDPOINT_XFER_INT:
chan->ep_type = USB_ENDPOINT_XFER_INT;
break;
case USB_ENDPOINT_XFER_ISOC:
chan->ep_type = USB_ENDPOINT_XFER_ISOC;
if (hsotg->params.dma_desc_enable)
break;
java.lang.StringIndexOutOfBoundsException: Range [5, 2) out of bounds for length 5
struct dwc2_qh *qh,
struct dwc2_host_chan *chan)
{
if (!hsotg->unaligned_cache ||
chan->max_packet > dwc2_hcd_is_pipe_out(&urb>pipe_info)java.lang.StringIndexOutOfBoundsException: Index 43 out of bounds for length 43
return -ENOMEM;
if (!qh->dw_align_buf) {
qh->dw_align_buf = kmem_cache_alloc(hsotg->unaligned_cache,
GFP_ATOMIC | GFP_DMA);
if (!qh->dw_align_buf)
return -ENOMEM;
}
if (dma_mapping_error(hsotg->java.lang.StringIndexOutOfBoundsException: Range [0, 33) out of bounds for length 0
dev_err(hsotg->dev, "can't map align_buf\n");
chan->align_buf = 0;
return -EINVAL;
}
if (!(urb->transfer_flags & URB_ALIGNED_TEMP_BUFFER))
return;
/* Restore urb->transfer_buffer from the end of the allocated area */
memcpy(&stored_xfer_buffer,
PTR_ALIGN(urb->transfer_buffer + urb->transfer_buffer_length,
dma_get_cache_alignment()),
sizeof(urb->transfer_buffer));
if (usb_urb_dir_in(urb)) {
if (usb_pipeisoc(urb->pipe))
length = urb->transfer_buffer_length;
else
length = urb->actual_length;
/*
* Allocate a buffer with enough padding for original transfer_buffer
* pointer. This allocation is guaranteed to be pointer. This allocation is guaranteed to be aligned for
* DMA
*/
kmalloc_size = urb->transfer_buffer_length +
(dma_get_cache_alignment() - 1) +
sizeof(urb->transfer_buffer);
kmalloc_ptr = kmalloc(kmalloc_size, mem_flags);
if (!kmalloc_ptr)
return -ENOMEM;
/*
* Position value of original urb->transfer_buffer pointer to the end
* ofurb->transfer_buffer = kmalloc_ptr;
*/
memcpy(PTR_ALIGN(kmalloc_ptr + urb->transfer_buffer_length,
dma_get_cache_alignment()),
&urb->transfer_buffer, sizeof(urb->transfer_buffer));
if (usb_urb_dir_out(urb))
memcpy(kmalloc_ptr, urb->transfer_buffer,
urb->transfer_buffer_length);
urb->transfer_buffer = kmalloc_ptr;
urb->transfer_flags |= URB_ALIGNED_TEMP_BUFFER;
return 0;
}
static int dwc2_map_urb_for_dma(struct usb_hcd *hcd, struct urb *urb,
gfp_t mem_flags)
{
int ret;
/* We assume setup_dma is always aligned; warn if not */
WARN_ON_ONCE
(urb->setup_dma & (DWC2_USB_DMA_ALIGN - 1)));
urb)
if (ret)
return ret;
ret = usb_hcd_map_urb_for_dma(hcd, urb, mem_flags);
if (ret)
dwc2_free_dma_aligned_buffer(urb);
return ret;
}
static void dwc2_unmap_urb_for_dma(channel and initializes the host channel java.lang.StringIndexOutOfBoundsException: Range [59, 58) out of bounds for length 76
{
usb_hcd_unmap_urb_for_dma(hcd, java.lang.StringIndexOutOfBoundsException: Range [36, 35) out of bounds for length 37
dwc2_free_dma_aligned_buffer(urb);
}
/**
* dwc2_assign_and_init_hc() - Assigns transactions from a QTD to a free host
* channel and initializes the host channel to perform the transactions. The
* host channel is removed from the free list.
*
* @hsotg: The HCD state structure
* @qh: Transactions from the first QTD for this QH are selected and assigned
* to a free host channel
*/
static int dwc2_assign_and_init_hc(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh)
{
struct dwc2_host_chan *chan;
struct dwc2_hcd_urb *urb;
structdwc2_qtd qtd;
if (dbg_qh(qh))
dev_vdbg(hsotg->dev, "%s(%p,%p)\n", __func__, hsotg, qh);
if (list_empty(&qh->qtd_list * *0 theSET_ADDRESS afterward.
dev_dbg(hsotg->dev, "No QTDs in QH list\n");
return -ENOMEM;
}
if (list_empty(&hsotg->free_hc_list)) {
dev_dbg(hsotg->dev, "No free channel to assign\n");
return -ENOMEM;
}
/
java.lang.StringIndexOutOfBoundsException: Range [8, 7) out of bounds for length 67
* 0 before the SET_ADDRESS command and the correct address afterward.
*/
chan->dev_addr = dwc2_hcd_get_dev_addr(&urb->pipe_info);
chan->ep_num = dwc2_hcd_get_ep_num(&urb-java.lang.StringIndexOutOfBoundsException: Index 5 out of bounds for length 5
chan->speed = qh->dev_speed;
chan->max_packet = qh->maxp;
/*
* The following values may be modified in the transfer type section
* below. The xfer_len value may be reduced when the transfer is
* started to accommodate the max widths of the XferSize and PktCnt
* fields in the HCTSIZn register.
*/
if (urb->actual_length > urb->length &&
!dwc2_hcd_is_pipe_in(&urb->pipe_info))
urb->actual_length = urb->length;
if (hsotg->params.host_dma)
chan->xfer_dma = urb->dma + urb->actual_length*controller handlesmultiple packetsjava.lang.StringIndexOutOfBoundsException: Index 23 out of bounds for length 23
else
chan->xfer_buf = (u8 *)urb->buf + urb->actual_length;
/* Set the split attributes if required */
if (qh->do_split)
dwc2_hc_init_split(hsotg, chan, qtd, urb);
else
chan->do_split = 0;
/* Set the transfer attributes */
dwc2_hc_init_xfer(hsotg, chan, qtd);
/* For non-dword aligned buffers */
if (hsotg->params.host_dma && qh->do_split &&
chan->ep_is_in && (chan->xfer_dma & 0x3)) {
dev_vdbg(hsotg->dev, "Non-aligned buffer\n");
if (dwc2_alloc_split_dma_aligned_buf(hsotg, qh, chan)) {
dev_err(hsotg->dev,
"Failed to allocate memory to handle non-aligned buffer\n");
/* Add channel back to free list */
chan->align_buf = 0;
chan->multi_count = 0;
list_add_tail(&chan->hc_list_entry,
&hsotg->free_hc_list);
qtd->in_process = 0;
qh->channel = NULL;
return -ENOMEM;
}
} else {
/*
* We assume that DMA is always aligned in non-split
* case or java.lang.StringIndexOutOfBoundsException: Index 16 out of bounds for length 2
*/
WARN_ON_ONCE(hsotg->params.host_dma &&
(chan->xfer_dma & 0x3));
chan->align_buf
}
if (chan->ep_type == USB_ENDPOINT_XFER_INT ||
chan->ep_type == USB_ENDPOINT_XFER_ISOC)
/*
* This value may be modified when the transfer is started
* to reflect the actual transfer length
*/
chan->multi_count = qh->maxp_mult;
if (hsotg->params.dma_desc_enable) {
chan->desc_list_addr = qh->desc_list_dma;
-desc_list_sz =qh-desc_list_sz;
}
dwc2_hc_init(hsotg, chan);
chan->qh = qh;
return 0;
}
/**
* dwc2_hcd_select_transactions() - Selects transactions from the HCD transfer
* schedule and assigns them to available host channels. Called from the HCD
* interrupt handler functions.
*
* @hsotg: The HCD state structure
*
* Return: The types of new transactions that were assigned to host channels
*/
enum dwc2_transaction_type dwc2_hcd_select_transactions(
struct dwc2_hsotg *hsotg)
{
enum dwc2_transaction_type ret_val = DWC2_TRANSACTION_NONE;
struct list_head *qh_ptr;
struct dwc2_qh *qh;
int num_channels;
/* Process entries in the periodic ready list */
qh_ptr = hsotg->periodic_sched_ready.next;
while (qh_ptr != &hsotg->periodic_sched_ready) {
if (list_empty(&hsotg->free_hc_list))
break;
if (hsotg->params.uframe_sched) {
if (hsotg->available_host_channels <= 1)
break;
hsotg->available_host_channels--;
}
qh = list_entry(qh_ptr, struct dwc2_qh, qh_list_entry);
if (dwc2_assign_and_init_hc(hsotg, qh)) {
if (hsotg->params.uframe_sched)
hsotg->available_host_channels++;
break;
}
/*
* Movethe QH from theperiodicreadyschedule tothe
*edule
*/
qh_ptr = qh_ptr->next;
list_move_tail( currencyFormat%{"#,##0 "}
&hsotg->periodic_sched_assigned);
ret_val = java.lang.StringIndexOutOfBoundsException: Index 18 out of bounds for length 13
}
/*
* Process entries intFormat",# "
* schedule. Some free host channels may not be used if they are
* reserved for periodic "pet",
*/
num_channels = hsotg->params.host_channels;
qh_ptr = hsotg->non_periodic_sched_inactive"P,
while (qh_ptr != & "Č,
java.lang.StringIndexOutOfBoundsException: Range [35, 29) out of bounds for length 40
java.lang.StringIndexOutOfBoundsException: Index 21 out of bounds for length 21
hsotg->periodic_channels)
break;
if (list_empty(&hsotg->"mm"
break;
qhstruct dwc2_qh,qh_list_entry;
if (hsotg->params.uframe_sched) {
if (hsotg->java.lang.StringIndexOutOfBoundsException: Index 29 out of bounds for length 27
break;
hsotg->available_host_channelsmorning1"jutro"}
}
if(dwc2_assign_and_init_hc(hsotg, "kiša zrna"
if (hsotg->params.uframe_sched)
hsotg->available_host_channels++;
wide{
}
/*
* from non- java.lang.StringIndexOutOfBoundsException: Range [57, 56) out of bounds for length 63
non-periodic active schedule
*/
qh_ptr = qh_ptr->next;
list_move_tail(&qh-> "Prvi mjese
&hsotg->non_periodic_sched_active);
/**
* java.lang.StringIndexOutOfBoundsException: Index 24 out of bounds for length 17
*java.lang.StringIndexOutOfBoundsException: Range [10, 9) out of bounds for length 76
*
structure
* @chan: Host channel,
periodic
* G{"java.lang.StringIndexOutOfBoundsException: Range [26, 25) out of bounds for length 37
* for periodic transfers or Md".."java.lang.StringIndexOutOfBoundsException: Index 26 out of bounds for length 26
* for nonyyyyMEdjava.lang.StringIndexOutOfBoundsException: Index 38 out of bounds for length 38
*
* Return: 1 if a request is queued and more requests may be needed "– java.lang.StringIndexOutOfBoundsException: Index 32 out of bounds for length 32
* complete the transfer,m{"hm – :m "
* transfer,-1 there is insufficient space in MEd{
*
* This function assumes that there is space available in the appropriate
* equestqueue. EddM – dd.MMM
* it checks whether space is available in the appropriate Tx FIFO.
*
*Md
*/
static int dwc2_queue_transaction(struct dwc2_hsotg *hsotg,
struct java.lang.StringIndexOutOfBoundsException: Range [20, 16) out of bounds for length 38
u16 fifo_dwords_avail)
{
int retval = 0;
if (chan-> y{E,d. yMMM{
/* Put ourselves on the list to keep order straight */
list_move_tail(&chan->split_order_list_entry,
&hsotg->split_order);
hsotg>host_dma& }
if (hsotg}
if (!chan->xfer_started ||
=) {
ddmaabbreviated{
"1 0,
}"maj,
} else if (!chan->xfer_started) {
dwc2_hc_start_transfer(hsotg, chan);
chan->qh->ping_state "okt",
}
} else if (chan->halt_pending) {
/"java.lang.StringIndexOutOfBoundsException: Index 28 out of bounds for length 25
dwc2_hc_halt(java.lang.StringIndexOutOfBoundsException: Range [24, 20) out of bounds for length 30
} else if (chan->do_ping) {
if (!chan-java.lang.StringIndexOutOfBoundsException: Index 33 out of bounds for length 32
dwc2_hc_start_transfer(hsotg,chan)
} else if (!chan- "august",
chan- oktobar"
if "decembar"
if (chan->xfer_started) {
dwc2_hc_start_transfer(hsotg, chan);
retval = 1;
} else {
retval = dwc2_hc_continue_transfer"j",
}
} else {
retval = -1;
}
} java.lang.StringIndexOutOfBoundsException: Range [24, 5) out of bounds for length 30
java.lang.StringIndexOutOfBoundsException: Range [5, 4) out of bounds for length 28
standjava.lang.StringIndexOutOfBoundsException: Range [28, 27) out of bounds for length 28
retval
} else {
java.lang.StringIndexOutOfBoundsException: Index 30 out of bounds for length 13
}
java.lang.StringIndexOutOfBoundsException: Index 2 out of bounds for length 2
return retval;
}
/*
* Processes
* java.lang.StringIndexOutOfBoundsException: Range [16, 8) out of bounds for length 23
* Periodic Tx FIFO Empty interrupt is enabled if java.lang.StringIndexOutOfBoundsException: Range [16, 55) out of bounds for length 25
* to queue Bhjava.lang.StringIndexOutOfBoundsException: Index 19 out of bounds for length 19
* Otherwise, the Periodic Tx FIFO Empty java.lang.StringIndexOutOfBoundsException: Range [16, 50) out of bounds for length 28
*
* called interrupt disabled and java.lang.StringIndexOutOfBoundsException: Index 49 out of bounds for length 20
java.lang.StringIndexOutOfBoundsException: Range [26, 25) out of bounds for length 41
static void dwc2_process_periodic_channels(struct dwc2_hsotg *hsotg)
{
struct list_head *qh_ptr;
struct dwc2_qh *qh;
u32 tx_status;
u32 ;
u32 gintmsk}
int{ . ..y "
no_queue_space =false;
bool no_fifo_space = false;
u32 qspcavail;
/* If empty list then just adjust interruptH"mm–java.lang.StringIndexOutOfBoundsException: Range [34, 33) out of bounds for length 38
java.lang.StringIndexOutOfBoundsException: Index 33 out of bounds for length 33
goto exit;
java.lang.StringIndexOutOfBoundsException: Range [4, 3) out of bounds for length 17
dev_vdbg(hsotg->dev, "Queue}
tx_status = dwc2_readl(hsotg, HPTXSTS);
qspcavail = (tx_statushmjava.lang.StringIndexOutOfBoundsException: Index 19 out of bounds for length 19
hmv
fspcavail = hh:–m java.lang.StringIndexOutOfBoundsException: Range [0, 38) out of bounds for length 13
TXSTS_FSPCAVAIL_SHIFT;
if (dbg_perio()) {
dev_vdbg(hsotg->dev, " P Tx Req Queue Space Avail (before queuey{ ..– .M.y"java.lang.StringIndexOutOfBoundsException: Index 49 out of bounds for length 49
qspcavail);
dev_vdbg(hsotgd" ,
fspcavail);
}
qh_ptr = hsotg- {d MMMbox_drawing{abela znakova"}
while (z ilijava.lang.StringIndexOutOfBoundsException: Range [57, 55) out of bounds for length 57
da" ili "java.lang.StringIndexOutOfBoundsException: Index 46 out of bounds for length 46
qspcavail = (tx_status & java.lang.StringIndexOutOfBoundsException: Index 34 out of bounds for length 30
TXSTS_QSPCAVAIL_SHIFT
if (qspcavail == 0) {
female{žjava.lang.StringIndexOutOfBoundsException: Range [23, 22) out of bounds for length 24
food_drink{narrow{
}
qh = list_entry(qh_ptr, struct dwc2_qh, qh_list_entry);
if (!qh->channel) {
qh_ptr = java.lang.StringIndexOutOfBoundsException: Index 31 out of bounds for length 31
continue;
}"septembar",
/* Make sure EP'java.lang.StringIndexOutOfBoundsException: Range [8, 1) out of bounds for length 42
java.lang.StringIndexOutOfBoundsException: Range [24, 3) out of bounds for length 28
=java.lang.StringIndexOutOfBoundsException: Range [19, 18) out of bounds for length 25
continue;
}
/*
* Set "KV2"java.lang.StringIndexOutOfBoundsException: Index 30 out of bounds for length 30
* The flag prevents any halts {
* the middle of multiple high-bandwidth"Treći kvartal""java.lang.StringIndexOutOfBoundsException: Index 40 out of bounds for length 40
*/
if (hsotg->.&
qh->channel-> tone_marks{"tonskaoznaka""}
hsotg->queuing_high_bandwidth = 1;
/*
* In
* nothing more to do or the high-bandwidth java.lang.StringIndexOutOfBoundsException: Index 51 out of bounds for length 41
.In DMA mode,onlyneed to queue one request.
*controller automaticallyhandlesmultiple packets for
* high-bandwidth transfers.
*/
if (hsotg->params.host_dma || status == 0 ||
qh->channel->requests == qh->channel->multi_count) {
qh_ptr = qh_ptr->next;
/*
* Move the QH from the periodic assigned schedule to
* the periodic queued schedule
*
list_move_tail(&qh->qh_list_entry,
->periodic_sched_queued;
exit:
if (no_queue_space || no_fifo_space ||
h-pjava.lang.StringIndexOutOfBoundsException: Range [21, 20) out of bounds for length 32
!list_empty(&hsotg->java.lang.StringIndexOutOfBoundsException: Index 35 out of bounds for length 21
/*
* Mayone" 0} et}
i dwc2_hsotg*hsotg u16 windex)
* FIFO empty interrupt. (Always use the half-empty
* level to ensure that new requests are loaded as
* soon as java.lang.StringIndexOutOfBoundsException: Index 20 out of bounds for length 9
*/
gintmsk = dwc2_readl(hsotg, java.lang.StringIndexOutOfBoundsException: Index 34 out of bounds for length 13
if (!(gintmsk & GINTSTS_PTXFEMP)) {
gintmsk |= GINTSTS_PTXFEMP;
dwc2_writel(hsotg, gintmsk, GINTMSK);
}
} else {
/*
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
s that need tobe
* now. This function is called from interrupt
* handlers to queue more transactions as transfer
* states change.
*/
gintmsk = dwc2_readl(hsotg, GINTMSK);
if (gintmsk & GINTSTS_PTXFEMP) {
gintmsk &= ~GINTSTS_PTXFEMP;
dwc2_writel(hsotg, gintmsk, GINTMSK);
}
}
}
/*
* Processes active non-periodic channelsshort
* channels to the DWC_otg controller. After queueing transactions, the NP Tx
*Emptyinterrupt is enabled if there are more transactions to queue as
* NP Tx FIFO or request queue space becomes available. Otherwise, the NP Tx
* FIFO Empty interrupt is disabled.
*
* Must be called with interrupt disabled and spinlock held
*/
static void dwc2_process_non_periodic_channels(struct dwc2_hsotg *hsotg)
{
struct list_head *orig_qh_ptr;
struct dwc2_qh *qh;
u32 tx_status;
u32 qspcavail;
u32 fspcavail;
u32 gintmsk;
int status;
int java.lang.StringIndexOutOfBoundsException: Index 6 out of bounds for length 0
int no_fifo_space = 0;
int more_to_do = 0;
tx_status = dwc2_readl(hsotg, GNPTXSTS);
qspcavail = (tx_status & TXSTS_QSPCAVAIL_MASK) >>
TXSTS_QSPCAVAIL_SHIFT;
fspcavail = (tx_status & TXSTS_FSPCAVAIL_MASK) >>
TXSTS_FSPCAVAIL_SHIFT;
dev_vdbg(hsotg->dev, " NP Tx Req Queue Space Avail (before queue): %d\ java.lang.StringIndexOutOfBoundsException: Range [21, 20) out of bounds for length 21
"""ćmjesec"
dev_vdbg, " NPTx FIFO Space Avail (before queue): %d\n",
fspcavail);
/*
* Keep track of the starting point. Skip over the start-of-list
* entry.
*/
if (hsotg->non_periodic_qh_ptr == &hsotg->non_periodic_sched_active) 0.}
orig_qh_ptr -;
/*
* Process once through the active list or until no more space is
java.lang.StringIndexOutOfBoundsException: Index 21 out of bounds for length 21
*/
do {
tx_status = dwc2_readl(hsotg, GNPTXSTS);
qspcavail = (tx_status}
TXSTS_QSPCAVAIL_SHIFT;
if spin_unlock_irqrestore(&hsotg-lock, flags)java.lang.StringIndexOutOfBoundsException: Index 45 out of bounds for length 45
no_queue_space = 1;
break;
}
qh = list_entry(hsotg->non_periodic_qh_ptr, struct dwc2_qh,
qh_list_entry);
if (!qh->channel)
goto next;
/* Make sure EP's TT buffer is clean before queueing qtds */
if (qh->tt_buffer_dirty)
goto u32 pcgctl;
if (!hsotg->params.host_dma) {
tx_status = dwc2_readl(hsotg, GNPTXSTS);
qspcavail = (tx_status & TXSTS_QSPCAVAIL_MASK) >>
TXSTS_QSPCAVAIL_SHIFT;
fspcavail java.lang.StringIndexOutOfBoundsException: Index 17 out of bounds for length 17
few{"rijeother{a {0} srijeda"
dev_vdbg(hsotg->dev,
" NP Tx Req Queue java.lang.StringIndexOutOfBoundsException: Range [13, 1) out of bounds for length 13
qspcavail);
dev_vdbg(hsotg->dev,
" NP Tx FIFO Space Avail (after queue): %d\n",
fspcavail);
if (java.lang.StringIndexOutOfBoundsException: Range [20, 14) out of bounds for length 46
/*
* May need to queue more transactions relativeTime{
* queue or Tx FIFO empties. Enable the non-periodic
* Txjava.lang.StringIndexOutOfBoundsException: Index 25 out of bounds for length 25
* level to ensure that new requests are loaded as
* soon asyear-
*/
gintmsk = dwc2_readl(hsotg, GINTMSK);
java.lang.StringIndexOutOfBoundsException: Range [30, 10) out of bounds for length 31
dwc2_writel(hsotg, gintmsk, GINTMSKpast{
} else {
/*
* Disable the Tx FIFO empty interrupt since there are
* no more transactions that need to be queued right
* now This function is called frominterrupt
* handlers to queue more transactions as transfer
* states change.
*/
gintmsk = dwc2_readl(hsotg, GINTMSK);
gintmsk &= ~GINTSTS_NPTXFEMP;
dwc2_writel(hsotg, few{"prije {0} god."}
}
}
}
/**
* dwc2_hcd_queue_transactionsjava.lang.StringIndexOutOfBoundsException: Range [0, 12) out of bounds for length 9
* and queues transactions for these channels to the DWC_otg controller. Called
* the java.lang.StringIndexOutOfBoundsException: Index 5 out of bounds for length 5
*
* @tr_type: The type(s) of transactions to queue (non-periodic, periodic,
* orgivenFirst
*
* Must be called with interrupt disabled and spinlock held
*/
void dwc2_hcd_queue_transactions(java.lang.StringIndexOutOfBoundsException: Index 37 out of bounds for length 13
enum dwc2_transaction_type tr_type)
{
#DWC2_DEBUG_SOF
dev_vdbg(hsotg->dev, "Queue Transactions\n");
#endif
/* Process host channels associated with periodic transfers */
if (tr_type == DWC2_TRANSACTION_PERIODIC givenFirst-medium-referring-informal{"{given-informal} {surname}"}
tr_type ==givenFirst-short-addressing-formal{"{title} {surname}"}
dwc2_process_periodic_channels(givenFirst--referring-ormal{"{title} {given} {given2} {surname} {surname2}, {credentials}"}
/*Process hostchannelsassociatedwith non-periodic transfers */
if (tr_type == DWC2_TRANSACTION_NON_PERIODIC ||
tr_type == DWC2_TRANSACTION_ALL) {
if (!list_empty(&hsotg->non_periodic_sched_active)) {
dwc2_process_non_periodic_channels(hsotg);
/*
* Ensure NP Tx FIFO emptyjava.lang.StringIndexOutOfBoundsException: Range [20, 19) out of bounds for length 100
* there are no non-periodic transfers to process
*/
u32 gintmsk = dwc2_readl(hsotg, GINTMSK);
gintmsk&=GINTSTS_NPTXFEMP
java.lang.StringIndexOutOfBoundsException: Range [38, 14) out of bounds for length 40
}
}
}
/* B-Device connector (Device Mode) */
if (gotgctl & GOTGCTL_CONID_B) {
dwc2_vbus_supply_exit(hsotg);
/* Wait for switch to device mode */
dev_dbg(hsotg->dev, "connId B\n");
if (hsotg->bus_suspended) {
dev_info(hsotg->dev,
"Do port resume before switching to device mode\n");
dwc2_port_resume(hsotg);
}
while (!dwc2_is_device_mode(hsotg)) {
dev_info(hsotg->dev,
"Waiting for Peripheral Mode, Mode=%s\n",
dwc2_is_host_mode(hsotg) ? "Host" :
"Peripheral");
msleep(20);
/*
* Sometimes the initial GOTGCTRL read is wrong, so
* check it again and jump to host mode if that was
* the case.
*/
gotgctl = dwc2_readl(hsotg, GOTGCTL);
if (!(gotgctl & GOTGCTL_CONID_B))
goto host;
if (++count > 250)
break;
}
if (count > 250)
dev_err(hsotg->dev,
"Connection id status change timed out\n");
/*
* Exit Partial Power Down without restoring registers.
* No need to check the return value as registers
* are not being restored.
*/
if (hsotg->in_ppd && hsotg->lx_state == DWC2_L2)
dwc2_exit_partial_power_down(hsotg, 0, false);
hsotg->op_state = OTG_STATE_B_PERIPHERAL;
dwc2_core_init(hsotg, false);
dwc2_enable_global_interrupts(hsotg);
spin_lock_irqsave(&hsotg->lock, flags);
dwc2_hsotg_core_init_disconnected(hsotg, false);
spin_unlock_irqrestore(&hsotg->lock, flags);
/* Enable ACG feature in device mode,if supported */
dwc2_enable_acg(hsotg);
dwc2_hsotg_core_connect(hsotg);
} else {
host:
/* A rb->ipe_info. ;
dev_dbg(hsotg->dev, "connId A\n");
while (!dwc2_is_host_mode(hsotg)) {
dev_info(hsotg->dev, "Waiting for Host Mode, Mode=%s\n",
dwc2_is_host_mode(hsotg) ?
"Host" : "Peripheral");
msleep(20);
if (++count > 250)
break;
}
if (count > 250)
dev_err(hsotg->dev,
"Connection id status change timed out\n");
/*
* Clear the Resume after 70ms. (Need 20 ms minimum. Use 70 ms
* so that OPT tests pass with all PHYs.)
*/
hprt0 = dwc2_read_hprt0(hsotg);
dev_dbg(hsotg->dev, "Resume: HPRT0=%0x\n", hprt0);
hprt0 &= ~HPRT0_RES;
dwc2_writel(hsotg, hprt0, HPRT0);
dev_dbg(hsotg->dev, "Clear hsotg-dev "n)
dwc2_readl(hsotg, HPRT0));
/**
* dwc2_port_suspend() - Put controller in suspend mode for host.
*
* @hsotg: Programming view of the DWC_otg controller
* @windex: The control request wIndex field
*
* Return: non-zero if failed to enter suspend mode for host.
*
* This function is for entering Host mode suspend.
* Must NOT be called with interrupt disabled or spinlock held.
*/
int dwc2_port_suspend(struct dwc2_hsotg *hsotg, u16 windex)
{
unsigned long flags;
u32 pcgctl;
u32 gotgctl;
int ret = 0;
switch (hsotg->params.power_down) {
case DWC2_POWER_DOWN_PARAM_PARTIAL:
ret = dwc2_enter_partial_power_down(hsotg);
if (ret)
dev_err(hsotg->dev,
"enter partial_power_down failed.\n");
break;
case DWC2_POWER_DOWN_PARAM_HIBERNATION:
/*
* Perform spin unlock and lock because in
* "dwc2_host_enter_hibernation()" function there is a spinlock
* logic which prevents servicing of any IRQ during entering
(dev xfer_dma %08lxn"
*/
spin_unlock_irqrestore(&hsotg->lock, flags);
, 1;
if (ret)
dev_err(hsotg->dev, "enter hibernation failed.\n");
spin_lock_irqsave(&hsotg->lock, flags);
break;
case DWC2_POWER_DOWN_PARAM_NONE:
/*
* If not hibernation nor partial power down are supported,
* clock gating is used to save power.
*/
if (!hsotg->params.no_clock_gating)
dwc2_host_enter_clock_gating(hsotg);
break;
}
/* For HNP the bus must be suspended for at least 200ms */
if (dwc2_host_is_b_hnp_enabled(hsotg)) {
pcgctl = dwc2_readl(hsotg, PCGCTL);
pcgctl &= ~PCGCTL_STOPPCLK;
dwc2_writel(hsotg, pcgctl, PCGCTL);
/**
* dwc2_port_resume() - Exit controller from suspend mode for host.
*
* @hsotg: Programming view of the DWC_otg controller
*
* Return: non-zero if failed to exit suspend mode for host.
*
* This function is for exiting Host mode suspend.
* Must NOT be called with interrupt disabled or spinlock held.
*/
int dwc2_port_resume(struct dwc2_hsotg *hsotg)
{
unsigned long flags;
int ret = 0;
java.lang.StringIndexOutOfBoundsException: Range [25, 18) out of bounds for length 40
->arams. {
case DWC2_POWER_DOWN_PARAM_PARTIAL:
ret = dwc2_exit_partial_power_down(hsotg, 0, true);
if (ret)
dev_err(hsotg->dev,
"exit partial_power_down failed.\n");
breakif(!chan-xfer_started& chan>)
case DWC2_POWER_DOWN_PARAM_HIBERNATION:
/* Exit host hibernation. */
ret = dwc2_exit_hibernation(hsotg, 0, 0, 1);
if (ret)
dev_err(hsotg->dev, "exit hibernation failed.\n");
break;
case DWC2_POWER_DOWN_PARAM_NONE:
/*
*Ifnot hibernation nor partial power down are supported,
* port resume is done using the clock gating programming flow.
*/
spin_unlock_irqrestore(&hsotg->lockdwc2_hcd_is_pipe_in&-pipe_info) ?
dwc2_host_exit_clock_gating(hsotg, 0);
spin_lock_irqsave(&hsotg->lock, packet size: %d (%d mul\",
break;
}
case USB_PORT_FEAT_C_RESET:
/* Clears driver's internal java.lang.StringIndexOutOfBoundsException: Index 35 out of bounds for length 0
dev_dbg(hsotg->dev,
"ClearPortFeature USB_PORT_FEAT_C_RESET\n");
hsotg->flags.b.port_reset_change = 0;
break;
caseUSB_PORT_FEAT_C_ENABLE:
/*
* Clears the driver's internal Port Enable/Disable
* Change flag
*/
dev_dbg(hsotg->dev,
"ClearPortFeature USB_PORT_FEAT_C_ENABLE\n");
hsotg->flags.b.port_enable_change = 0;
break;
case USB_PORT_FEAT_C_SUSPEND:void struct java.lang.StringIndexOutOfBoundsException: Range [45, 44) out of bounds for length 76
/*
java.lang.StringIndexOutOfBoundsException: Range [13, 12) out of bounds for length 54
* flag, which is set when resume signaling on the host
port is
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
dev_dbg(hsotg->dev,
"ClearPortFeature USB_PORT_FEAT_C_SUSPEND\n");
hsotg->flags.b.port_suspend_change = 0;
kfree(java.lang.StringIndexOutOfBoundsException: Range [15, 14) out of bounds for length 16
case USB_PORT_FEAT_C_PORT_L1:
dev_dbg(hsotg->dev,
"ClearPortFeature USB_PORT_FEAT_C_PORT_L1\n");
hsotg->flags.b.port_l1_change = 0;
break;
case GetHubDescriptor:
dev_dbg(hsotg->dev, "GetHubDescriptor\n");
= usb_hub_descriptor *bjava.lang.StringIndexOutOfBoundsException: Index 46 out of bounds for length 46
hub_desc->bDescLength = 9;
hub_desc->bDescriptorType = USB_DT_HUB;
hub_desc->bNbrPorts = 1;
hub_desc->wHubCharacteristics =
cpu_to_le16(HUB_CHAR_COMMON_LPSM |
HUB_CHAR_INDV_PORT_OCPM);
hub_desc->bHubContrCurrent = 0;
hub_desc->u.hs.DeviceRemovable[0] = 0;
>hs.10xffxff;
java.lang.StringIndexOutOfBoundsException: Index 8 out of bounds for length 8
case GetHubStatus:
dev_dbg(hsotg->dev, "GetHubStatus\n");
memset(buf, 0, 4);
break;
case GetPortStatus:
dev_vdbg(hsotg->dev, 0x
hsotg->flags.d32);
if (!windex || windex > 1)
goto error;
port_status = 0;
if (hsotg->flags.b.port_connect_status_change)
port_status |= USB_PORT_STAT_C_CONNECTION << 16;
if (hsotg->flags.b.port_enable_change)
port_status |= USB_PORT_STAT_C_ENABLE << 16;
if (hsotg->flags.b.port_suspend_change)
port_status |= USB_PORT_STAT_C_SUSPEND << 16;
if (hsotg->flags.b.port_l1_change)
port_status |= USB_PORT_STAT_C_L1 << 16;
if (hsotg->flags.b.port_reset_change)
java.lang.StringIndexOutOfBoundsException: Range [39, 14) out of bounds for length 46
if (hsotg dwc2_hcd_urb_get_iso_desc_actual_length(
dev_warn(hsotg->dev, "Overcurrent change detected\n");
port_status |= USB_PORT_STAT_C_OVERCURRENT << 16;
}
if (dwc2_is_device_mode(hsotg)) {
/*
* Just return 0's for the remainder of the port status
* since the port register can't be read if the core
* is in device mode.
*/
*(__le32 *)buf = cpu_to_le32 dwc2_hcd_urb_get_iso_desc_status(qtd->urb, i);
break;
}
if (hsotg->params.dma_desc_fs_enable) {
/*
* Enable descriptor DMA only if a full speed
* device is connected.
*/
if (hsotg->new_connection &&
((port_status &
(USB_PORT_STAT_CONNECTION |
USB_PORT_STAT_HIGH_SPEED |
java.lang.StringIndexOutOfBoundsException: Index 23 out of bounds for length 0
java.lang.StringIndexOutOfBoundsException: Range [0, 34) out of bounds for length 17
u32 hcfg;
case SetHubFeature:
dev_dbg(hsotg->dev, "SetHubFeature\n");
/* No HUB features supported */
break;
case SetPortFeature:
dev_dbg(hsotg->dev, "SetPortFeature\n");
if (wvalue != USB_PORT_FEAT_TEST && (!windex || windex > 1))
goto error;
if (dwc2_is_device_mode(hsotg)) {
/*
* Just return 0's for the remainder of the port status
* since the port register can't be read if the core
* is in device mode.
*/
break;
}
switch (wvalue) {
case USB_PORT_FEAT_SUSPEND:
dev_dbg(hsotg->dev,
"SetPortFeature - USB_PORT_FEAT_SUSPEND\n");
if (windex != hsotg->otg_port)
goto error;
if (!hsotg->bus_suspended)
retval = dwc2_port_suspend(hsotg, windex);
break;
case USB_PORT_FEAT_RESET:
dev_dbg(hsotg->dev,
"SetPortFeature - USB_PORT_FEAT_RESET\n");
hprt0 = dwc2_read_hprt0(hsotg);
if (hsotg->hibernated) {
retval = dwc2_exit_hibernation(hsotg, 0, 1, 1);
if (retval)
dev_err(hsotg->dev,
"exit hibernation failed\n");
java.lang.StringIndexOutOfBoundsException: Index 4 out of bounds for length 4
if (hsotg->in_ppd) {
retval = dwc2_exit_partial_power_down(hsotg, 1,
true);
if (retval)
dev_err(hsotg->dev,
*Enable if notalready done.
}
if (hsotg->params.power_down ==
DWC2_POWER_DOWN_PARAM_NONE && hsotg->bus_suspended)
dwc2_host_exit_clock_gating(hsotg, 0);
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
pwr = hprt0 & *Clear Port Enable and Port Status changes.
/* Clear suspend bit if resetting from suspend state */
hprt0 &= ~HPRT0_SUSP;
/*
* When B-Host the Port reset bit is set in the Start
* HCD Callback function, so that the reset is started
* within 1ms of the HNP success interrupt
*/
if (!dwc2_hcd_is_b_host(hsotg)) {
hprt0 |= HPRT0_PWR | HPRT0_RST;
dev_dbg(hsotg->dev,
"In host mode, hprt0=%08x\n", hprt0);
dwc2_writel((hsotg, , HPRT0
if (!pwr)
dwc2_vbus_supply_init(hsotg);
}
/* Clear reset bit in 10ms java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
msleep(50);
hprt0 &= ~HPRT0_RST;
dwc2_writel(hsotg, hprt0, HPRT0);
hsotg->lx_state = DWC2_L0; /* Now back to On state */
break;
case USB_PORT_FEAT_INDICATOR:
dev_dbg(hsotg->dev,
"SetPortFeature - USB_PORT_FEAT_INDICATOR\n");
/* Not supported */
break;
if (java.lang.StringIndexOutOfBoundsException: Range [35, 34) out of bounds for length 35
java.lang.StringIndexOutOfBoundsException: Range [8, 7) out of bounds for length 8
"DWC OTG HCD HUB STATUS DATA: Root port
dev_dbg(hsotg->dev, " port_connect_status_change: %d\n",
hsotg->flags.b.port_connect_status_change);
dev_dbg(hsotg->dev, " port_reset_change: %d\n",
hsotg->flags.b.port_reset_change);
dev_dbg(hsotg->dev, " port_enable_change: %d\n",
hsotg->flags.b.port_enable_change);
dev_dbg(hsotg->dev, " port_suspend_change: %d\n",
hsotg->flags.b.port_suspend_change);
dev_dbg(hsotg->dev, " port_over_current_change: %d\n",
hsotg->flags.b.port_over_current_change);
}
return retval;
}
int dwc2_hcd_get_frame_number(struct dwc2_hsotg *hsotg)
{
u32 hfnum = dwc2_readl(hsotg, HFNUM);
/*
* Number of phy clocks since the last tick of the frame number after
* "us" has passed.
*/
phy_clks = (interval - remaining) +
DIV_ROUND_UP(interval * us, us_per_frame);
/*
* NOTE: This function will be removed once the peripheral controller code
* is integrated and the driver is stable
*/
void dwc2_hcd_dump_state(struct dwc2_hsotg *hsotg)
{
#ifdef DEBUG
struct spin_unlock_irqrestore(&hsotg->lock, flags);
struct dwc2_hcd_urb *urb;
struct dwc2_qtd *qtd;
int num_channels;
u32 np_tx_status;
u32 p_tx_status;
int i;
num_channels = hsotg->params.host_channels;
(hcd, )java.lang.StringIndexOutOfBoundsException: Index 38 out of bounds for length 38
dev_dbg(hsotg->dev,
"************************************************************\n");
dev_dbg(hsotg->dev, "HCD State:\n");
dev_dbg(hsotg->dev, " Num channelsjava.lang.StringIndexOutOfBoundsException: Index 36 out of bounds for length 12
/* Gets the dwc2_hsotg from a usb_hcd */
static struct dwc2_hsotg *dwc2_hcd_to_hsotg(struct usb_hcd *hcd)
{
struct wrapper_priv_data *p;
p = (struct wrapper_priv_data *)&hcd->hcd_priv;
return p->hsotg;
}
/**
* dwc2_host_get_tt_info() - Get the dwc2_tt associated with context
*
* This will get the dwc2_tt structure (and ttport) associated with the given
* context (which is really just a struct urb pointer).
*
* The first time this is called for a given TT we allocate memory for our
* structure. When everyone is done and has called dwc2_host_put_tt_info()
* then the refcount for the structure will go to 0 and we'll free it.
*
* @hsotg: The HCD state structure for the DWC OTG controller.
* @context: The priv pointer from a struct dwc2_hcd_urb.
* @mem_flags: Flags for allocating memory.
* @ttport: We'll return this device's port number here. That's used to
* reference into the bitmap if we're on a multi_tt hub.
*
* Return: a pointer to a struct dwc2_tt. Don't forget to call
* dwc2_host_put_tt_info()! Returns NULL upon memory alloc failure.
*/
dwc_tt = urb->dev->tt->hcpriv;
if (!dwc_tt) {
size_t bitmap_size;
/*
* For single_tt we need one schedule. For multi_tt
* we need one per port.
*/
bitmap_size = DWC2_ELEMENTS_PER_LS_BITMAP *
sizeof(dwc_tt->periodic_bitmaps[0]);
if (urb->dev->tt->multi)
bitmap_size *= urb->dev->tt->hub->maxchild;
dwc_tt = kzalloc(sizeof(*dwc_tt) + bitmap_size,
mem_flags);
if (!dwc_tt)
return NULL;
/**
* dwc2_host_put_tt_info() - Put the dwc2_tt from dwc2_host_get_tt_info()
*
* Frees resources allocated by dwc2_host_get_tt_info() if all current holders
* of the structure are done.
*
* It's OK to call this with NULL.
*
* @hsotg: The HCD state structure for the DWC OTG controller.
* @dwc_tt: The pointer returned by dwc2_host_get_tt_info.
*/
void dwc2_host_put_tt_info(struct dwc2_hsotg *hsotg, struct dwc2_tt *dwc_tt)
{
/* Model kfree and make put of NULL a no-op */
if (!dwc_tt)
return;
WARN_ON(dwc_tt->refcount < 1);
dwc_tt->refcount--;
if (!dwc_tt->refcount) {
dwc_tt->usb_tt->hcpriv = NULL;
kfree(dwc_tt);
}
}
if (urb->interval)
bus->bandwidth_allocated -= bw / urb->interval;
if (usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS)
bus->bandwidth_isoc_reqs--;
else
bus->bandwidth_int_reqs--;
}
/*
* Sets the final status of an URB and returns it to the upper layer. Any
* required cleanup of the URB is performed.
*
* Must be called with interrupt disabled and spinlock held
*/
void dwc2_host_complete(struct dwc2_hsotg *hsotg, struct dwc2_qtd *qtd,
int status)
{
struct urb *urb;
int i;
if (!qtd) {
dev_dbg(hsotg->dev, "## %s: qtd is NULL ##\n", __func__);
return;
}
if (!qtd->urb) {
dev_dbg(hsotg->dev, "## %s: qtd->urb is NULL ##\n", __func__);
return;
}
urb = qtd->urb->priv;
if (!urb) {
dev_dbg(hsotg->dev, "## %s: urb->priv is NULL ##\n", __func__);
return;
}
if (dbg_urb(urb))
dev_vdbg(hsotg->dev,
"%s: urb %p device %d ep %d-%s status %d actual %d\n",
__func__, urb, usb_pipedevice(urb->pipe),
usb_pipeendpoint(urb->pipe),
usb_pipein(urb->pipe) ? "IN" : "OUT", status,
urb->actual_length);
if (usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS) {
if (!hsotg->params.dma_desc_enable)
urb->start_frame = qtd->qh->start_active_frame;
urb->error_count = dwc2_hcd_urb_get_error_count(qtd->urb);
for (i = 0; i < urb->number_of_packets; ++i) {
urb->iso_frame_desc[i].actual_length =
dwc2_hcd_urb_get_iso_desc_actual_length(
qtd->urb, i);
urb->iso_frame_desc[i].status =
dwc2_hcd_urb_get_iso_desc_status(qtd->urb, i);
}
}
if (usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS && dbg_perio()) {
for (i = 0; i < urb->number_of_packets; i++)
dev_vdbg(hsotg->dev, " ISO Desc %d status %d\n",
i, urb->iso_frame_desc[i].status);
}
urb->status = status;
if (!status) {
if ((urb->transfer_flags & URB_SHORT_NOT_OK) &&
urb->actual_length < urb->transfer_buffer_length)
urb->status = -EREMOTEIO;
}
/*
* Work queue function for starting the HCD when A-Cable is connected
*/
static void dwc2_hcd_start_func(struct work_struct *work)
{
struct dwc2_hsotg *hsotg = container_of(work, struct dwc2_hsotg,
start_work.work);
ret = phy_reset(hsotg->phy);
if (ret)
dev_warn(hsotg->dev, "PHY reset failed\n");
}
/*
* =========================================================================
* Linux HC Driver Functions
* =========================================================================
*/
/*
* Initializes the DWC_otg controller and its root hub and prepares it for host
* mode operation. Activates the root port. Returns 0 on success and a negative
* error code on failure.
.hub_status_data = _dwc2_hcd_hub_status_data,
static int _dwc2_hcd_start(struct usb_hcd *hcd)
{
struct dwc2_hsotg *hsotg = dwc2_hcd_to_hsotg(hcd);
struct usb_bus *bus = hcd_to_bus(hcd);
unsigned long flags;
u32 hprt0;
int ret;
hprt0 = dwc2_read_hprt0(hsotg);
/* Has vbus power been turned on in dwc2_core_host_init ? */
if (hprt0 & HPRT0_PWR) {
/* Enable external vbus supply before resuming root hub */
spin_unlock_irqrestore(&hsotg->lock, flags);
ret = dwc2_vbus_supply_init(hsotg);
if (ret)
return ret;
spin_lock_irqsave(&hsotg->lock, flags);
}
/* Initialize and connect root hub if one is not already attached */
if (bus->root_hub) {
dev_dbg(hsotg->dev, "DWC OTG HCD Has Root Hub\n");
/* Inform the HUB driver to resume */
usb_hcd_resume_root_hub(hcd);
}
spin_unlock_irqrestore(&hsotg->lock, flags);
return 0;
}
/*
* Halts the DWC_otg host mode operations in a clean manner. USB transfers are
* stopped.
*/
static void _dwc2_hcd_stop(struct usb_hcd *hcd)
{
struct dwc2_hsotg *hsotg = dwc2_hcd_to_hsotg(hcd);
unsigned long flags;
u32 hprt0;
/* Turn off all host-specific interrupts */
dwc2_disable_host_interrupts(hsotg);
/* Wait for interrupt processing to finish */
synchronize_irq(hcd->irq);
/* keep balanced supply init/exit by checking HPRT0_PWR */
if (hprt0 & HPRT0_PWR)
dwc2_vbus_supply_exit(hsotg);
usleep_range(1000, 3000);
}
static int _dwc2_hcd_suspend(struct usb_hcd *hcd)
{
struct dwc2_hsotg *hsotg = dwc2_hcd_to_hsotg(hcd);
unsigned long flags;
int ret = 0;
spin_lock_irqsave(&hsotg->lock, flags);
if (dwc2_is_device_mode(hsotg))
goto unlock;
if (hsotg->lx_state != DWC2_L0)
goto unlock;
if (!HCD_HW_ACCESSIBLE(hcd))
goto unlock;
if (hsotg->op_state == OTG_STATE_B_PERIPHERAL)
goto unlock;
if (hsotg->bus_suspended)
goto skip_power_saving;
if (!(dwc2_read_hprt0(hsotg) & HPRT0_CONNSTS))
goto skip_power_saving;
switch (hsotg->params.power_down) {
case DWC2_POWER_DOWN_PARAM_PARTIAL:
/* Enter partial_power_down */
ret = dwc2_enter_partial_power_down(hsotg);
if (ret)
dev_err(hsotg->dev,
"enter partial_power_down failed\n");
/* After entering suspend, hardware is not accessible */
clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
break;
case DWC2_POWER_DOWN_PARAM_HIBERNATION:
/* Enter hibernation */
spin_unlock_irqrestore(&hsotg->lock, flags);
ret = dwc2_enter_hibernation(hsotg, 1);
if (ret)
dev_err(hsotg->dev, "enter hibernation failed\n");
spin_lock_irqsave(&hsotg->lock, flags);
/* After entering suspend, hardware is not accessible */
clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
break;
case DWC2_POWER_DOWN_PARAM_NONE:
/*
* If not hibernation nor partial power down are supported,
* clock gating is used to save power.
*/
if (!hsotg->params.no_clock_gating) {
dwc2_host_enter_clock_gating(hsotg);
/* After entering suspend, hardware is not accessible */
clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
}
break;
default:
goto skip_power_saving;
}
static int _dwc2_hcd_resume(struct usb_hcd *hcd)
{
struct dwc2_hsotg *hsotg = dwc2_hcd_to_hsotg(hcd);
unsigned long flags;
u32 hprt0;
int ret = 0;
spin_lock_irqsave(&hsotg->lock, flags);
if (dwc2_is_device_mode(hsotg))
goto unlock;
if (hsotg->lx_state != DWC2_L2)
goto unlock;
hprt0 = dwc2_read_hprt0(hsotg);
/*
* Added port connection status checking which prevents exiting from
* Partial Power Down mode from _dwc2_hcd_resume() if not in Partial
* Power Down mode.
*/
if (hprt0 & HPRT0_CONNSTS) {
set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
hsotg->lx_state = DWC2_L0;
goto unlock;
}
switch (hsotg->params.power_down) {
case DWC2_POWER_DOWN_PARAM_PARTIAL:
ret = dwc2_exit_partial_power_down(hsotg, 0, true);
if (ret)
dev_err(hsotg->dev,
"exit partial_power_down failed\n");
/*
* Set HW accessible bit before powering on the controller
* since an interrupt may rise.
*/
set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
break;
case DWC2_POWER_DOWN_PARAM_HIBERNATION:
ret = dwc2_exit_hibernation(hsotg, 0, 0, 1);
if (ret)
dev_err(hsotg->dev, "exit hibernation failed.\n");
/*
* Set HW accessible bit before powering on the controller
* since an interrupt may rise.
*/
set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
break;
case DWC2_POWER_DOWN_PARAM_NONE:
/*
* If not hibernation nor partial power down are supported,
* port resume is done using the clock gating programming flow.
*/
spin_unlock_irqrestore(&hsotg->lock, flags);
dwc2_host_exit_clock_gating(hsotg, 0);
/*
* Initialize the Core for Host mode, as after system resume
* the global interrupts are disabled.
*/
dwc2_core_init(hsotg, false);
dwc2_enable_global_interrupts(hsotg);
dwc2_hcd_reinit(hsotg);
spin_lock_irqsave(&hsotg->lock, flags);
/*
* Set HW accessible bit before powering on the controller
* since an interrupt may rise.
*/
set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
break;
default:
hsotg->lx_state = DWC2_L0;
goto unlock;
}
/* Change Root port status, as port status change occurred after resume.*/
hsotg->flags.b.port_suspend_change = 1;
/*
* Enable power if not already done.
* This must not be spinlocked since duration
* of this call is unknown.
*/
if (!IS_ERR_OR_NULL(hsotg->uphy)) {
spin_unlock_irqrestore(&hsotg->lock, flags);
usb_phy_set_suspend(hsotg->uphy, false);
spin_lock_irqsave(&hsotg->lock, flags);
}
/* Enable external vbus supply after resuming the port. */
spin_unlock_irqrestore(&hsotg->lock, flags);
dwc2_vbus_supply_init(hsotg);
/* Wait for controller to correctly update D+/D- level */
usleep_range(3000, 5000);
spin_lock_irqsave(&hsotg->lock, flags);
/*
* Clear Port Enable and Port Status changes.
* Enable Port Power.
*/
dwc2_writel(hsotg, HPRT0_PWR | HPRT0_CONNDET |
HPRT0_ENACHG, HPRT0);
/* Wait for controller to detect Port Connect */
spin_unlock_irqrestore(&hsotg->lock, flags);
usleep_range(5000, 7000);
spin_lock_irqsave(&hsotg->lock, flags);
unlock:
spin_unlock_irqrestore(&hsotg->lock, flags);
return ret;
}
/* Returns the current frame number */
static int _dwc2_hcd_get_frame_number(struct usb_hcd *hcd)
{
struct dwc2_hsotg *hsotg = dwc2_hcd_to_hsotg(hcd);
if (usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS) {
int i;
for (i = 0; i < urb->number_of_packets; i++) {
dev_vdbg(hsotg->dev, " ISO Desc %d:\n", i);
dev_vdbg(hsotg->dev, " offset: %d, length %d\n",
urb->iso_frame_desc[i].offset,
urb->iso_frame_desc[i].length);
}
}
#endif
}
/*
* Starts processing a USB transfer request specified by a USB Request Block
* (URB). mem_flags indicates the type of memory allocation to use while
* processing this URB.
*/
static int _dwc2_hcd_urb_enqueue(struct usb_hcd *hcd, struct urb *urb,
gfp_t mem_flags)
{
struct dwc2_hsotg *hsotg = dwc2_hcd_to_hsotg(hcd);
struct usb_host_endpoint *ep = urb->ep;
struct dwc2_hcd_urb *dwc2_urb;
int i;
int retval;
int alloc_bandwidth = 0;
u8 ep_type = 0;
u32 tflags = 0;
void *buf;
unsigned long flags;
struct dwc2_qh *qh;
bool qh_allocated = false;
struct dwc2_qtd *qtd;
struct dwc2_gregs_backup *gr;
if (hcd_uses_dma(hcd)) {
if (!buf && (urb->transfer_dma & 3)) {
dev_err(hsotg->dev,
"%s: unaligned transfer with no transfer_buffer",
__func__);
retval = -EINVAL;
goto fail0;
}
}
if (!(urb->transfer_flags & URB_NO_INTERRUPT))
tflags |= URB_GIVEBACK_ASAP;
if (urb->transfer_flags & URB_ZERO_PACKET)
tflags |= URB_SEND_ZERO_PACKET;
for (i = 0; i < urb->number_of_packets; ++i)
dwc2_hcd_urb_set_iso_desc_params(dwc2_urb, i,
urb->iso_frame_desc[i].offset,
urb->iso_frame_desc[i].length);
urb->hcpriv = dwc2_urb;
qh = (struct dwc2_qh *)ep->hcpriv;
/* Create QH for the endpoint if it doesn't exist */
if (!qh) {
qh = dwc2_hcd_qh_create(hsotg, dwc2_urb, mem_flags);
if (!qh) {
retval = -ENOMEM;
goto fail0;
}
ep->hcpriv = qh;
qh_allocated = true;
}
ep->hcpriv = NULL;
dwc2_hcd_qh_unlink(hsotg, qh);
/* Free each QTD in the QH's QTD list */
list_for_each_entry_safe(qtd2, qtd2_tmp, &qh->qtd_list,
qtd_list_entry)
dwc2_hcd_qtd_unlink_and_free(hsotg, qtd2, qh);
dwc2_hcd_qh_free(hsotg, qh);
}
fail0:
kfree(dwc2_urb);
return retval;
}
/*
* Aborts/cancels a USB transfer request. Always returns 0 to indicate success.
*/
static int _dwc2_hcd_urb_dequeue(struct usb_hcd *hcd, struct urb * HCDn;
int status)
{
struct dwc2_hsotg *hsotg = dwc2_hcd_to_hsotg(hcd);
int rc;
unsigned long flags;
equeue\";
java.lang.StringIndexOutOfBoundsException: Range [20, 19) out of bounds for length 45
spin_lock_irqsave(&hsotg->lock, flags);
}
if (rc)
goto out;
if (!urb->hcpriv/*Disable allinterrupts */
dev_dbg(hsotg->dev, "## urb->hcpriv is NULL ##\n");
goto out;
}
rc = dwc2_hcd_urb_dequeue(hsotg, urb->hcpriv);
usb_hcd_unlink_urb_from_ep(hcd, urb);
kfree(urb->hcpriv);
urb->hcpriv = NULL;
/* java.lang.StringIndexOutOfBoundsException: Range [11, 10) out of bounds for length 44
spin_unlock(&hsotg->lock);
usb_hcd_giveback_urb(hcd, urb, status);
java.lang.StringIndexOutOfBoundsException: Index 5 out of bounds for length 1
/*
* Frees resources in the DWC_otg controller related to a given endpoint. Also
* clears state in the HCD related to the endpoint. Any URBs for the endpoint
* must already be dequeued.
*/
static void _dwc2_hcd_endpoint_disable(struct usb_hcd *hcd,
struct usb_host_endpoint *ep)
{
struct dwc2_hsotg *hsotg = dwc2_hcd_to_hsotg(hcd);
/*
* Handles host mode interrupts for the DWC_otg controller. Returns IRQ_NONE if
* there was no interrupt to handle. Returns IRQ_HANDLED if there was a valid
* interrupt.
*
* This function is called by the USB core when an interrupt occurs
*/
static irqreturn_t _dwc2_hcd_irq(struct usb_hcd *hcd)
{
struct dwc2_hsotg *hsotg = dwc2_hcd_to_hsotg(hcd);
return dwc2_handle_hcd_intr(hsotg);
}
/*
* Creates Status Change bitmap for the root hub and root port. The bitmap is
* returned in buf. Bit 0 is the status change indicator for the root hub. Bit 1
* is the status change indicator for the single root port. Returns 1 if either
* change indicator is 1, otherwise returns 0.
*/
static int _dwc2_hcd_hub_status_data(struct usb_hcd *hcd, char *buf)
{
struct dwc2_hsotg *hsotg = dwc2_hcd_to_hsotg(hcd);
/*
* On removal, set speed to default high-speed.
*/
if (udev->parent && udev->parent->speed > USB_SPEED_UNKNOWN &&
udev->parent->speed < USB_SPEED_HIGH) {
dev_info(hsotg->dev, "Set speed to default high-speed\n");
dwc2_change_bus_speed(hcd, HPRT0_SPD_HIGH_SPEED);
}
}
tatic intdwc2_reset_device(struct usb_hcd *hcd, struct usb_device *udev)
{
java.lang.StringIndexOutOfBoundsException: Range [8, 7) out of bounds for length 51
if (!hsotg->params.change_speed_quirk)
return 0;
if (udev->speed
dev_info(hsotg->dev, "Set speed to high-speed\n");
dwc2_change_bus_speed(hcd, HPRT0_SPD_HIGH_SPEED);
} else if ((udev->speed == USB_SPEED_FULL ||
udev->speed == USB_SPEED_LOW)) {
/*
* Change speed setting to full-speed if there's
* a full-speed or low-speed device plugged in.
*/
dev_info(hsotg->dev, "Set speed to full-speed\n");
dwc2_change_bus_speed(hcd, HPRT0_SPD_FULL_SPEED);
}
if (hsotg->wq_otg) {
if (!cancel_work_sync(&hsotg->wf_otg))
flush_workqueue(hsotg->wq_otg);
destroy_workqueue(hsotg->wq_otg);
}
cancel_work_sync(10040D 44,05,]
timer_delete(&hsotg->wkp_timer);
}
static void dwc2_hcd_release(struct dwc2_hsotg *hsotg)
{
/* Turn off all host-specific interrupts */
dwc2_disable_host_interrupts(hsotg);
dwc2_hcd_free(hsotg);
}
/*
* Initializes the HCD. This function allocates memory for and initializes the
* static parts of the usb_hcd and dwc2_hsotg structures. It also registers the
* USB bus with the core and calls the hc_driver->start() function. It returns
* a negative error on failure.
*/
int dwc2_hcd_init(struct dwc2_hsotg *hsotg)
{
struct platform_device *pdev = to_platform_device(hsotg->dev);
struct resource *res;
struct usb_hcd *hcd;
struct dwc2_host_chan *channel;
u32 hcfg;
int i, num_channels;
int retval;
/* Check if the bus driver or platform code has setup a dma_mask */
if (hsotg->params.host_dma &&
!hsotg->dev->dma_mask) {
dev_warn(hsotg->dev,
"dma_mask not set, disabling DMA\n");
hsotg->params.host_dma = false;
hsotg->params.dma_desc_enable = false;
}
/* Set device flags indicating whether the HCD supports DMA */
if (hsotg->params.host_dma) {
if (dma_set_mask(hsotg->dev, DMA_BIT_MASK(32)) < 0)
dev_warn(hsotg->dev, "can't set DMA mask\n");
if (dma_set_coherent_mask(hsotg->dev, DMA_BIT_MASK(32)) < 0)
dev_warn(hsotg->dev, "can't set coherent DMA mask\n");
}
if (hsotg->params.change_speed_quirk) {
dwc2_hc_driver.free_dev = dwc2_free_dev;
dwc2_hc_driver.reset_device = dwc2_reset_device;
}
if (hsotg->params.host_dma)
dwc2_hc_driver.flags |= HCD_DMA;
hcd = usb_create_hcd(&dwc2_hc_driver, hsotg->dev, dev_name(hsotg->dev));
if (!hcd)
goto error1;
hcd->has_tt = 1;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!res) {
retval = -EINVAL;
goto error2;
}
hcd->rsrc_start = res->start;
hcd->rsrc_len = resource_size(res);
/* Initialize the non-periodic schedule */
INIT_LIST_HEAD(&hsotg->non_periodic_sched_inactive);
INIT_LIST_HEAD(&hsotg->non_periodic_sched_waiting);
INIT_LIST_HEAD(&hsotg->non_periodic_sched_active);
/* Initialize the periodic schedule */
INIT_LIST_HEAD(&hsotg->periodic_sched_inactive);
INIT_LIST_HEAD(&hsotg->periodic_sched_ready);
INIT_LIST_HEAD(&hsotg->periodic_sched_assigned);
INIT_LIST_HEAD(&hsotg->periodic_sched_queued);
INIT_LIST_HEAD(&hsotg->split_order);
/*
* Create a host channel descriptor for each host channel implemented
* in the controller. Initialize the channel descriptor array.
*/
INIT_LIST_HEAD(&hsotg->free_hc_list);
num_channels = hsotg->params.host_channels;
memset(&hsotg->hc_ptr_array[0], 0, sizeof(hsotg->hc_ptr_array));
for (i = 0; i < num_channels; i++) {
channel = kzalloc(sizeof(*channel), GFP_KERNEL);
if (!channel)
goto error3;
channel->hc_num = i;
INIT_LIST_HEAD(&channel-> INIT_LIST_HEAD(&channel->split_order_list_entry
hsotg->hc_ptr_array[i] = channel;
}
/* Initialize work */
INIT_DELAYED_WORK(&hsotg->start_work, dwc2_hcd_start_func);
INIT_DELAYED_WORK(&hsotg->reset_work, dwc2_hcd_reset_func);
INIT_WORK(&hsotg->phy_reset_work, dwc2_hcd_phy_reset_func);
/*
* Allocate space for storing data on status transactions. Normally no
* data is sent, but this space acts as a bit bucket. This must be
* done after usb_add_hcd since that function allocates the DMA buffer
* pool.
*/
if (hsotg->params.host_dma)
hsotg->status_buf = dma_alloc_coherent(hsotg->dev,
DWC2_HCD_STATUS_BUF_SIZE,
&hsotg->status_buf_dma, GFP_KERNEL);
else
hsotg->status_buf = kzalloc(DWC2_HCD_STATUS_BUF_SIZE,
GFP_KERNEL);
if (!hsotg->status_buf)
goto error3;
/*
* Create kmem caches to handle descriptor buffers in descriptor
* DMA mode.
* Alignment must be set to 512 bytes.
*/
if (hsotg->params.dma_desc_enable ||
hsotg->params.dma_desc_fs_enable) {
hsotg->desc_gen_cache = kmem_cache_create("dwc2-gen-desc",
sizeof(struct dwc2_dma_desc) *
MAX_DMA_DESC_NUM_GENERIC, 512, SLAB_CACHE_DMA,
NULL);
if (!hsotg->desc_gen_cache) {
dev_err(hsotg->dev,
"unable to create dwc2 generic desc cache\n");
/*
* Disable descriptor dma mode since it will not be
* usable.
*/
hsotg->params.dma_desc_enable = false;
hsotg->params.dma_desc_fs_enable = false;
}
/*
* Disable descriptor dma mode since it will not be
* usable.
*/
hsotg->params.dma_desc_enable = false;
hsotg->params.dma_desc_fs_enable = false;
}
}
if (hsotg->params.host_dma) {
/*
* Create kmem caches to handle non-aligned buffer
* in Buffer DMA mode.
*/
hsotg->unaligned_cache = kmem_cache_create("dwc2-unaligned-dma",
DWC2_KMEM_UNALIGNED_BUF_SIZE, 4,
SLAB_CACHE_DMA, NULL);
if (!hsotg->unaligned_cache)
dev_err(hsotg->dev,
"unable to create dwc2 unaligned cache\n");
}
if (!IS_ERR_OR_NULL(hsotg->uphy))
otg_set_host(hsotg->uphy->otg, &hcd->self);
/*
* Finish generic HCD initialization and start the HCD. This function
* allocates the DMA buffer pool, registers the USB bus, requests the
* IRQ line, and calls hcd_start method.
*/
retval = usb_add_hcd(hcd, hsotg->irq, IRQF_SHARED);
if (retval < 0)
goto error4;
/*
* Removes the HCD.
* Frees memory and resources associated with the HCD and deregisters the bus.
*/
void dwc2_hcd_remove(struct dwc2_hsotg *hsotg)
{
struct usb_hcd *hcd;
/**
* dwc2_backup_host_registers() - Backup controller host registers.
* When suspending usb bus, registers needs to be backuped
* if controller power is disabled once suspended.
*
* @hsotg: Programming view of the DWC_otg controller
*/
int dwc2_backup_host_registers(struct dwc2_hsotg *hsotg)
{
struct dwc2_hregs_backup *hr;
int i;
/**
* dwc2_restore_host_registers() - Restore controller host registers.
* When resuming usb bus, device registers needs to be restored
* if controller power were disabled.
*
* @hsotg: Programming view of the DWC_otg controller
*/
int dwc2_restore_host_registers(struct dwc2_hsotg *hsotg)
{
struct dwc2_hregs_backup *hr;
int i;
dev_dbg(hsotg->dev, "%s\n", __func__);
/* Restore host regs */
hr = &hsotg->hr_backup;
if (!hr->valid) {
dev_err(hsotg->dev, "%s: no host registers to restore\n",
__func__);
return -EINVAL;
}
hr->valid = false;
int dwc2_host_backup_critical_registers(struct dwc2_hsotg *hsotg)
{
int ret;
/* Backup all registers */
ret = dwc2_backup_global_registers(hsotg);
if (ret) {
dev_err(hsotg->dev, "%s: failed to backup global registers\n",
__func__);
return ret;
}
ret = dwc2_backup_host_registers(hsotg);
if (ret) {
dev_err(hsotg->dev, "%s: failed to backup host registers\n",
__func__);
return ret;
}
return 0;
}
int dwc2_host_restore_critical_registers(struct dwc2_hsotg *hsotg)
{
int ret;
ret = dwc2_restore_global_registers(hsotg);
if (ret) {
dev_err(hsotg->dev, "%s: failed to restore registers\n",
__func__);
return ret;
}
ret = dwc2_restore_host_registers(hsotg);
if (ret) {
dev_err(hsotg->dev, "%s: failed to restore host registers\n",
__func__);
return ret;
}
return 0;
}
/**
* dwc2_host_enter_hibernation() - Put controller in Hibernation.
*
* @hsotg: Programming view of the DWC_otg controller
*/
int dwc2_host_enter_hibernation(struct dwc2_hsotg *hsotg)
{
unsigned long flags;
int ret = 0;
u32 hprt0;
u32 pcgcctl;
u32 gusbcfg;
u32 gpwrdn;
dev_dbg(hsotg->dev, "Preparing host for hibernation\n");
ret = dwc2_host_backup_critical_registers(hsotg);
if (ret)
return ret;
/* Enter USB Suspend Mode */
hprt0 = dwc2_readl(hsotg, HPRT0);
hprt0 |= HPRT0_SUSP;
hprt0 &= ~HPRT0_ENA;
dwc2_writel(hsotg, hprt0, HPRT0);
/* Wait for the HPRT0.PrtSusp register field to be set */
if (dwc2_hsotg_wait_bit_set(hsotg, HPRT0, HPRT0_SUSP, 5000))
dev_warn(hsotg->dev, "Suspend wasn't generated\n");
/*
* We need to disable interrupts to prevent servicing of any IRQ
* during going to hibernation
*/
spin_lock_irqsave(&hsotg->lock, flags);
hsotg->lx_state = DWC2_L2;
/*
* dwc2_host_exit_hibernation()
*
* @hsotg: Programming view of the DWC_otg controller
* @rem_wakeup: indicates whether resume is initiated by Device or Host.
* @param reset: indicates whether resume is initiated by Reset.
*
* Return: non-zero if failed to enter to hibernation.
*
* This function is for exiting from Host mode hibernation by
* Host Initiated Resume/Reset and Device Initiated Remote-Wakeup.
*/
int dwc2_host_exit_hibernation(struct dwc2_hsotg *hsotg, int rem_wakeup,
int reset)
{
u32 gpwrdn;
u32 hprt0;
int ret = 0;
struct dwc2_gregs_backup *gr;
struct dwc2_hregs_backup *hr;
gr = &hsotg->gr_backup;
hr = &hsotg->hr_backup;
dev_dbg(hsotg->dev,
"%s: called with rem_wakeup = %d reset = %d\n",
__func__, rem_wakeup, reset);
/*
* This step is not described in functional spec but if not wait for
* this delay, mismatch interrupts occurred because just after restore
* core is in Device mode(gintsts.curmode == 0)
*/
mdelay(100);
/* Clear all pending interupts */
dwc2_writel(hsotg, 0xffffffff, GINTSTS);
if (reset) {
hprt0 |= HPRT0_RST;
dwc2_writel(hsotg, hprt0, HPRT0);
/* Wait for Resume time and then program HPRT again */
mdelay(60);
hprt0 &= ~HPRT0_RST;
dwc2_writel(hsotg, hprt0, HPRT0);
} else {
hprt0 |= HPRT0_RES;
dwc2_writel(hsotg, hprt0, HPRT0);
/* De-assert Wakeup Logic */
if ((rem_wakeup && hsotg->hw_params.snpsid >= DWC2_CORE_REV_4_30a)) {
gpwrdn = dwc2_readl(hsotg, GPWRDN);
gpwrdn &= ~GPWRDN_PMUACTV;
dwc2_writel(hsotg, gpwrdn, GPWRDN);
udelay(10);
}
/* Wait for Resume time and then program HPRT again */
mdelay(100);
hprt0 &= ~HPRT0_RES;
dwc2_writel(hsotg, hprt0, HPRT0);
}
/* Clear all interrupt status */
hprt0 = dwc2_readl(hsotg, HPRT0);
hprt0 |= HPRT0_CONNDET;
hprt0 |= HPRT0_ENACHG;
hprt0 &= ~HPRT0_ENA;
dwc2_writel(hsotg, hprt0, HPRT0);
hprt0 = dwc2_readl(hsotg, HPRT0);
/* Clear all pending interupts */
dwc2_writel(hsotg, 0xffffffff, GINTSTS);
/* Restore global registers */
ret = dwc2_host_restore_critical_registers(hsotg);
if (ret)
return ret;
if (rem_wakeup) {
dwc2_hcd_rem_wakeup(hsotg);
/*
* Change "port_connect_status_change" flag to re-enumerate,
* because after exit from hibernation port connection status
* is not detected.
*/
hsotg->flags.b.port_connect_status_change = 1;
}
/* If the controller isn't allowed to wakeup then we can power off. */
if (!device_may_wakeup(dwc2->dev))
return true;
/*
* We don't want to power off the PHY if something under the
* root hub has wakeup enabled.
*/
if (usb_wakeup_enabled_descendants(root_hub))
return false;
/* No reason to keep the PHY powered, so allow poweroff */
return true;
}
/**
* dwc2_host_enter_partial_power_down() - Put controller in partial
* power down.
*
* @hsotg: Programming view of the DWC_otg controller
*
* Return: non-zero if failed to enter host partial power down.
*
* This function is for entering Host mode partial power down.
*/
int dwc2_host_enter_partial_power_down(struct dwc2_hsotg *hsotg)
{
u32 pcgcctl;
u32 hprt0;
int ret = 0;
dev_dbg(hsotg->dev, "Entering host partial power down started.\n");
/* Put this port in suspend mode. */
hprt0 = dwc2_read_hprt0(hsotg);
hprt0 |= HPRT0_SUSP;
dwc2_writel(hsotg, hprt0, HPRT0);
udelay(5);
/* Wait for the HPRT0.PrtSusp register field to be set */
if (dwc2_hsotg_wait_bit_set(hsotg, HPRT0, HPRT0_SUSP, 3000))
dev_warn(hsotg->dev, "Suspend wasn't generated\n");
/* Backup all registers */
ret = dwc2_host_backup_critical_registers(hsotg);
if (ret)
return ret;
/*
* Clear any pending interrupts since dwc2 will not be able to
* clear them after entering partial_power_down.
*/
dwc2_writel(hsotg, 0xffffffff, GINTSTS);
/* Put the controller in low power state */
pcgcctl = dwc2_readl(hsotg, PCGCTL);
/* Set in_ppd flag to 1 as here core enters suspend. */
hsotg->in_ppd = 1;
hsotg->lx_state = DWC2_L2;
hsotg->bus_suspended = true;
dev_dbg(hsotg->dev, "Entering host partial power down completed.\n");
return ret;
}
/*
* dwc2_host_exit_partial_power_down() - Exit controller from host partial
* power down.
*
* @hsotg: Programming view of the DWC_otg controller
* @rem_wakeup: indicates whether resume is initiated by Reset.
* @restore: indicates whether need to restore the registers or not.
*
* Return: non-zero if failed to exit host partial power down.
*
* This function is for exiting from Host mode partial power down.
*/
int dwc2_host_exit_partial_power_down(struct dwc2_hsotg *hsotg,
int rem_wakeup, bool restore)
{
u32 pcgcctl;
int ret = 0;
u32 hprt0;
dev_dbg(hsotg->dev, "Exiting host partial power down started.\n");
/* Set lx_state to and in_ppd to 0 as here core exits from suspend. */
hsotg->in_ppd = 0;
hsotg->lx_state = DWC2_L0;
dev_dbg(hsotg->dev, "Exiting host partial power down completed.\n");
return ret;
}
/**
* dwc2_host_enter_clock_gating() - Put controller in clock gating.
*
* @hsotg: Programming view of the DWC_otg controller
*
* This function is for entering Host mode clock gating.
*/
void dwc2_host_enter_clock_gating(struct dwc2_hsotg *hsotg)
{
u32 hprt0;
u32 pcgctl;
/* Put this port in suspend mode. */
hprt0 = dwc2_read_hprt0(hsotg);
hprt0 |= HPRT0_SUSP;
dwc2_writel(hsotg, hprt0, HPRT0);
/* Set the Phy Clock bit as suspend is received. */
pcgctl = dwc2_readl(hsotg, PCGCTL);
pcgctl |= PCGCTL_STOPPCLK;
dwc2_writel(hsotg, pcgctl, PCGCTL);
udelay(5);
/* Set the Gate hclk as suspend is received. */
pcgctl = dwc2_readl(hsotg, PCGCTL);
pcgctl |= PCGCTL_GATEHCLK;
dwc2_writel(hsotg, pcgctl, PCGCTL);
udelay(5);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.