|
@@ -3019,7 +3019,8 @@ static struct usb_host_operations xhci_operations = {
|
3019
|
3019
|
* @v xhci xHCI device
|
3020
|
3020
|
* @v pci PCI device
|
3021
|
3021
|
*/
|
3022
|
|
-static void xhci_pch ( struct xhci_device *xhci, struct pci_device *pci ) {
|
|
3022
|
+static void xhci_pch_fix ( struct xhci_device *xhci, struct pci_device *pci ) {
|
|
3023
|
+ struct xhci_pch *pch = &xhci->pch;
|
3023
|
3024
|
uint32_t xusb2pr;
|
3024
|
3025
|
uint32_t xusb2prm;
|
3025
|
3026
|
uint32_t usb3pssen;
|
|
@@ -3034,6 +3035,7 @@ static void xhci_pch ( struct xhci_device *xhci, struct pci_device *pci ) {
|
3034
|
3035
|
DBGC ( xhci, "XHCI %p enabling SuperSpeed on ports %08x\n",
|
3035
|
3036
|
xhci, ( usb3prm & ~usb3pssen ) );
|
3036
|
3037
|
}
|
|
3038
|
+ pch->usb3pssen = usb3pssen;
|
3037
|
3039
|
usb3pssen |= usb3prm;
|
3038
|
3040
|
pci_write_config_dword ( pci, XHCI_PCH_USB3PSSEN, usb3pssen );
|
3039
|
3041
|
|
|
@@ -3044,10 +3046,27 @@ static void xhci_pch ( struct xhci_device *xhci, struct pci_device *pci ) {
|
3044
|
3046
|
DBGC ( xhci, "XHCI %p routing ports %08x from EHCI to xHCI\n",
|
3045
|
3047
|
xhci, ( xusb2prm & ~xusb2pr ) );
|
3046
|
3048
|
}
|
|
3049
|
+ pch->xusb2pr = xusb2pr;
|
3047
|
3050
|
xusb2pr |= xusb2prm;
|
3048
|
3051
|
pci_write_config_dword ( pci, XHCI_PCH_XUSB2PR, xusb2pr );
|
3049
|
3052
|
}
|
3050
|
3053
|
|
|
3054
|
+/**
|
|
3055
|
+ * Undo Intel PCH-specific quirk fixes
|
|
3056
|
+ *
|
|
3057
|
+ * @v xhci xHCI device
|
|
3058
|
+ * @v pci PCI device
|
|
3059
|
+ */
|
|
3060
|
+static void xhci_pch_undo ( struct xhci_device *xhci, struct pci_device *pci ) {
|
|
3061
|
+ struct xhci_pch *pch = &xhci->pch;
|
|
3062
|
+
|
|
3063
|
+ /* Restore USB2 port routing to original state */
|
|
3064
|
+ pci_write_config_dword ( pci, XHCI_PCH_XUSB2PR, pch->xusb2pr );
|
|
3065
|
+
|
|
3066
|
+ /* Restore SuperSpeed capability to original state */
|
|
3067
|
+ pci_write_config_dword ( pci, XHCI_PCH_USB3PSSEN, pch->usb3pssen );
|
|
3068
|
+}
|
|
3069
|
+
|
3051
|
3070
|
/**
|
3052
|
3071
|
* Probe PCI device
|
3053
|
3072
|
*
|
|
@@ -3091,7 +3110,7 @@ static int xhci_probe ( struct pci_device *pci ) {
|
3091
|
3110
|
|
3092
|
3111
|
/* Fix Intel PCH-specific quirks, if applicable */
|
3093
|
3112
|
if ( pci->id->driver_data & XHCI_PCH )
|
3094
|
|
- xhci_pch ( xhci, pci );
|
|
3113
|
+ xhci_pch_fix ( xhci, pci );
|
3095
|
3114
|
|
3096
|
3115
|
/* Reset device */
|
3097
|
3116
|
if ( ( rc = xhci_reset ( xhci ) ) != 0 )
|
|
@@ -3126,6 +3145,8 @@ static int xhci_probe ( struct pci_device *pci ) {
|
3126
|
3145
|
err_alloc_bus:
|
3127
|
3146
|
xhci_reset ( xhci );
|
3128
|
3147
|
err_reset:
|
|
3148
|
+ if ( pci->id->driver_data & XHCI_PCH )
|
|
3149
|
+ xhci_pch_undo ( xhci, pci );
|
3129
|
3150
|
xhci_legacy_release ( xhci );
|
3130
|
3151
|
err_legacy_claim:
|
3131
|
3152
|
iounmap ( xhci->regs );
|
|
@@ -3147,6 +3168,8 @@ static void xhci_remove ( struct pci_device *pci ) {
|
3147
|
3168
|
unregister_usb_bus ( bus );
|
3148
|
3169
|
free_usb_bus ( bus );
|
3149
|
3170
|
xhci_reset ( xhci );
|
|
3171
|
+ if ( pci->id->driver_data & XHCI_PCH )
|
|
3172
|
+ xhci_pch_undo ( xhci, pci );
|
3150
|
3173
|
xhci_legacy_release ( xhci );
|
3151
|
3174
|
iounmap ( xhci->regs );
|
3152
|
3175
|
free ( xhci );
|