diff options
author | Martin Fuzzey <mfuzzey@gmail.com> | 2010-09-30 18:21:43 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2010-10-22 13:22:02 -0400 |
commit | b2a068d058e71519e14d2c03e92459c4c1d63c8b (patch) | |
tree | 772d86ac294690f0a360382e7ae8b1a3dc15ba8c /drivers/usb/host/imx21-hcd.c | |
parent | e6da55cb0aa36f30168da8c20ceccdc538b054be (diff) |
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: Martin Fuzzey <mfuzzey@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb/host/imx21-hcd.c')
-rw-r--r-- | drivers/usb/host/imx21-hcd.c | 30 |
1 files changed, 16 insertions, 14 deletions
diff --git a/drivers/usb/host/imx21-hcd.c b/drivers/usb/host/imx21-hcd.c index 6c0848b66e25..1be144167da4 100644 --- a/drivers/usb/host/imx21-hcd.c +++ b/drivers/usb/host/imx21-hcd.c | |||
@@ -323,16 +323,23 @@ static void activate_queued_etd(struct imx21 *imx21, | |||
323 | etd_writel(imx21, etd_num, 1, | 323 | etd_writel(imx21, etd_num, 1, |
324 | ((dmem_offset + maxpacket) << DW1_YBUFSRTAD) | dmem_offset); | 324 | ((dmem_offset + maxpacket) << DW1_YBUFSRTAD) | dmem_offset); |
325 | 325 | ||
326 | etd->dmem_offset = dmem_offset; | ||
326 | urb_priv->active = 1; | 327 | urb_priv->active = 1; |
327 | activate_etd(imx21, etd_num, etd->dma_handle, dir); | 328 | activate_etd(imx21, etd_num, etd->dma_handle, dir); |
328 | } | 329 | } |
329 | 330 | ||
330 | static void free_dmem(struct imx21 *imx21, int offset) | 331 | static void free_dmem(struct imx21 *imx21, struct etd_priv *etd) |
331 | { | 332 | { |
332 | struct imx21_dmem_area *area; | 333 | struct imx21_dmem_area *area; |
333 | struct etd_priv *etd, *tmp; | 334 | struct etd_priv *tmp; |
334 | int found = 0; | 335 | int found = 0; |
336 | int offset; | ||
335 | 337 | ||
338 | if (!etd->dmem_size) | ||
339 | return; | ||
340 | etd->dmem_size = 0; | ||
341 | |||
342 | offset = etd->dmem_offset; | ||
336 | list_for_each_entry(area, &imx21->dmem_list, list) { | 343 | list_for_each_entry(area, &imx21->dmem_list, list) { |
337 | if (area->offset == offset) { | 344 | if (area->offset == offset) { |
338 | debug_dmem_freed(imx21, area->size); | 345 | debug_dmem_freed(imx21, area->size); |
@@ -734,9 +741,7 @@ static void dequeue_isoc_urb(struct imx21 *imx21, | |||
734 | struct etd_priv *etd = imx21->etd + etd_num; | 741 | struct etd_priv *etd = imx21->etd + etd_num; |
735 | 742 | ||
736 | reset_etd(imx21, etd_num); | 743 | reset_etd(imx21, etd_num); |
737 | if (etd->dmem_size) | 744 | free_dmem(imx21, etd); |
738 | free_dmem(imx21, etd->dmem_offset); | ||
739 | etd->dmem_size = 0; | ||
740 | } | 745 | } |
741 | } | 746 | } |
742 | } | 747 | } |
@@ -761,7 +766,6 @@ static void schedule_nonisoc_etd(struct imx21 *imx21, struct urb *urb) | |||
761 | int state = urb_priv->state; | 766 | int state = urb_priv->state; |
762 | int etd_num = ep_priv->etd[0]; | 767 | int etd_num = ep_priv->etd[0]; |
763 | struct etd_priv *etd; | 768 | struct etd_priv *etd; |
764 | int dmem_offset; | ||
765 | u32 count; | 769 | u32 count; |
766 | u16 etd_buf_size; | 770 | u16 etd_buf_size; |
767 | u16 maxpacket; | 771 | u16 maxpacket; |
@@ -855,8 +859,8 @@ static void schedule_nonisoc_etd(struct imx21 *imx21, struct urb *urb) | |||
855 | 859 | ||
856 | /* allocate x and y buffer space at once */ | 860 | /* allocate x and y buffer space at once */ |
857 | etd->dmem_size = (count > maxpacket) ? maxpacket * 2 : maxpacket; | 861 | etd->dmem_size = (count > maxpacket) ? maxpacket * 2 : maxpacket; |
858 | dmem_offset = alloc_dmem(imx21, etd->dmem_size, urb_priv->ep); | 862 | etd->dmem_offset = alloc_dmem(imx21, etd->dmem_size, urb_priv->ep); |
859 | if (dmem_offset < 0) { | 863 | if (etd->dmem_offset < 0) { |
860 | /* Setup everything we can in HW and update when we get DMEM */ | 864 | /* Setup everything we can in HW and update when we get DMEM */ |
861 | etd_writel(imx21, etd_num, 1, (u32)maxpacket << 16); | 865 | etd_writel(imx21, etd_num, 1, (u32)maxpacket << 16); |
862 | 866 | ||
@@ -867,8 +871,8 @@ static void schedule_nonisoc_etd(struct imx21 *imx21, struct urb *urb) | |||
867 | } | 871 | } |
868 | 872 | ||
869 | etd_writel(imx21, etd_num, 1, | 873 | etd_writel(imx21, etd_num, 1, |
870 | (((u32) dmem_offset + (u32) maxpacket) << DW1_YBUFSRTAD) | | 874 | (((u32) etd->dmem_offset + (u32) maxpacket) << DW1_YBUFSRTAD) | |
871 | (u32) dmem_offset); | 875 | (u32) etd->dmem_offset); |
872 | 876 | ||
873 | urb_priv->active = 1; | 877 | urb_priv->active = 1; |
874 | 878 | ||
@@ -886,7 +890,6 @@ static void nonisoc_etd_done(struct usb_hcd *hcd, struct urb *urb, int etd_num) | |||
886 | u32 etd_mask = 1 << etd_num; | 890 | u32 etd_mask = 1 << etd_num; |
887 | struct urb_priv *urb_priv = urb->hcpriv; | 891 | struct urb_priv *urb_priv = urb->hcpriv; |
888 | int dir; | 892 | int dir; |
889 | u16 xbufaddr; | ||
890 | int cc; | 893 | int cc; |
891 | u32 bytes_xfrd; | 894 | u32 bytes_xfrd; |
892 | int etd_done; | 895 | int etd_done; |
@@ -894,7 +897,6 @@ static void nonisoc_etd_done(struct usb_hcd *hcd, struct urb *urb, int etd_num) | |||
894 | disactivate_etd(imx21, etd_num); | 897 | disactivate_etd(imx21, etd_num); |
895 | 898 | ||
896 | dir = (etd_readl(imx21, etd_num, 0) >> DW0_DIRECT) & 0x3; | 899 | dir = (etd_readl(imx21, etd_num, 0) >> DW0_DIRECT) & 0x3; |
897 | xbufaddr = etd_readl(imx21, etd_num, 1) & 0xffff; | ||
898 | cc = (etd_readl(imx21, etd_num, 2) >> DW2_COMPCODE) & 0xf; | 900 | cc = (etd_readl(imx21, etd_num, 2) >> DW2_COMPCODE) & 0xf; |
899 | bytes_xfrd = etd->len - (etd_readl(imx21, etd_num, 3) & 0x1fffff); | 901 | bytes_xfrd = etd->len - (etd_readl(imx21, etd_num, 3) & 0x1fffff); |
900 | 902 | ||
@@ -907,7 +909,7 @@ static void nonisoc_etd_done(struct usb_hcd *hcd, struct urb *urb, int etd_num) | |||
907 | clear_toggle_bit(imx21, USBH_XFILLSTAT, etd_mask); | 909 | clear_toggle_bit(imx21, USBH_XFILLSTAT, etd_mask); |
908 | clear_toggle_bit(imx21, USBH_YFILLSTAT, etd_mask); | 910 | clear_toggle_bit(imx21, USBH_YFILLSTAT, etd_mask); |
909 | } | 911 | } |
910 | free_dmem(imx21, xbufaddr); | 912 | free_dmem(imx21, etd); |
911 | 913 | ||
912 | urb->error_count = 0; | 914 | urb->error_count = 0; |
913 | if (!(urb->transfer_flags & URB_SHORT_NOT_OK) | 915 | 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, | |||
1123 | int etd_num = ep_priv->etd[0]; | 1125 | int etd_num = ep_priv->etd[0]; |
1124 | if (etd_num != -1) { | 1126 | if (etd_num != -1) { |
1125 | disactivate_etd(imx21, etd_num); | 1127 | disactivate_etd(imx21, etd_num); |
1126 | free_dmem(imx21, etd_readl(imx21, etd_num, 1) & 0xffff); | 1128 | free_dmem(imx21, &imx21->etd[etd_num]); |
1127 | imx21->etd[etd_num].urb = NULL; | 1129 | imx21->etd[etd_num].urb = NULL; |
1128 | } | 1130 | } |
1129 | } | 1131 | } |