.. | .. |
---|
560 | 560 | ehci->command = temp; |
---|
561 | 561 | |
---|
562 | 562 | /* Accept arbitrarily long scatter-gather lists */ |
---|
563 | | - if (!(hcd->driver->flags & HCD_LOCAL_MEM)) |
---|
| 563 | + if (!hcd->localmem_pool) |
---|
564 | 564 | hcd->self.sg_tablesize = ~0; |
---|
565 | 565 | |
---|
566 | 566 | /* Prepare for unlinking active QHs */ |
---|
.. | .. |
---|
712 | 712 | static irqreturn_t ehci_irq (struct usb_hcd *hcd) |
---|
713 | 713 | { |
---|
714 | 714 | struct ehci_hcd *ehci = hcd_to_ehci (hcd); |
---|
715 | | - u32 status, masked_status, pcd_status = 0, cmd; |
---|
| 715 | + u32 status, current_status, masked_status, pcd_status = 0; |
---|
| 716 | + u32 cmd; |
---|
716 | 717 | int bh; |
---|
717 | 718 | unsigned long flags; |
---|
718 | 719 | |
---|
.. | .. |
---|
724 | 725 | */ |
---|
725 | 726 | spin_lock_irqsave(&ehci->lock, flags); |
---|
726 | 727 | |
---|
727 | | - status = ehci_readl(ehci, &ehci->regs->status); |
---|
| 728 | + status = 0; |
---|
| 729 | + current_status = ehci_readl(ehci, &ehci->regs->status); |
---|
| 730 | +restart: |
---|
728 | 731 | |
---|
729 | 732 | /* e.g. cardbus physical eject */ |
---|
730 | | - if (status == ~(u32) 0) { |
---|
| 733 | + if (current_status == ~(u32) 0) { |
---|
731 | 734 | ehci_dbg (ehci, "device removed\n"); |
---|
732 | 735 | goto dead; |
---|
733 | 736 | } |
---|
| 737 | + status |= current_status; |
---|
734 | 738 | |
---|
735 | 739 | /* |
---|
736 | 740 | * We don't use STS_FLR, but some controllers don't like it to |
---|
737 | 741 | * remain on, so mask it out along with the other status bits. |
---|
738 | 742 | */ |
---|
739 | | - masked_status = status & (INTR_MASK | STS_FLR); |
---|
| 743 | + masked_status = current_status & (INTR_MASK | STS_FLR); |
---|
740 | 744 | |
---|
741 | 745 | /* Shared IRQ? */ |
---|
742 | 746 | if (!masked_status || unlikely(ehci->rh_state == EHCI_RH_HALTED)) { |
---|
| 747 | + if (masked_status) |
---|
| 748 | + ehci_writel(ehci, masked_status, &ehci->regs->status); |
---|
743 | 749 | spin_unlock_irqrestore(&ehci->lock, flags); |
---|
744 | 750 | return IRQ_NONE; |
---|
745 | 751 | } |
---|
746 | 752 | |
---|
747 | 753 | /* clear (just) interrupts */ |
---|
748 | 754 | ehci_writel(ehci, masked_status, &ehci->regs->status); |
---|
| 755 | + |
---|
| 756 | + /* For edge interrupts, don't race with an interrupt bit being raised */ |
---|
| 757 | + current_status = ehci_readl(ehci, &ehci->regs->status); |
---|
| 758 | + if (current_status & INTR_MASK) |
---|
| 759 | + goto restart; |
---|
| 760 | + |
---|
749 | 761 | cmd = ehci_readl(ehci, &ehci->regs->command); |
---|
750 | 762 | bh = 0; |
---|
751 | 763 | |
---|
752 | 764 | /* normal [4.15.1.2] or error [4.15.1.1] completion */ |
---|
753 | 765 | if (likely ((status & (STS_INT|STS_ERR)) != 0)) { |
---|
754 | 766 | if (likely ((status & STS_ERR) == 0)) |
---|
755 | | - COUNT (ehci->stats.normal); |
---|
| 767 | + INCR(ehci->stats.normal); |
---|
756 | 768 | else |
---|
757 | | - COUNT (ehci->stats.error); |
---|
| 769 | + INCR(ehci->stats.error); |
---|
758 | 770 | bh = 1; |
---|
759 | 771 | } |
---|
760 | 772 | |
---|
.. | .. |
---|
778 | 790 | if (cmd & CMD_IAAD) |
---|
779 | 791 | ehci_dbg(ehci, "IAA with IAAD still set?\n"); |
---|
780 | 792 | if (ehci->iaa_in_progress) |
---|
781 | | - COUNT(ehci->stats.iaa); |
---|
| 793 | + INCR(ehci->stats.iaa); |
---|
782 | 794 | end_iaa_cycle(ehci); |
---|
783 | 795 | } |
---|
784 | 796 | |
---|
.. | .. |
---|
1004 | 1016 | start_unlink_async(ehci, qh); |
---|
1005 | 1017 | else |
---|
1006 | 1018 | start_unlink_intr(ehci, qh); |
---|
1007 | | - /* FALL THROUGH */ |
---|
| 1019 | + fallthrough; |
---|
1008 | 1020 | case QH_STATE_COMPLETING: /* already in unlinking */ |
---|
1009 | 1021 | case QH_STATE_UNLINK: /* wait for hw to finish? */ |
---|
1010 | 1022 | case QH_STATE_UNLINK_WAIT: |
---|
.. | .. |
---|
1021 | 1033 | qh_destroy(ehci, qh); |
---|
1022 | 1034 | break; |
---|
1023 | 1035 | } |
---|
1024 | | - /* fall through */ |
---|
| 1036 | + fallthrough; |
---|
1025 | 1037 | default: |
---|
1026 | 1038 | /* caller was supposed to have unlinked any requests; |
---|
1027 | 1039 | * that's not our job. just leak this memory. |
---|
.. | .. |
---|
1215 | 1227 | * generic hardware linkage |
---|
1216 | 1228 | */ |
---|
1217 | 1229 | .irq = ehci_irq, |
---|
1218 | | - .flags = HCD_MEMORY | HCD_USB2 | HCD_BH, |
---|
| 1230 | + .flags = HCD_MEMORY | HCD_DMA | HCD_USB2 | HCD_BH, |
---|
1219 | 1231 | |
---|
1220 | 1232 | /* |
---|
1221 | 1233 | * basic lifecycle operations |
---|
.. | .. |
---|
1306 | 1318 | #ifdef CONFIG_SPARC_LEON |
---|
1307 | 1319 | #include "ehci-grlib.c" |
---|
1308 | 1320 | #define PLATFORM_DRIVER ehci_grlib_driver |
---|
1309 | | -#endif |
---|
1310 | | - |
---|
1311 | | -#ifdef CONFIG_USB_EHCI_MV |
---|
1312 | | -#include "ehci-mv.c" |
---|
1313 | | -#define PLATFORM_DRIVER ehci_mv_driver |
---|
1314 | 1321 | #endif |
---|
1315 | 1322 | |
---|
1316 | 1323 | static int __init ehci_hcd_init(void) |
---|