.. | .. |
---|
16 | 16 | #include <linux/export.h> |
---|
17 | 17 | #include <linux/acpi.h> |
---|
18 | 18 | #include <linux/dmi.h> |
---|
| 19 | +#include <linux/of.h> |
---|
| 20 | +#include <linux/iopoll.h> |
---|
| 21 | + |
---|
19 | 22 | #include "pci-quirks.h" |
---|
20 | 23 | #include "xhci-ext-caps.h" |
---|
21 | 24 | |
---|
.. | .. |
---|
132 | 135 | struct amd_chipset_type sb_type; |
---|
133 | 136 | int isoc_reqs; |
---|
134 | 137 | int probe_count; |
---|
135 | | - int probe_result; |
---|
| 138 | + bool need_pll_quirk; |
---|
136 | 139 | } amd_chipset; |
---|
137 | 140 | |
---|
138 | 141 | static DEFINE_SPINLOCK(amd_lock); |
---|
.. | .. |
---|
201 | 204 | } |
---|
202 | 205 | EXPORT_SYMBOL_GPL(sb800_prefetch); |
---|
203 | 206 | |
---|
204 | | -int usb_amd_find_chipset_info(void) |
---|
| 207 | +static void usb_amd_find_chipset_info(void) |
---|
205 | 208 | { |
---|
206 | 209 | unsigned long flags; |
---|
207 | 210 | struct amd_chipset_info info; |
---|
208 | | - int need_pll_quirk = 0; |
---|
| 211 | + info.need_pll_quirk = false; |
---|
209 | 212 | |
---|
210 | 213 | spin_lock_irqsave(&amd_lock, flags); |
---|
211 | 214 | |
---|
.. | .. |
---|
213 | 216 | if (amd_chipset.probe_count > 0) { |
---|
214 | 217 | amd_chipset.probe_count++; |
---|
215 | 218 | spin_unlock_irqrestore(&amd_lock, flags); |
---|
216 | | - return amd_chipset.probe_result; |
---|
| 219 | + return; |
---|
217 | 220 | } |
---|
218 | 221 | memset(&info, 0, sizeof(info)); |
---|
219 | 222 | spin_unlock_irqrestore(&amd_lock, flags); |
---|
.. | .. |
---|
224 | 227 | |
---|
225 | 228 | switch (info.sb_type.gen) { |
---|
226 | 229 | case AMD_CHIPSET_SB700: |
---|
227 | | - need_pll_quirk = info.sb_type.rev <= 0x3B; |
---|
| 230 | + info.need_pll_quirk = info.sb_type.rev <= 0x3B; |
---|
228 | 231 | break; |
---|
229 | 232 | case AMD_CHIPSET_SB800: |
---|
230 | 233 | case AMD_CHIPSET_HUDSON2: |
---|
231 | 234 | case AMD_CHIPSET_BOLTON: |
---|
232 | | - need_pll_quirk = 1; |
---|
| 235 | + info.need_pll_quirk = true; |
---|
233 | 236 | break; |
---|
234 | 237 | default: |
---|
235 | | - need_pll_quirk = 0; |
---|
| 238 | + info.need_pll_quirk = false; |
---|
236 | 239 | break; |
---|
237 | 240 | } |
---|
238 | 241 | |
---|
239 | | - if (!need_pll_quirk) { |
---|
| 242 | + if (!info.need_pll_quirk) { |
---|
240 | 243 | if (info.smbus_dev) { |
---|
241 | 244 | pci_dev_put(info.smbus_dev); |
---|
242 | 245 | info.smbus_dev = NULL; |
---|
.. | .. |
---|
259 | 262 | } |
---|
260 | 263 | } |
---|
261 | 264 | |
---|
262 | | - need_pll_quirk = info.probe_result = 1; |
---|
263 | 265 | printk(KERN_DEBUG "QUIRK: Enable AMD PLL fix\n"); |
---|
264 | 266 | |
---|
265 | 267 | commit: |
---|
.. | .. |
---|
270 | 272 | |
---|
271 | 273 | /* Mark that we where here */ |
---|
272 | 274 | amd_chipset.probe_count++; |
---|
273 | | - need_pll_quirk = amd_chipset.probe_result; |
---|
274 | 275 | |
---|
275 | 276 | spin_unlock_irqrestore(&amd_lock, flags); |
---|
276 | 277 | |
---|
.. | .. |
---|
283 | 284 | amd_chipset = info; |
---|
284 | 285 | spin_unlock_irqrestore(&amd_lock, flags); |
---|
285 | 286 | } |
---|
286 | | - |
---|
287 | | - return need_pll_quirk; |
---|
288 | 287 | } |
---|
289 | | -EXPORT_SYMBOL_GPL(usb_amd_find_chipset_info); |
---|
290 | 288 | |
---|
291 | 289 | int usb_hcd_amd_remote_wakeup_quirk(struct pci_dev *pdev) |
---|
292 | 290 | { |
---|
.. | .. |
---|
321 | 319 | return amd_chipset.sb_type.gen == AMD_CHIPSET_SB800; |
---|
322 | 320 | } |
---|
323 | 321 | EXPORT_SYMBOL_GPL(usb_amd_prefetch_quirk); |
---|
| 322 | + |
---|
| 323 | +bool usb_amd_quirk_pll_check(void) |
---|
| 324 | +{ |
---|
| 325 | + usb_amd_find_chipset_info(); |
---|
| 326 | + return amd_chipset.need_pll_quirk; |
---|
| 327 | +} |
---|
| 328 | +EXPORT_SYMBOL_GPL(usb_amd_quirk_pll_check); |
---|
324 | 329 | |
---|
325 | 330 | /* |
---|
326 | 331 | * The hardware normally enables the A-link power management feature, which |
---|
.. | .. |
---|
527 | 532 | amd_chipset.nb_type = 0; |
---|
528 | 533 | memset(&amd_chipset.sb_type, 0, sizeof(amd_chipset.sb_type)); |
---|
529 | 534 | amd_chipset.isoc_reqs = 0; |
---|
530 | | - amd_chipset.probe_result = 0; |
---|
| 535 | + amd_chipset.need_pll_quirk = false; |
---|
531 | 536 | |
---|
532 | 537 | spin_unlock_irqrestore(&amd_lock, flags); |
---|
533 | 538 | |
---|
.. | .. |
---|
726 | 731 | if (!pio_enabled(pdev)) |
---|
727 | 732 | return; |
---|
728 | 733 | |
---|
729 | | - for (i = 0; i < PCI_ROM_RESOURCE; i++) |
---|
| 734 | + for (i = 0; i < PCI_STD_NUM_BARS; i++) |
---|
730 | 735 | if ((pci_resource_flags(pdev, i) & IORESOURCE_IO)) { |
---|
731 | 736 | base = pci_resource_start(pdev, i); |
---|
732 | 737 | break; |
---|
.. | .. |
---|
790 | 795 | /* disable interrupts */ |
---|
791 | 796 | writel((u32) ~0, base + OHCI_INTRDISABLE); |
---|
792 | 797 | |
---|
793 | | - /* Reset the USB bus, if the controller isn't already in RESET */ |
---|
794 | | - if (control & OHCI_HCFS) { |
---|
795 | | - /* Go into RESET, preserving RWC (and possibly IR) */ |
---|
796 | | - writel(control & OHCI_CTRL_MASK, base + OHCI_CONTROL); |
---|
797 | | - readl(base + OHCI_CONTROL); |
---|
798 | | - |
---|
799 | | - /* drive bus reset for at least 50 ms (7.1.7.5) */ |
---|
800 | | - msleep(50); |
---|
801 | | - } |
---|
| 798 | + /* Go into the USB_RESET state, preserving RWC (and possibly IR) */ |
---|
| 799 | + writel(control & OHCI_CTRL_MASK, base + OHCI_CONTROL); |
---|
| 800 | + readl(base + OHCI_CONTROL); |
---|
802 | 801 | |
---|
803 | 802 | /* software reset of the controller, preserving HcFmInterval */ |
---|
804 | 803 | if (!no_fminterval) |
---|
.. | .. |
---|
958 | 957 | ehci_bios_handoff(pdev, op_reg_base, cap, offset); |
---|
959 | 958 | break; |
---|
960 | 959 | case 0: /* Illegal reserved cap, set cap=0 so we exit */ |
---|
961 | | - cap = 0; /* fall through */ |
---|
| 960 | + cap = 0; |
---|
| 961 | + fallthrough; |
---|
962 | 962 | default: |
---|
963 | 963 | dev_warn(&pdev->dev, |
---|
964 | 964 | "EHCI: unrecognized capability %02x\n", |
---|
.. | .. |
---|
1013 | 1013 | { |
---|
1014 | 1014 | u32 result; |
---|
1015 | 1015 | |
---|
1016 | | - do { |
---|
1017 | | - result = readl(ptr); |
---|
1018 | | - result &= mask; |
---|
1019 | | - if (result == done) |
---|
1020 | | - return 0; |
---|
1021 | | - udelay(delay_usec); |
---|
1022 | | - wait_usec -= delay_usec; |
---|
1023 | | - } while (wait_usec > 0); |
---|
1024 | | - return -ETIMEDOUT; |
---|
| 1016 | + return readl_poll_timeout_atomic(ptr, result, |
---|
| 1017 | + ((result & mask) == done), |
---|
| 1018 | + delay_usec, wait_usec); |
---|
1025 | 1019 | } |
---|
1026 | 1020 | |
---|
1027 | 1021 | /* |
---|
.. | .. |
---|
1134 | 1128 | } |
---|
1135 | 1129 | EXPORT_SYMBOL_GPL(usb_disable_xhci_ports); |
---|
1136 | 1130 | |
---|
1137 | | -/** |
---|
| 1131 | +/* |
---|
1138 | 1132 | * PCI Quirks for xHCI. |
---|
1139 | 1133 | * |
---|
1140 | 1134 | * Takes care of the handoff between the Pre-OS (i.e. BIOS) and the OS. |
---|
.. | .. |
---|
1154 | 1148 | if (!mmio_resource_enabled(pdev, 0)) |
---|
1155 | 1149 | return; |
---|
1156 | 1150 | |
---|
1157 | | - base = ioremap_nocache(pci_resource_start(pdev, 0), len); |
---|
| 1151 | + base = ioremap(pci_resource_start(pdev, 0), len); |
---|
1158 | 1152 | if (base == NULL) |
---|
1159 | 1153 | return; |
---|
1160 | 1154 | |
---|
.. | .. |
---|
1247 | 1241 | |
---|
1248 | 1242 | static void quirk_usb_early_handoff(struct pci_dev *pdev) |
---|
1249 | 1243 | { |
---|
| 1244 | + struct device_node *parent; |
---|
| 1245 | + bool is_rpi; |
---|
| 1246 | + |
---|
1250 | 1247 | /* Skip Netlogic mips SoC's internal PCI USB controller. |
---|
1251 | 1248 | * This device does not need/support EHCI/OHCI handoff |
---|
1252 | 1249 | */ |
---|
1253 | 1250 | if (pdev->vendor == 0x184e) /* vendor Netlogic */ |
---|
1254 | 1251 | return; |
---|
| 1252 | + |
---|
| 1253 | + /* |
---|
| 1254 | + * Bypass the Raspberry Pi 4 controller xHCI controller, things are |
---|
| 1255 | + * taken care of by the board's co-processor. |
---|
| 1256 | + */ |
---|
| 1257 | + if (pdev->vendor == PCI_VENDOR_ID_VIA && pdev->device == 0x3483) { |
---|
| 1258 | + parent = of_get_parent(pdev->bus->dev.of_node); |
---|
| 1259 | + is_rpi = of_device_is_compatible(parent, "brcm,bcm2711-pcie"); |
---|
| 1260 | + of_node_put(parent); |
---|
| 1261 | + if (is_rpi) |
---|
| 1262 | + return; |
---|
| 1263 | + } |
---|
| 1264 | + |
---|
1255 | 1265 | if (pdev->class != PCI_CLASS_SERIAL_USB_UHCI && |
---|
1256 | 1266 | pdev->class != PCI_CLASS_SERIAL_USB_OHCI && |
---|
1257 | 1267 | pdev->class != PCI_CLASS_SERIAL_USB_EHCI && |
---|