diff options
Diffstat (limited to 'drivers/usb/host/isp1760-hcd.c')
-rw-r--r-- | drivers/usb/host/isp1760-hcd.c | 418 |
1 files changed, 270 insertions, 148 deletions
diff --git a/drivers/usb/host/isp1760-hcd.c b/drivers/usb/host/isp1760-hcd.c index 840beda66dd9..27dfab80ed8f 100644 --- a/drivers/usb/host/isp1760-hcd.c +++ b/drivers/usb/host/isp1760-hcd.c | |||
@@ -21,8 +21,10 @@ | |||
21 | #include <linux/uaccess.h> | 21 | #include <linux/uaccess.h> |
22 | #include <linux/io.h> | 22 | #include <linux/io.h> |
23 | #include <linux/mm.h> | 23 | #include <linux/mm.h> |
24 | #include <linux/timer.h> | ||
24 | #include <asm/unaligned.h> | 25 | #include <asm/unaligned.h> |
25 | #include <asm/cacheflush.h> | 26 | #include <asm/cacheflush.h> |
27 | #include <linux/gpio.h> | ||
26 | 28 | ||
27 | #include "isp1760-hcd.h" | 29 | #include "isp1760-hcd.h" |
28 | 30 | ||
@@ -39,7 +41,6 @@ struct isp1760_hcd { | |||
39 | int int_done_map; | 41 | int int_done_map; |
40 | struct memory_chunk memory_pool[BLOCKS]; | 42 | struct memory_chunk memory_pool[BLOCKS]; |
41 | struct list_head controlqhs, bulkqhs, interruptqhs; | 43 | struct list_head controlqhs, bulkqhs, interruptqhs; |
42 | int active_ptds; | ||
43 | 44 | ||
44 | /* periodic schedule support */ | 45 | /* periodic schedule support */ |
45 | #define DEFAULT_I_TDPS 1024 | 46 | #define DEFAULT_I_TDPS 1024 |
@@ -48,6 +49,8 @@ struct isp1760_hcd { | |||
48 | unsigned long reset_done; | 49 | unsigned long reset_done; |
49 | unsigned long next_statechange; | 50 | unsigned long next_statechange; |
50 | unsigned int devflags; | 51 | unsigned int devflags; |
52 | |||
53 | int rst_gpio; | ||
51 | }; | 54 | }; |
52 | 55 | ||
53 | static inline struct isp1760_hcd *hcd_to_priv(struct usb_hcd *hcd) | 56 | static inline struct isp1760_hcd *hcd_to_priv(struct usb_hcd *hcd) |
@@ -114,6 +117,7 @@ struct isp1760_qh { | |||
114 | u32 toggle; | 117 | u32 toggle; |
115 | u32 ping; | 118 | u32 ping; |
116 | int slot; | 119 | int slot; |
120 | int tt_buffer_dirty; /* See USB2.0 spec section 11.17.5 */ | ||
117 | }; | 121 | }; |
118 | 122 | ||
119 | struct urb_listitem { | 123 | struct urb_listitem { |
@@ -432,6 +436,18 @@ static int isp1760_hc_setup(struct usb_hcd *hcd) | |||
432 | int result; | 436 | int result; |
433 | u32 scratch, hwmode; | 437 | u32 scratch, hwmode; |
434 | 438 | ||
439 | /* low-level chip reset */ | ||
440 | if (gpio_is_valid(priv->rst_gpio)) { | ||
441 | unsigned int rst_lvl; | ||
442 | |||
443 | rst_lvl = (priv->devflags & | ||
444 | ISP1760_FLAG_RESET_ACTIVE_HIGH) ? 1 : 0; | ||
445 | |||
446 | gpio_set_value(priv->rst_gpio, rst_lvl); | ||
447 | mdelay(50); | ||
448 | gpio_set_value(priv->rst_gpio, !rst_lvl); | ||
449 | } | ||
450 | |||
435 | /* Setup HW Mode Control: This assumes a level active-low interrupt */ | 451 | /* Setup HW Mode Control: This assumes a level active-low interrupt */ |
436 | hwmode = HW_DATA_BUS_32BIT; | 452 | hwmode = HW_DATA_BUS_32BIT; |
437 | 453 | ||
@@ -489,10 +505,6 @@ static int isp1760_hc_setup(struct usb_hcd *hcd) | |||
489 | 16 : 32, (priv->devflags & ISP1760_FLAG_ANALOG_OC) ? | 505 | 16 : 32, (priv->devflags & ISP1760_FLAG_ANALOG_OC) ? |
490 | "analog" : "digital"); | 506 | "analog" : "digital"); |
491 | 507 | ||
492 | /* This is weird: at the first plug-in of a device there seems to be | ||
493 | one packet queued that never gets returned? */ | ||
494 | priv->active_ptds = -1; | ||
495 | |||
496 | /* ATL reset */ | 508 | /* ATL reset */ |
497 | reg_write32(hcd->regs, HC_HW_MODE_CTRL, hwmode | ALL_ATX_RESET); | 509 | reg_write32(hcd->regs, HC_HW_MODE_CTRL, hwmode | ALL_ATX_RESET); |
498 | mdelay(10); | 510 | mdelay(10); |
@@ -514,83 +526,6 @@ static int isp1760_hc_setup(struct usb_hcd *hcd) | |||
514 | return priv_init(hcd); | 526 | return priv_init(hcd); |
515 | } | 527 | } |
516 | 528 | ||
517 | static void isp1760_init_maps(struct usb_hcd *hcd) | ||
518 | { | ||
519 | /*set last maps, for iso its only 1, else 32 tds bitmap*/ | ||
520 | reg_write32(hcd->regs, HC_ATL_PTD_LASTPTD_REG, 0x80000000); | ||
521 | reg_write32(hcd->regs, HC_INT_PTD_LASTPTD_REG, 0x80000000); | ||
522 | reg_write32(hcd->regs, HC_ISO_PTD_LASTPTD_REG, 0x00000001); | ||
523 | |||
524 | reg_write32(hcd->regs, HC_ATL_PTD_SKIPMAP_REG, 0xffffffff); | ||
525 | reg_write32(hcd->regs, HC_INT_PTD_SKIPMAP_REG, 0xffffffff); | ||
526 | reg_write32(hcd->regs, HC_ISO_PTD_SKIPMAP_REG, 0xffffffff); | ||
527 | |||
528 | reg_write32(hcd->regs, HC_BUFFER_STATUS_REG, | ||
529 | ATL_BUF_FILL | INT_BUF_FILL); | ||
530 | } | ||
531 | |||
532 | static void isp1760_enable_interrupts(struct usb_hcd *hcd) | ||
533 | { | ||
534 | reg_write32(hcd->regs, HC_ATL_IRQ_MASK_AND_REG, 0); | ||
535 | reg_write32(hcd->regs, HC_ATL_IRQ_MASK_OR_REG, 0xffffffff); | ||
536 | reg_write32(hcd->regs, HC_INT_IRQ_MASK_AND_REG, 0); | ||
537 | reg_write32(hcd->regs, HC_INT_IRQ_MASK_OR_REG, 0xffffffff); | ||
538 | reg_write32(hcd->regs, HC_ISO_IRQ_MASK_AND_REG, 0); | ||
539 | reg_write32(hcd->regs, HC_ISO_IRQ_MASK_OR_REG, 0xffffffff); | ||
540 | /* step 23 passed */ | ||
541 | } | ||
542 | |||
543 | static int isp1760_run(struct usb_hcd *hcd) | ||
544 | { | ||
545 | int retval; | ||
546 | u32 temp; | ||
547 | u32 command; | ||
548 | u32 chipid; | ||
549 | |||
550 | hcd->uses_new_polling = 1; | ||
551 | |||
552 | hcd->state = HC_STATE_RUNNING; | ||
553 | isp1760_enable_interrupts(hcd); | ||
554 | temp = reg_read32(hcd->regs, HC_HW_MODE_CTRL); | ||
555 | reg_write32(hcd->regs, HC_HW_MODE_CTRL, temp | HW_GLOBAL_INTR_EN); | ||
556 | |||
557 | command = reg_read32(hcd->regs, HC_USBCMD); | ||
558 | command &= ~(CMD_LRESET|CMD_RESET); | ||
559 | command |= CMD_RUN; | ||
560 | reg_write32(hcd->regs, HC_USBCMD, command); | ||
561 | |||
562 | retval = handshake(hcd, HC_USBCMD, CMD_RUN, CMD_RUN, 250 * 1000); | ||
563 | if (retval) | ||
564 | return retval; | ||
565 | |||
566 | /* | ||
567 | * XXX | ||
568 | * Spec says to write FLAG_CF as last config action, priv code grabs | ||
569 | * the semaphore while doing so. | ||
570 | */ | ||
571 | down_write(&ehci_cf_port_reset_rwsem); | ||
572 | reg_write32(hcd->regs, HC_CONFIGFLAG, FLAG_CF); | ||
573 | |||
574 | retval = handshake(hcd, HC_CONFIGFLAG, FLAG_CF, FLAG_CF, 250 * 1000); | ||
575 | up_write(&ehci_cf_port_reset_rwsem); | ||
576 | if (retval) | ||
577 | return retval; | ||
578 | |||
579 | chipid = reg_read32(hcd->regs, HC_CHIP_ID_REG); | ||
580 | dev_info(hcd->self.controller, "USB ISP %04x HW rev. %d started\n", | ||
581 | chipid & 0xffff, chipid >> 16); | ||
582 | |||
583 | /* PTD Register Init Part 2, Step 28 */ | ||
584 | /* enable INTs */ | ||
585 | isp1760_init_maps(hcd); | ||
586 | |||
587 | /* GRR this is run-once init(), being done every time the HC starts. | ||
588 | * So long as they're part of class devices, we can't do it init() | ||
589 | * since the class device isn't created that early. | ||
590 | */ | ||
591 | return 0; | ||
592 | } | ||
593 | |||
594 | static u32 base_to_chip(u32 base) | 529 | static u32 base_to_chip(u32 base) |
595 | { | 530 | { |
596 | return ((base - 0x400) >> 3); | 531 | return ((base - 0x400) >> 3); |
@@ -813,28 +748,29 @@ static void start_bus_transfer(struct usb_hcd *hcd, u32 ptd_offset, int slot, | |||
813 | WARN_ON(slots[slot].qh); | 748 | WARN_ON(slots[slot].qh); |
814 | WARN_ON(qtd->status != QTD_PAYLOAD_ALLOC); | 749 | WARN_ON(qtd->status != QTD_PAYLOAD_ALLOC); |
815 | 750 | ||
816 | slots[slot].qtd = qtd; | ||
817 | slots[slot].qh = qh; | ||
818 | qh->slot = slot; | ||
819 | qtd->status = QTD_XFER_STARTED; /* Set this before writing ptd, since | ||
820 | interrupt routine may preempt and expects this value. */ | ||
821 | ptd_write(hcd->regs, ptd_offset, slot, ptd); | ||
822 | priv->active_ptds++; | ||
823 | |||
824 | /* Make sure done map has not triggered from some unlinked transfer */ | 751 | /* Make sure done map has not triggered from some unlinked transfer */ |
825 | if (ptd_offset == ATL_PTD_OFFSET) { | 752 | if (ptd_offset == ATL_PTD_OFFSET) { |
826 | priv->atl_done_map |= reg_read32(hcd->regs, | 753 | priv->atl_done_map |= reg_read32(hcd->regs, |
827 | HC_ATL_PTD_DONEMAP_REG); | 754 | HC_ATL_PTD_DONEMAP_REG); |
828 | priv->atl_done_map &= ~(1 << qh->slot); | 755 | priv->atl_done_map &= ~(1 << slot); |
756 | } else { | ||
757 | priv->int_done_map |= reg_read32(hcd->regs, | ||
758 | HC_INT_PTD_DONEMAP_REG); | ||
759 | priv->int_done_map &= ~(1 << slot); | ||
760 | } | ||
761 | |||
762 | qh->slot = slot; | ||
763 | qtd->status = QTD_XFER_STARTED; | ||
764 | slots[slot].timestamp = jiffies; | ||
765 | slots[slot].qtd = qtd; | ||
766 | slots[slot].qh = qh; | ||
767 | ptd_write(hcd->regs, ptd_offset, slot, ptd); | ||
829 | 768 | ||
769 | if (ptd_offset == ATL_PTD_OFFSET) { | ||
830 | skip_map = reg_read32(hcd->regs, HC_ATL_PTD_SKIPMAP_REG); | 770 | skip_map = reg_read32(hcd->regs, HC_ATL_PTD_SKIPMAP_REG); |
831 | skip_map &= ~(1 << qh->slot); | 771 | skip_map &= ~(1 << qh->slot); |
832 | reg_write32(hcd->regs, HC_ATL_PTD_SKIPMAP_REG, skip_map); | 772 | reg_write32(hcd->regs, HC_ATL_PTD_SKIPMAP_REG, skip_map); |
833 | } else { | 773 | } else { |
834 | priv->int_done_map |= reg_read32(hcd->regs, | ||
835 | HC_INT_PTD_DONEMAP_REG); | ||
836 | priv->int_done_map &= ~(1 << qh->slot); | ||
837 | |||
838 | skip_map = reg_read32(hcd->regs, HC_INT_PTD_SKIPMAP_REG); | 774 | skip_map = reg_read32(hcd->regs, HC_INT_PTD_SKIPMAP_REG); |
839 | skip_map &= ~(1 << qh->slot); | 775 | skip_map &= ~(1 << qh->slot); |
840 | reg_write32(hcd->regs, HC_INT_PTD_SKIPMAP_REG, skip_map); | 776 | reg_write32(hcd->regs, HC_INT_PTD_SKIPMAP_REG, skip_map); |
@@ -858,10 +794,7 @@ static void collect_qtds(struct usb_hcd *hcd, struct isp1760_qh *qh, | |||
858 | if (qtd->status < QTD_XFER_COMPLETE) | 794 | if (qtd->status < QTD_XFER_COMPLETE) |
859 | break; | 795 | break; |
860 | 796 | ||
861 | if (list_is_last(&qtd->qtd_list, &qh->qtd_list)) | 797 | last_qtd = last_qtd_of_urb(qtd, qh); |
862 | last_qtd = 1; | ||
863 | else | ||
864 | last_qtd = qtd->urb != qtd_next->urb; | ||
865 | 798 | ||
866 | if ((!last_qtd) && (qtd->status == QTD_RETIRE)) | 799 | if ((!last_qtd) && (qtd->status == QTD_RETIRE)) |
867 | qtd_next->status = QTD_RETIRE; | 800 | qtd_next->status = QTD_RETIRE; |
@@ -902,7 +835,7 @@ static void collect_qtds(struct usb_hcd *hcd, struct isp1760_qh *qh, | |||
902 | urb_listitem = kmem_cache_zalloc(urb_listitem_cachep, | 835 | urb_listitem = kmem_cache_zalloc(urb_listitem_cachep, |
903 | GFP_ATOMIC); | 836 | GFP_ATOMIC); |
904 | if (unlikely(!urb_listitem)) | 837 | if (unlikely(!urb_listitem)) |
905 | break; | 838 | break; /* Try again on next call */ |
906 | urb_listitem->urb = qtd->urb; | 839 | urb_listitem->urb = qtd->urb; |
907 | list_add_tail(&urb_listitem->urb_list, urb_list); | 840 | list_add_tail(&urb_listitem->urb_list, urb_list); |
908 | } | 841 | } |
@@ -928,6 +861,10 @@ static void enqueue_qtds(struct usb_hcd *hcd, struct isp1760_qh *qh) | |||
928 | return; | 861 | return; |
929 | } | 862 | } |
930 | 863 | ||
864 | /* Make sure this endpoint's TT buffer is clean before queueing ptds */ | ||
865 | if (qh->tt_buffer_dirty) | ||
866 | return; | ||
867 | |||
931 | if (usb_pipeint(list_entry(qh->qtd_list.next, struct isp1760_qtd, | 868 | if (usb_pipeint(list_entry(qh->qtd_list.next, struct isp1760_qtd, |
932 | qtd_list)->urb->pipe)) { | 869 | qtd_list)->urb->pipe)) { |
933 | ptd_offset = INT_PTD_OFFSET; | 870 | ptd_offset = INT_PTD_OFFSET; |
@@ -1168,11 +1105,9 @@ static int check_atl_transfer(struct usb_hcd *hcd, struct ptd *ptd, | |||
1168 | return PTD_STATE_QTD_DONE; | 1105 | return PTD_STATE_QTD_DONE; |
1169 | } | 1106 | } |
1170 | 1107 | ||
1171 | static irqreturn_t isp1760_irq(struct usb_hcd *hcd) | 1108 | static void handle_done_ptds(struct usb_hcd *hcd) |
1172 | { | 1109 | { |
1173 | struct isp1760_hcd *priv = hcd_to_priv(hcd); | 1110 | struct isp1760_hcd *priv = hcd_to_priv(hcd); |
1174 | u32 imask; | ||
1175 | irqreturn_t irqret = IRQ_NONE; | ||
1176 | struct ptd ptd; | 1111 | struct ptd ptd; |
1177 | struct isp1760_qh *qh; | 1112 | struct isp1760_qh *qh; |
1178 | int slot; | 1113 | int slot; |
@@ -1181,27 +1116,14 @@ static irqreturn_t isp1760_irq(struct usb_hcd *hcd) | |||
1181 | u32 ptd_offset; | 1116 | u32 ptd_offset; |
1182 | struct isp1760_qtd *qtd; | 1117 | struct isp1760_qtd *qtd; |
1183 | int modified; | 1118 | int modified; |
1184 | static int last_active_ptds; | 1119 | int skip_map; |
1185 | int int_skip_map, atl_skip_map; | ||
1186 | |||
1187 | spin_lock(&priv->lock); | ||
1188 | |||
1189 | if (!(hcd->state & HC_STATE_RUNNING)) | ||
1190 | goto leave; | ||
1191 | |||
1192 | imask = reg_read32(hcd->regs, HC_INTERRUPT_REG); | ||
1193 | if (unlikely(!imask)) | ||
1194 | goto leave; | ||
1195 | reg_write32(hcd->regs, HC_INTERRUPT_REG, imask); /* Clear */ | ||
1196 | 1120 | ||
1197 | int_skip_map = reg_read32(hcd->regs, HC_INT_PTD_SKIPMAP_REG); | 1121 | skip_map = reg_read32(hcd->regs, HC_INT_PTD_SKIPMAP_REG); |
1198 | atl_skip_map = reg_read32(hcd->regs, HC_ATL_PTD_SKIPMAP_REG); | 1122 | priv->int_done_map &= ~skip_map; |
1199 | priv->int_done_map |= reg_read32(hcd->regs, HC_INT_PTD_DONEMAP_REG); | 1123 | skip_map = reg_read32(hcd->regs, HC_ATL_PTD_SKIPMAP_REG); |
1200 | priv->atl_done_map |= reg_read32(hcd->regs, HC_ATL_PTD_DONEMAP_REG); | 1124 | priv->atl_done_map &= ~skip_map; |
1201 | priv->int_done_map &= ~int_skip_map; | ||
1202 | priv->atl_done_map &= ~atl_skip_map; | ||
1203 | 1125 | ||
1204 | modified = priv->int_done_map | priv->atl_done_map; | 1126 | modified = priv->int_done_map || priv->atl_done_map; |
1205 | 1127 | ||
1206 | while (priv->int_done_map || priv->atl_done_map) { | 1128 | while (priv->int_done_map || priv->atl_done_map) { |
1207 | if (priv->int_done_map) { | 1129 | if (priv->int_done_map) { |
@@ -1240,7 +1162,6 @@ static irqreturn_t isp1760_irq(struct usb_hcd *hcd) | |||
1240 | slots[slot].qtd = NULL; | 1162 | slots[slot].qtd = NULL; |
1241 | qh = slots[slot].qh; | 1163 | qh = slots[slot].qh; |
1242 | slots[slot].qh = NULL; | 1164 | slots[slot].qh = NULL; |
1243 | priv->active_ptds--; | ||
1244 | qh->slot = -1; | 1165 | qh->slot = -1; |
1245 | 1166 | ||
1246 | WARN_ON(qtd->status != QTD_XFER_STARTED); | 1167 | WARN_ON(qtd->status != QTD_XFER_STARTED); |
@@ -1281,6 +1202,15 @@ static irqreturn_t isp1760_irq(struct usb_hcd *hcd) | |||
1281 | 1202 | ||
1282 | case PTD_STATE_URB_RETIRE: | 1203 | case PTD_STATE_URB_RETIRE: |
1283 | qtd->status = QTD_RETIRE; | 1204 | qtd->status = QTD_RETIRE; |
1205 | if ((qtd->urb->dev->speed != USB_SPEED_HIGH) && | ||
1206 | (qtd->urb->status != -EPIPE) && | ||
1207 | (qtd->urb->status != -EREMOTEIO)) { | ||
1208 | qh->tt_buffer_dirty = 1; | ||
1209 | if (usb_hub_clear_tt_buffer(qtd->urb)) | ||
1210 | /* Clear failed; let's hope things work | ||
1211 | anyway */ | ||
1212 | qh->tt_buffer_dirty = 0; | ||
1213 | } | ||
1284 | qtd = NULL; | 1214 | qtd = NULL; |
1285 | qh->toggle = 0; | 1215 | qh->toggle = 0; |
1286 | qh->ping = 0; | 1216 | qh->ping = 0; |
@@ -1311,22 +1241,28 @@ static irqreturn_t isp1760_irq(struct usb_hcd *hcd) | |||
1311 | 1241 | ||
1312 | if (modified) | 1242 | if (modified) |
1313 | schedule_ptds(hcd); | 1243 | schedule_ptds(hcd); |
1244 | } | ||
1314 | 1245 | ||
1315 | /* ISP1760 Errata 2 explains that interrupts may be missed (or not | 1246 | static irqreturn_t isp1760_irq(struct usb_hcd *hcd) |
1316 | happen?) if two USB devices are running simultaneously. Perhaps | 1247 | { |
1317 | this happens when a PTD is finished during interrupt handling; | 1248 | struct isp1760_hcd *priv = hcd_to_priv(hcd); |
1318 | enable SOF interrupts if PTDs are still scheduled when exiting this | 1249 | u32 imask; |
1319 | interrupt handler, just to be safe. */ | 1250 | irqreturn_t irqret = IRQ_NONE; |
1320 | 1251 | ||
1321 | if (priv->active_ptds != last_active_ptds) { | 1252 | spin_lock(&priv->lock); |
1322 | if (priv->active_ptds > 0) | 1253 | |
1323 | reg_write32(hcd->regs, HC_INTERRUPT_ENABLE, | 1254 | if (!(hcd->state & HC_STATE_RUNNING)) |
1324 | INTERRUPT_ENABLE_SOT_MASK); | 1255 | goto leave; |
1325 | else | 1256 | |
1326 | reg_write32(hcd->regs, HC_INTERRUPT_ENABLE, | 1257 | imask = reg_read32(hcd->regs, HC_INTERRUPT_REG); |
1327 | INTERRUPT_ENABLE_MASK); | 1258 | if (unlikely(!imask)) |
1328 | last_active_ptds = priv->active_ptds; | 1259 | goto leave; |
1329 | } | 1260 | reg_write32(hcd->regs, HC_INTERRUPT_REG, imask); /* Clear */ |
1261 | |||
1262 | priv->int_done_map |= reg_read32(hcd->regs, HC_INT_PTD_DONEMAP_REG); | ||
1263 | priv->atl_done_map |= reg_read32(hcd->regs, HC_ATL_PTD_DONEMAP_REG); | ||
1264 | |||
1265 | handle_done_ptds(hcd); | ||
1330 | 1266 | ||
1331 | irqret = IRQ_HANDLED; | 1267 | irqret = IRQ_HANDLED; |
1332 | leave: | 1268 | leave: |
@@ -1335,6 +1271,138 @@ leave: | |||
1335 | return irqret; | 1271 | return irqret; |
1336 | } | 1272 | } |
1337 | 1273 | ||
1274 | /* | ||
1275 | * Workaround for problem described in chip errata 2: | ||
1276 | * | ||
1277 | * Sometimes interrupts are not generated when ATL (not INT?) completion occurs. | ||
1278 | * One solution suggested in the errata is to use SOF interrupts _instead_of_ | ||
1279 | * ATL done interrupts (the "instead of" might be important since it seems | ||
1280 | * enabling ATL interrupts also causes the chip to sometimes - rarely - "forget" | ||
1281 | * to set the PTD's done bit in addition to not generating an interrupt!). | ||
1282 | * | ||
1283 | * So if we use SOF + ATL interrupts, we sometimes get stale PTDs since their | ||
1284 | * done bit is not being set. This is bad - it blocks the endpoint until reboot. | ||
1285 | * | ||
1286 | * If we use SOF interrupts only, we get latency between ptd completion and the | ||
1287 | * actual handling. This is very noticeable in testusb runs which takes several | ||
1288 | * minutes longer without ATL interrupts. | ||
1289 | * | ||
1290 | * A better solution is to run the code below every SLOT_CHECK_PERIOD ms. If it | ||
1291 | * finds active ATL slots which are older than SLOT_TIMEOUT ms, it checks the | ||
1292 | * slot's ACTIVE and VALID bits. If these are not set, the ptd is considered | ||
1293 | * completed and its done map bit is set. | ||
1294 | * | ||
1295 | * The values of SLOT_TIMEOUT and SLOT_CHECK_PERIOD have been arbitrarily chosen | ||
1296 | * not to cause too much lag when this HW bug occurs, while still hopefully | ||
1297 | * ensuring that the check does not falsely trigger. | ||
1298 | */ | ||
1299 | #define SLOT_TIMEOUT 300 | ||
1300 | #define SLOT_CHECK_PERIOD 200 | ||
1301 | static struct timer_list errata2_timer; | ||
1302 | |||
1303 | void errata2_function(unsigned long data) | ||
1304 | { | ||
1305 | struct usb_hcd *hcd = (struct usb_hcd *) data; | ||
1306 | struct isp1760_hcd *priv = hcd_to_priv(hcd); | ||
1307 | int slot; | ||
1308 | struct ptd ptd; | ||
1309 | unsigned long spinflags; | ||
1310 | |||
1311 | spin_lock_irqsave(&priv->lock, spinflags); | ||
1312 | |||
1313 | for (slot = 0; slot < 32; slot++) | ||
1314 | if (priv->atl_slots[slot].qh && time_after(jiffies, | ||
1315 | priv->atl_slots[slot].timestamp + | ||
1316 | SLOT_TIMEOUT * HZ / 1000)) { | ||
1317 | ptd_read(hcd->regs, ATL_PTD_OFFSET, slot, &ptd); | ||
1318 | if (!FROM_DW0_VALID(ptd.dw0) && | ||
1319 | !FROM_DW3_ACTIVE(ptd.dw3)) | ||
1320 | priv->atl_done_map |= 1 << slot; | ||
1321 | } | ||
1322 | |||
1323 | if (priv->atl_done_map) | ||
1324 | handle_done_ptds(hcd); | ||
1325 | |||
1326 | spin_unlock_irqrestore(&priv->lock, spinflags); | ||
1327 | |||
1328 | errata2_timer.expires = jiffies + SLOT_CHECK_PERIOD * HZ / 1000; | ||
1329 | add_timer(&errata2_timer); | ||
1330 | } | ||
1331 | |||
1332 | static int isp1760_run(struct usb_hcd *hcd) | ||
1333 | { | ||
1334 | int retval; | ||
1335 | u32 temp; | ||
1336 | u32 command; | ||
1337 | u32 chipid; | ||
1338 | |||
1339 | hcd->uses_new_polling = 1; | ||
1340 | |||
1341 | hcd->state = HC_STATE_RUNNING; | ||
1342 | |||
1343 | /* Set PTD interrupt AND & OR maps */ | ||
1344 | reg_write32(hcd->regs, HC_ATL_IRQ_MASK_AND_REG, 0); | ||
1345 | reg_write32(hcd->regs, HC_ATL_IRQ_MASK_OR_REG, 0xffffffff); | ||
1346 | reg_write32(hcd->regs, HC_INT_IRQ_MASK_AND_REG, 0); | ||
1347 | reg_write32(hcd->regs, HC_INT_IRQ_MASK_OR_REG, 0xffffffff); | ||
1348 | reg_write32(hcd->regs, HC_ISO_IRQ_MASK_AND_REG, 0); | ||
1349 | reg_write32(hcd->regs, HC_ISO_IRQ_MASK_OR_REG, 0xffffffff); | ||
1350 | /* step 23 passed */ | ||
1351 | |||
1352 | temp = reg_read32(hcd->regs, HC_HW_MODE_CTRL); | ||
1353 | reg_write32(hcd->regs, HC_HW_MODE_CTRL, temp | HW_GLOBAL_INTR_EN); | ||
1354 | |||
1355 | command = reg_read32(hcd->regs, HC_USBCMD); | ||
1356 | command &= ~(CMD_LRESET|CMD_RESET); | ||
1357 | command |= CMD_RUN; | ||
1358 | reg_write32(hcd->regs, HC_USBCMD, command); | ||
1359 | |||
1360 | retval = handshake(hcd, HC_USBCMD, CMD_RUN, CMD_RUN, 250 * 1000); | ||
1361 | if (retval) | ||
1362 | return retval; | ||
1363 | |||
1364 | /* | ||
1365 | * XXX | ||
1366 | * Spec says to write FLAG_CF as last config action, priv code grabs | ||
1367 | * the semaphore while doing so. | ||
1368 | */ | ||
1369 | down_write(&ehci_cf_port_reset_rwsem); | ||
1370 | reg_write32(hcd->regs, HC_CONFIGFLAG, FLAG_CF); | ||
1371 | |||
1372 | retval = handshake(hcd, HC_CONFIGFLAG, FLAG_CF, FLAG_CF, 250 * 1000); | ||
1373 | up_write(&ehci_cf_port_reset_rwsem); | ||
1374 | if (retval) | ||
1375 | return retval; | ||
1376 | |||
1377 | init_timer(&errata2_timer); | ||
1378 | errata2_timer.function = errata2_function; | ||
1379 | errata2_timer.data = (unsigned long) hcd; | ||
1380 | errata2_timer.expires = jiffies + SLOT_CHECK_PERIOD * HZ / 1000; | ||
1381 | add_timer(&errata2_timer); | ||
1382 | |||
1383 | chipid = reg_read32(hcd->regs, HC_CHIP_ID_REG); | ||
1384 | dev_info(hcd->self.controller, "USB ISP %04x HW rev. %d started\n", | ||
1385 | chipid & 0xffff, chipid >> 16); | ||
1386 | |||
1387 | /* PTD Register Init Part 2, Step 28 */ | ||
1388 | |||
1389 | /* Setup registers controlling PTD checking */ | ||
1390 | reg_write32(hcd->regs, HC_ATL_PTD_LASTPTD_REG, 0x80000000); | ||
1391 | reg_write32(hcd->regs, HC_INT_PTD_LASTPTD_REG, 0x80000000); | ||
1392 | reg_write32(hcd->regs, HC_ISO_PTD_LASTPTD_REG, 0x00000001); | ||
1393 | reg_write32(hcd->regs, HC_ATL_PTD_SKIPMAP_REG, 0xffffffff); | ||
1394 | reg_write32(hcd->regs, HC_INT_PTD_SKIPMAP_REG, 0xffffffff); | ||
1395 | reg_write32(hcd->regs, HC_ISO_PTD_SKIPMAP_REG, 0xffffffff); | ||
1396 | reg_write32(hcd->regs, HC_BUFFER_STATUS_REG, | ||
1397 | ATL_BUF_FILL | INT_BUF_FILL); | ||
1398 | |||
1399 | /* GRR this is run-once init(), being done every time the HC starts. | ||
1400 | * So long as they're part of class devices, we can't do it init() | ||
1401 | * since the class device isn't created that early. | ||
1402 | */ | ||
1403 | return 0; | ||
1404 | } | ||
1405 | |||
1338 | static int qtd_fill(struct isp1760_qtd *qtd, void *databuffer, size_t len) | 1406 | static int qtd_fill(struct isp1760_qtd *qtd, void *databuffer, size_t len) |
1339 | { | 1407 | { |
1340 | qtd->data_buffer = databuffer; | 1408 | qtd->data_buffer = databuffer; |
@@ -1503,7 +1571,6 @@ static int isp1760_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, | |||
1503 | packetize_urb(hcd, urb, &new_qtds, mem_flags); | 1571 | packetize_urb(hcd, urb, &new_qtds, mem_flags); |
1504 | if (list_empty(&new_qtds)) | 1572 | if (list_empty(&new_qtds)) |
1505 | return -ENOMEM; | 1573 | return -ENOMEM; |
1506 | urb->hcpriv = NULL; /* Used to signal unlink to interrupt handler */ | ||
1507 | 1574 | ||
1508 | retval = 0; | 1575 | retval = 0; |
1509 | spin_lock_irqsave(&priv->lock, spinflags); | 1576 | spin_lock_irqsave(&priv->lock, spinflags); |
@@ -1531,6 +1598,7 @@ static int isp1760_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, | |||
1531 | qh = qh_alloc(GFP_ATOMIC); | 1598 | qh = qh_alloc(GFP_ATOMIC); |
1532 | if (!qh) { | 1599 | if (!qh) { |
1533 | retval = -ENOMEM; | 1600 | retval = -ENOMEM; |
1601 | usb_hcd_unlink_urb_from_ep(hcd, urb); | ||
1534 | goto out; | 1602 | goto out; |
1535 | } | 1603 | } |
1536 | list_add_tail(&qh->qh_list, ep_queue); | 1604 | list_add_tail(&qh->qh_list, ep_queue); |
@@ -1570,7 +1638,41 @@ static void kill_transfer(struct usb_hcd *hcd, struct urb *urb, | |||
1570 | } | 1638 | } |
1571 | 1639 | ||
1572 | qh->slot = -1; | 1640 | qh->slot = -1; |
1573 | priv->active_ptds--; | 1641 | } |
1642 | |||
1643 | /* | ||
1644 | * Retire the qtds beginning at 'qtd' and belonging all to the same urb, killing | ||
1645 | * any active transfer belonging to the urb in the process. | ||
1646 | */ | ||
1647 | static void dequeue_urb_from_qtd(struct usb_hcd *hcd, struct isp1760_qh *qh, | ||
1648 | struct isp1760_qtd *qtd) | ||
1649 | { | ||
1650 | struct urb *urb; | ||
1651 | int urb_was_running; | ||
1652 | |||
1653 | urb = qtd->urb; | ||
1654 | urb_was_running = 0; | ||
1655 | list_for_each_entry_from(qtd, &qh->qtd_list, qtd_list) { | ||
1656 | if (qtd->urb != urb) | ||
1657 | break; | ||
1658 | |||
1659 | if (qtd->status >= QTD_XFER_STARTED) | ||
1660 | urb_was_running = 1; | ||
1661 | if (last_qtd_of_urb(qtd, qh) && | ||
1662 | (qtd->status >= QTD_XFER_COMPLETE)) | ||
1663 | urb_was_running = 0; | ||
1664 | |||
1665 | if (qtd->status == QTD_XFER_STARTED) | ||
1666 | kill_transfer(hcd, urb, qh); | ||
1667 | qtd->status = QTD_RETIRE; | ||
1668 | } | ||
1669 | |||
1670 | if ((urb->dev->speed != USB_SPEED_HIGH) && urb_was_running) { | ||
1671 | qh->tt_buffer_dirty = 1; | ||
1672 | if (usb_hub_clear_tt_buffer(urb)) | ||
1673 | /* Clear failed; let's hope things work anyway */ | ||
1674 | qh->tt_buffer_dirty = 0; | ||
1675 | } | ||
1574 | } | 1676 | } |
1575 | 1677 | ||
1576 | static int isp1760_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, | 1678 | static int isp1760_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, |
@@ -1595,9 +1697,8 @@ static int isp1760_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, | |||
1595 | 1697 | ||
1596 | list_for_each_entry(qtd, &qh->qtd_list, qtd_list) | 1698 | list_for_each_entry(qtd, &qh->qtd_list, qtd_list) |
1597 | if (qtd->urb == urb) { | 1699 | if (qtd->urb == urb) { |
1598 | if (qtd->status == QTD_XFER_STARTED) | 1700 | dequeue_urb_from_qtd(hcd, qh, qtd); |
1599 | kill_transfer(hcd, urb, qh); | 1701 | break; |
1600 | qtd->status = QTD_RETIRE; | ||
1601 | } | 1702 | } |
1602 | 1703 | ||
1603 | urb->status = status; | 1704 | urb->status = status; |
@@ -1622,12 +1723,11 @@ static void isp1760_endpoint_disable(struct usb_hcd *hcd, | |||
1622 | if (!qh) | 1723 | if (!qh) |
1623 | goto out; | 1724 | goto out; |
1624 | 1725 | ||
1625 | list_for_each_entry(qtd, &qh->qtd_list, qtd_list) { | 1726 | list_for_each_entry(qtd, &qh->qtd_list, qtd_list) |
1626 | if (qtd->status == QTD_XFER_STARTED) | 1727 | if (qtd->status != QTD_RETIRE) { |
1627 | kill_transfer(hcd, qtd->urb, qh); | 1728 | dequeue_urb_from_qtd(hcd, qh, qtd); |
1628 | qtd->status = QTD_RETIRE; | 1729 | qtd->urb->status = -ECONNRESET; |
1629 | qtd->urb->status = -ECONNRESET; | 1730 | } |
1630 | } | ||
1631 | 1731 | ||
1632 | ep->hcpriv = NULL; | 1732 | ep->hcpriv = NULL; |
1633 | /* Cannot free qh here since it will be parsed by schedule_ptds() */ | 1733 | /* Cannot free qh here since it will be parsed by schedule_ptds() */ |
@@ -2021,6 +2121,8 @@ static void isp1760_stop(struct usb_hcd *hcd) | |||
2021 | struct isp1760_hcd *priv = hcd_to_priv(hcd); | 2121 | struct isp1760_hcd *priv = hcd_to_priv(hcd); |
2022 | u32 temp; | 2122 | u32 temp; |
2023 | 2123 | ||
2124 | del_timer(&errata2_timer); | ||
2125 | |||
2024 | isp1760_hub_control(hcd, ClearPortFeature, USB_PORT_FEAT_POWER, 1, | 2126 | isp1760_hub_control(hcd, ClearPortFeature, USB_PORT_FEAT_POWER, 1, |
2025 | NULL, 0); | 2127 | NULL, 0); |
2026 | mdelay(20); | 2128 | mdelay(20); |
@@ -2048,6 +2150,23 @@ static void isp1760_shutdown(struct usb_hcd *hcd) | |||
2048 | reg_write32(hcd->regs, HC_USBCMD, command); | 2150 | reg_write32(hcd->regs, HC_USBCMD, command); |
2049 | } | 2151 | } |
2050 | 2152 | ||
2153 | static void isp1760_clear_tt_buffer_complete(struct usb_hcd *hcd, | ||
2154 | struct usb_host_endpoint *ep) | ||
2155 | { | ||
2156 | struct isp1760_hcd *priv = hcd_to_priv(hcd); | ||
2157 | struct isp1760_qh *qh = ep->hcpriv; | ||
2158 | unsigned long spinflags; | ||
2159 | |||
2160 | if (!qh) | ||
2161 | return; | ||
2162 | |||
2163 | spin_lock_irqsave(&priv->lock, spinflags); | ||
2164 | qh->tt_buffer_dirty = 0; | ||
2165 | schedule_ptds(hcd); | ||
2166 | spin_unlock_irqrestore(&priv->lock, spinflags); | ||
2167 | } | ||
2168 | |||
2169 | |||
2051 | static const struct hc_driver isp1760_hc_driver = { | 2170 | static const struct hc_driver isp1760_hc_driver = { |
2052 | .description = "isp1760-hcd", | 2171 | .description = "isp1760-hcd", |
2053 | .product_desc = "NXP ISP1760 USB Host Controller", | 2172 | .product_desc = "NXP ISP1760 USB Host Controller", |
@@ -2064,6 +2183,7 @@ static const struct hc_driver isp1760_hc_driver = { | |||
2064 | .get_frame_number = isp1760_get_frame, | 2183 | .get_frame_number = isp1760_get_frame, |
2065 | .hub_status_data = isp1760_hub_status_data, | 2184 | .hub_status_data = isp1760_hub_status_data, |
2066 | .hub_control = isp1760_hub_control, | 2185 | .hub_control = isp1760_hub_control, |
2186 | .clear_tt_buffer_complete = isp1760_clear_tt_buffer_complete, | ||
2067 | }; | 2187 | }; |
2068 | 2188 | ||
2069 | int __init init_kmem_once(void) | 2189 | int __init init_kmem_once(void) |
@@ -2102,6 +2222,7 @@ void deinit_kmem_cache(void) | |||
2102 | 2222 | ||
2103 | struct usb_hcd *isp1760_register(phys_addr_t res_start, resource_size_t res_len, | 2223 | struct usb_hcd *isp1760_register(phys_addr_t res_start, resource_size_t res_len, |
2104 | int irq, unsigned long irqflags, | 2224 | int irq, unsigned long irqflags, |
2225 | int rst_gpio, | ||
2105 | struct device *dev, const char *busname, | 2226 | struct device *dev, const char *busname, |
2106 | unsigned int devflags) | 2227 | unsigned int devflags) |
2107 | { | 2228 | { |
@@ -2121,6 +2242,7 @@ struct usb_hcd *isp1760_register(phys_addr_t res_start, resource_size_t res_len, | |||
2121 | 2242 | ||
2122 | priv = hcd_to_priv(hcd); | 2243 | priv = hcd_to_priv(hcd); |
2123 | priv->devflags = devflags; | 2244 | priv->devflags = devflags; |
2245 | priv->rst_gpio = rst_gpio; | ||
2124 | init_memory(priv); | 2246 | init_memory(priv); |
2125 | hcd->regs = ioremap(res_start, res_len); | 2247 | hcd->regs = ioremap(res_start, res_len); |
2126 | if (!hcd->regs) { | 2248 | if (!hcd->regs) { |