| .. | .. |
|---|
| 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) |
|---|