Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b2a068d0 authored by Martin Fuzzey's avatar Martin Fuzzey Committed by Greg Kroah-Hartman
Browse files

USB: imx21-hcd: refactor hardware data memory management



We already have fields describing the hardware data memory
(dmem_size and dmem_offset) in the HCD private data,
use them rather than the rather obscure read from the
hardware descriptor.

Signed-off-by: default avatarMartin Fuzzey <mfuzzey@gmail.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent e6da55cb
Loading
Loading
Loading
Loading
+16 −14
Original line number Original line Diff line number Diff line
@@ -323,16 +323,23 @@ static void activate_queued_etd(struct imx21 *imx21,
	etd_writel(imx21, etd_num, 1,
	etd_writel(imx21, etd_num, 1,
	    ((dmem_offset + maxpacket) << DW1_YBUFSRTAD) | dmem_offset);
	    ((dmem_offset + maxpacket) << DW1_YBUFSRTAD) | dmem_offset);


	etd->dmem_offset = dmem_offset;
	urb_priv->active = 1;
	urb_priv->active = 1;
	activate_etd(imx21, etd_num, etd->dma_handle, dir);
	activate_etd(imx21, etd_num, etd->dma_handle, dir);
}
}


static void free_dmem(struct imx21 *imx21, int offset)
static void free_dmem(struct imx21 *imx21, struct etd_priv *etd)
{
{
	struct imx21_dmem_area *area;
	struct imx21_dmem_area *area;
	struct etd_priv *etd, *tmp;
	struct etd_priv *tmp;
	int found = 0;
	int found = 0;
	int offset;


	if (!etd->dmem_size)
		return;
	etd->dmem_size = 0;

	offset = etd->dmem_offset;
	list_for_each_entry(area, &imx21->dmem_list, list) {
	list_for_each_entry(area, &imx21->dmem_list, list) {
		if (area->offset == offset) {
		if (area->offset == offset) {
			debug_dmem_freed(imx21, area->size);
			debug_dmem_freed(imx21, area->size);
@@ -734,9 +741,7 @@ static void dequeue_isoc_urb(struct imx21 *imx21,
				struct etd_priv *etd = imx21->etd + etd_num;
				struct etd_priv *etd = imx21->etd + etd_num;


				reset_etd(imx21, etd_num);
				reset_etd(imx21, etd_num);
				if (etd->dmem_size)
				free_dmem(imx21, etd);
					free_dmem(imx21, etd->dmem_offset);
				etd->dmem_size = 0;
			}
			}
		}
		}
	}
	}
@@ -761,7 +766,6 @@ static void schedule_nonisoc_etd(struct imx21 *imx21, struct urb *urb)
	int state = urb_priv->state;
	int state = urb_priv->state;
	int etd_num = ep_priv->etd[0];
	int etd_num = ep_priv->etd[0];
	struct etd_priv *etd;
	struct etd_priv *etd;
	int dmem_offset;
	u32 count;
	u32 count;
	u16 etd_buf_size;
	u16 etd_buf_size;
	u16 maxpacket;
	u16 maxpacket;
@@ -855,8 +859,8 @@ static void schedule_nonisoc_etd(struct imx21 *imx21, struct urb *urb)


	/* allocate x and y buffer space at once */
	/* allocate x and y buffer space at once */
	etd->dmem_size = (count > maxpacket) ? maxpacket * 2 : maxpacket;
	etd->dmem_size = (count > maxpacket) ? maxpacket * 2 : maxpacket;
	dmem_offset = alloc_dmem(imx21, etd->dmem_size, urb_priv->ep);
	etd->dmem_offset = alloc_dmem(imx21, etd->dmem_size, urb_priv->ep);
	if (dmem_offset < 0) {
	if (etd->dmem_offset < 0) {
		/* Setup everything we can in HW and update when we get DMEM */
		/* Setup everything we can in HW and update when we get DMEM */
		etd_writel(imx21, etd_num, 1, (u32)maxpacket << 16);
		etd_writel(imx21, etd_num, 1, (u32)maxpacket << 16);


@@ -867,8 +871,8 @@ static void schedule_nonisoc_etd(struct imx21 *imx21, struct urb *urb)
	}
	}


	etd_writel(imx21, etd_num, 1,
	etd_writel(imx21, etd_num, 1,
		(((u32) dmem_offset + (u32) maxpacket) << DW1_YBUFSRTAD) |
		(((u32) etd->dmem_offset + (u32) maxpacket) << DW1_YBUFSRTAD) |
		(u32) dmem_offset);
		(u32) etd->dmem_offset);


	urb_priv->active = 1;
	urb_priv->active = 1;


@@ -886,7 +890,6 @@ static void nonisoc_etd_done(struct usb_hcd *hcd, struct urb *urb, int etd_num)
	u32 etd_mask = 1 << etd_num;
	u32 etd_mask = 1 << etd_num;
	struct urb_priv *urb_priv = urb->hcpriv;
	struct urb_priv *urb_priv = urb->hcpriv;
	int dir;
	int dir;
	u16 xbufaddr;
	int cc;
	int cc;
	u32 bytes_xfrd;
	u32 bytes_xfrd;
	int etd_done;
	int etd_done;
@@ -894,7 +897,6 @@ static void nonisoc_etd_done(struct usb_hcd *hcd, struct urb *urb, int etd_num)
	disactivate_etd(imx21, etd_num);
	disactivate_etd(imx21, etd_num);


	dir = (etd_readl(imx21, etd_num, 0) >> DW0_DIRECT) & 0x3;
	dir = (etd_readl(imx21, etd_num, 0) >> DW0_DIRECT) & 0x3;
	xbufaddr = etd_readl(imx21, etd_num, 1) & 0xffff;
	cc = (etd_readl(imx21, etd_num, 2) >> DW2_COMPCODE) & 0xf;
	cc = (etd_readl(imx21, etd_num, 2) >> DW2_COMPCODE) & 0xf;
	bytes_xfrd = etd->len - (etd_readl(imx21, etd_num, 3) & 0x1fffff);
	bytes_xfrd = etd->len - (etd_readl(imx21, etd_num, 3) & 0x1fffff);


@@ -907,7 +909,7 @@ static void nonisoc_etd_done(struct usb_hcd *hcd, struct urb *urb, int etd_num)
		clear_toggle_bit(imx21, USBH_XFILLSTAT, etd_mask);
		clear_toggle_bit(imx21, USBH_XFILLSTAT, etd_mask);
		clear_toggle_bit(imx21, USBH_YFILLSTAT, etd_mask);
		clear_toggle_bit(imx21, USBH_YFILLSTAT, etd_mask);
	}
	}
	free_dmem(imx21, xbufaddr);
	free_dmem(imx21, etd);


	urb->error_count = 0;
	urb->error_count = 0;
	if (!(urb->transfer_flags & URB_SHORT_NOT_OK)
	if (!(urb->transfer_flags & URB_SHORT_NOT_OK)
@@ -1123,7 +1125,7 @@ static int imx21_hc_urb_dequeue(struct usb_hcd *hcd, struct urb *urb,
		int etd_num = ep_priv->etd[0];
		int etd_num = ep_priv->etd[0];
		if (etd_num != -1) {
		if (etd_num != -1) {
			disactivate_etd(imx21, etd_num);
			disactivate_etd(imx21, etd_num);
			free_dmem(imx21, etd_readl(imx21, etd_num, 1) & 0xffff);
			free_dmem(imx21, &imx21->etd[etd_num]);
			imx21->etd[etd_num].urb = NULL;
			imx21->etd[etd_num].urb = NULL;
		}
		}
	}
	}