diff options
-rw-r--r-- | drivers/usb/host/isp1760-hcd.c | 22 | ||||
-rw-r--r-- | drivers/usb/host/isp1760-hcd.h | 1 |
2 files changed, 17 insertions, 6 deletions
diff --git a/drivers/usb/host/isp1760-hcd.c b/drivers/usb/host/isp1760-hcd.c index bdba8c5d844a..c470cc83dbb0 100644 --- a/drivers/usb/host/isp1760-hcd.c +++ b/drivers/usb/host/isp1760-hcd.c | |||
@@ -33,6 +33,7 @@ struct isp1760_hcd { | |||
33 | struct inter_packet_info atl_ints[32]; | 33 | struct inter_packet_info atl_ints[32]; |
34 | struct inter_packet_info int_ints[32]; | 34 | struct inter_packet_info int_ints[32]; |
35 | struct memory_chunk memory_pool[BLOCKS]; | 35 | struct memory_chunk memory_pool[BLOCKS]; |
36 | u32 atl_queued; | ||
36 | 37 | ||
37 | /* periodic schedule support */ | 38 | /* periodic schedule support */ |
38 | #define DEFAULT_I_TDPS 1024 | 39 | #define DEFAULT_I_TDPS 1024 |
@@ -850,6 +851,11 @@ static void enqueue_an_ATL_packet(struct usb_hcd *hcd, struct isp1760_qh *qh, | |||
850 | skip_map &= ~queue_entry; | 851 | skip_map &= ~queue_entry; |
851 | isp1760_writel(skip_map, hcd->regs + HC_ATL_PTD_SKIPMAP_REG); | 852 | isp1760_writel(skip_map, hcd->regs + HC_ATL_PTD_SKIPMAP_REG); |
852 | 853 | ||
854 | priv->atl_queued++; | ||
855 | if (priv->atl_queued == 2) | ||
856 | isp1760_writel(INTERRUPT_ENABLE_SOT_MASK, | ||
857 | hcd->regs + HC_INTERRUPT_ENABLE); | ||
858 | |||
853 | buffstatus = isp1760_readl(hcd->regs + HC_BUFFER_STATUS_REG); | 859 | buffstatus = isp1760_readl(hcd->regs + HC_BUFFER_STATUS_REG); |
854 | buffstatus |= ATL_BUFFER; | 860 | buffstatus |= ATL_BUFFER; |
855 | isp1760_writel(buffstatus, hcd->regs + HC_BUFFER_STATUS_REG); | 861 | isp1760_writel(buffstatus, hcd->regs + HC_BUFFER_STATUS_REG); |
@@ -992,6 +998,7 @@ static void do_atl_int(struct usb_hcd *usb_hcd) | |||
992 | u32 dw3; | 998 | u32 dw3; |
993 | 999 | ||
994 | status = 0; | 1000 | status = 0; |
1001 | priv->atl_queued--; | ||
995 | 1002 | ||
996 | queue_entry = __ffs(done_map); | 1003 | queue_entry = __ffs(done_map); |
997 | done_map &= ~(1 << queue_entry); | 1004 | done_map &= ~(1 << queue_entry); |
@@ -1054,11 +1061,6 @@ static void do_atl_int(struct usb_hcd *usb_hcd) | |||
1054 | * device is not able to send data fast enough. | 1061 | * device is not able to send data fast enough. |
1055 | * This happens mostly on slower hardware. | 1062 | * This happens mostly on slower hardware. |
1056 | */ | 1063 | */ |
1057 | printk(KERN_NOTICE "Reloading ptd %p/%p... qh %p read: " | ||
1058 | "%d of %zu done: %08x cur: %08x\n", qtd, | ||
1059 | urb, qh, PTD_XFERRED_LENGTH(dw3), | ||
1060 | qtd->length, done_map, | ||
1061 | (1 << queue_entry)); | ||
1062 | 1064 | ||
1063 | /* RL counter = ERR counter */ | 1065 | /* RL counter = ERR counter */ |
1064 | dw3 &= ~(0xf << 19); | 1066 | dw3 &= ~(0xf << 19); |
@@ -1086,6 +1088,11 @@ static void do_atl_int(struct usb_hcd *usb_hcd) | |||
1086 | priv_write_copy(priv, (u32 *)&ptd, usb_hcd->regs + | 1088 | priv_write_copy(priv, (u32 *)&ptd, usb_hcd->regs + |
1087 | atl_regs, sizeof(ptd)); | 1089 | atl_regs, sizeof(ptd)); |
1088 | 1090 | ||
1091 | priv->atl_queued++; | ||
1092 | if (priv->atl_queued == 2) | ||
1093 | isp1760_writel(INTERRUPT_ENABLE_SOT_MASK, | ||
1094 | usb_hcd->regs + HC_INTERRUPT_ENABLE); | ||
1095 | |||
1089 | buffstatus = isp1760_readl(usb_hcd->regs + | 1096 | buffstatus = isp1760_readl(usb_hcd->regs + |
1090 | HC_BUFFER_STATUS_REG); | 1097 | HC_BUFFER_STATUS_REG); |
1091 | buffstatus |= ATL_BUFFER; | 1098 | buffstatus |= ATL_BUFFER; |
@@ -1191,6 +1198,9 @@ static void do_atl_int(struct usb_hcd *usb_hcd) | |||
1191 | skip_map = isp1760_readl(usb_hcd->regs + | 1198 | skip_map = isp1760_readl(usb_hcd->regs + |
1192 | HC_ATL_PTD_SKIPMAP_REG); | 1199 | HC_ATL_PTD_SKIPMAP_REG); |
1193 | } | 1200 | } |
1201 | if (priv->atl_queued <= 1) | ||
1202 | isp1760_writel(INTERRUPT_ENABLE_MASK, | ||
1203 | usb_hcd->regs + HC_INTERRUPT_ENABLE); | ||
1194 | } | 1204 | } |
1195 | 1205 | ||
1196 | static void do_intl_int(struct usb_hcd *usb_hcd) | 1206 | static void do_intl_int(struct usb_hcd *usb_hcd) |
@@ -1770,7 +1780,7 @@ static irqreturn_t isp1760_irq(struct usb_hcd *usb_hcd) | |||
1770 | goto leave; | 1780 | goto leave; |
1771 | 1781 | ||
1772 | isp1760_writel(imask, usb_hcd->regs + HC_INTERRUPT_REG); | 1782 | isp1760_writel(imask, usb_hcd->regs + HC_INTERRUPT_REG); |
1773 | if (imask & HC_ATL_INT) | 1783 | if (imask & (HC_ATL_INT | HC_SOT_INT)) |
1774 | do_atl_int(usb_hcd); | 1784 | do_atl_int(usb_hcd); |
1775 | 1785 | ||
1776 | if (imask & HC_INTL_INT) | 1786 | if (imask & HC_INTL_INT) |
diff --git a/drivers/usb/host/isp1760-hcd.h b/drivers/usb/host/isp1760-hcd.h index 6931ef5c9650..612bce5dce03 100644 --- a/drivers/usb/host/isp1760-hcd.h +++ b/drivers/usb/host/isp1760-hcd.h | |||
@@ -69,6 +69,7 @@ void deinit_kmem_cache(void); | |||
69 | 69 | ||
70 | #define HC_INTERRUPT_ENABLE 0x314 | 70 | #define HC_INTERRUPT_ENABLE 0x314 |
71 | #define INTERRUPT_ENABLE_MASK (HC_INTL_INT | HC_ATL_INT | HC_EOT_INT) | 71 | #define INTERRUPT_ENABLE_MASK (HC_INTL_INT | HC_ATL_INT | HC_EOT_INT) |
72 | #define INTERRUPT_ENABLE_SOT_MASK (HC_INTL_INT | HC_SOT_INT | HC_EOT_INT) | ||
72 | 73 | ||
73 | #define HC_ISO_INT (1 << 9) | 74 | #define HC_ISO_INT (1 << 9) |
74 | #define HC_ATL_INT (1 << 8) | 75 | #define HC_ATL_INT (1 << 8) |