[PATCH v15 08/10] USB ppc4xx: Add Synopsys DWC OTG PCD interrupt function
Pratyush Anand
pratyush.anand at gmail.com
Thu Oct 20 21:12:46 EST 2011
On Sat, Oct 15, 2011 at 3:39 AM, <tmarri at apm.com> wrote:
> From: Tirumala Marri <tmarri at apm.com>
>
[...]
> +static int write_empty_tx_fifo(struct dwc_pcd *pcd, u32 epnum)
> +{
> + struct core_if *core_if = GET_CORE_IF(pcd);
> + ulong regs;
> + u32 txstatus = 0;
> + struct pcd_ep *ep;
> + u32 len;
> + int dwords;
> + u32 diepint = 0;
> +
> + ep = get_in_ep(pcd, epnum);
> + regs = core_if->dev_if->in_ep_regs[epnum];
> + txstatus = dwc_reg_read(regs, DWC_DTXFSTS);
> +
> + /*
> + * While there is space in the queue, space in the FIFO and data to
> + * tranfer, write packets to the Tx FIFO
> + */
> + len = ep->dwc_ep.xfer_len - ep->dwc_ep.xfer_count;
> + dwords = count_dwords(ep, len);
> + while (DWC_DTXFSTS_TXFSSPC_AVAI_RD(txstatus) > dwords
If you use a >= here, it will be more efficient.
Other wise even if you have 512 bytes spece remaining in TXFIFO, you will not be
able to send a 512 byte packet.
> + && ep->dwc_ep.xfer_count < ep->dwc_ep.xfer_len
> + && ep->dwc_ep.xfer_len != 0) {
> + dwc_otg_ep_write_packet(core_if, &ep->dwc_ep, 0);
> + len = ep->dwc_ep.xfer_len - ep->dwc_ep.xfer_count;
> + dwords = count_dwords(ep, len);
> + txstatus = dwc_reg_read(regs, DWC_DTXFSTS);
> + }
> + /* Clear emptyintr */
> + diepint = DWC_DIEPINT_TXFIFO_EMPTY_RW(diepint, 1);
> + dwc_reg_write(in_ep_int_reg(pcd, epnum), 0, diepint);
> + return 1;
> +}
[...]
> +/**
> + * Clear the EP halt (STALL) and if pending requests start the
> + * transfer.
> + */
> +static void pcd_clear_halt(struct dwc_pcd *pcd, struct pcd_ep *ep)
> +{
> + struct core_if *core_if = GET_CORE_IF(pcd);
> +
> + if (!ep->dwc_ep.stall_clear_flag)
> + dwc_otg_ep_clear_stall(core_if, &ep->dwc_ep);
> +
> + /* Reactive the EP */
> + dwc_otg_ep_activate(core_if, &ep->dwc_ep);
> +
> + if (ep->stopped) {
> + ep->stopped = 0;
> + /* If there is a request in the EP queue start it */
> +
> + /*
> + * dwc_start_next_request(), outside of interpt contxt at some
> + * time after the current time, after a clear-halt setup packet.
> + * Still need to implement ep mismatch in the future if a gadget
> + * ever uses more than one endpoint at once
> + */
> + if (core_if->dma_enable) {
> + ep->queue_sof = 1;
> + tasklet_schedule(pcd->start_xfer_tasklet);
> + } else {
> + /*
> + * Added-sr: 2007-07-26
> + *
> + * To re-enable this endpoint it's important to
> + * set this next_ep number. Otherwise the endpoint
> + * will not get active again after stalling.
> + */
> + if (dwc_has_feature(core_if, DWC_LIMITED_XFER))
> + dwc_start_next_request(ep);
Should next request be not started for all the cases?
> + }
> + }
> +
> + /* Start Control Status Phase */
> + do_setup_in_status_phase(pcd);
> +}
> +
Regards
Pratyush
More information about the Linuxppc-dev
mailing list