mirror of
				https://xff.cz/git/u-boot/
				synced 2025-10-31 02:15:45 +01:00 
			
		
		
		
	usb: xhci: Add reset controller support
Some atypical users of xhci might need to manually reset their xHCI controller before starting the HCD setup. Check if a reset controller device is available to the PCI bus and trigger a reset. Signed-off-by: Nicolas Saenz Julienne <nsaenzjulienne@suse.de> [mb: squash fix to only build xhci_reset_hw() if CONFIG_DM_BUS] Signed-off-by: Matthias Brugger <mbrugger@suse.com>
This commit is contained in:
		
				
					committed by
					
						 Matthias Brugger
						Matthias Brugger
					
				
			
			
				
	
			
			
			
						parent
						
							6836d59094
						
					
				
				
					commit
					0b80371b35
				
			| @@ -180,6 +180,8 @@ void xhci_cleanup(struct xhci_ctrl *ctrl) | |||||||
| 	xhci_free_virt_devices(ctrl); | 	xhci_free_virt_devices(ctrl); | ||||||
| 	free(ctrl->erst.entries); | 	free(ctrl->erst.entries); | ||||||
| 	free(ctrl->dcbaa); | 	free(ctrl->dcbaa); | ||||||
|  | 	if (reset_valid(&ctrl->reset)) | ||||||
|  | 		reset_free(&ctrl->reset); | ||||||
| 	memset(ctrl, '\0', sizeof(struct xhci_ctrl)); | 	memset(ctrl, '\0', sizeof(struct xhci_ctrl)); | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -190,6 +190,37 @@ static int xhci_start(struct xhci_hcor *hcor) | |||||||
| 	return ret; | 	return ret; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | #if CONFIG_IS_ENABLED(DM_USB) | ||||||
|  | /** | ||||||
|  |  * Resets XHCI Hardware | ||||||
|  |  * | ||||||
|  |  * @param ctrl	pointer to host controller | ||||||
|  |  * @return 0 if OK, or a negative error code. | ||||||
|  |  */ | ||||||
|  | static int xhci_reset_hw(struct xhci_ctrl *ctrl) | ||||||
|  | { | ||||||
|  | 	int ret; | ||||||
|  |  | ||||||
|  | 	ret = reset_get_by_index(ctrl->dev, 0, &ctrl->reset); | ||||||
|  | 	if (ret && ret != -ENOENT && ret != -ENOTSUPP) { | ||||||
|  | 		dev_err(ctrl->dev, "failed to get reset\n"); | ||||||
|  | 		return ret; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if (reset_valid(&ctrl->reset)) { | ||||||
|  | 		ret = reset_assert(&ctrl->reset); | ||||||
|  | 		if (ret) | ||||||
|  | 			return ret; | ||||||
|  |  | ||||||
|  | 		ret = reset_deassert(&ctrl->reset); | ||||||
|  | 		if (ret) | ||||||
|  | 			return ret; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	return 0; | ||||||
|  | } | ||||||
|  | #endif | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * Resets the XHCI Controller |  * Resets the XHCI Controller | ||||||
|  * |  * | ||||||
| @@ -1508,6 +1539,10 @@ int xhci_register(struct udevice *dev, struct xhci_hccr *hccr, | |||||||
|  |  | ||||||
| 	ctrl->dev = dev; | 	ctrl->dev = dev; | ||||||
|  |  | ||||||
|  | 	ret = xhci_reset_hw(ctrl); | ||||||
|  | 	if (ret) | ||||||
|  | 		goto err; | ||||||
|  |  | ||||||
| 	/* | 	/* | ||||||
| 	 * XHCI needs to issue a Address device command to setup | 	 * XHCI needs to issue a Address device command to setup | ||||||
| 	 * proper device context structures, before it can interact | 	 * proper device context structures, before it can interact | ||||||
|   | |||||||
| @@ -16,6 +16,7 @@ | |||||||
| #ifndef HOST_XHCI_H_ | #ifndef HOST_XHCI_H_ | ||||||
| #define HOST_XHCI_H_ | #define HOST_XHCI_H_ | ||||||
|  |  | ||||||
|  | #include <reset.h> | ||||||
| #include <asm/types.h> | #include <asm/types.h> | ||||||
| #include <asm/cache.h> | #include <asm/cache.h> | ||||||
| #include <asm/io.h> | #include <asm/io.h> | ||||||
| @@ -1209,6 +1210,7 @@ struct xhci_ctrl { | |||||||
| #if CONFIG_IS_ENABLED(DM_USB) | #if CONFIG_IS_ENABLED(DM_USB) | ||||||
| 	struct udevice *dev; | 	struct udevice *dev; | ||||||
| #endif | #endif | ||||||
|  | 	struct reset_ctl reset; | ||||||
| 	struct xhci_hccr *hccr;	/* R/O registers, not need for volatile */ | 	struct xhci_hccr *hccr;	/* R/O registers, not need for volatile */ | ||||||
| 	struct xhci_hcor *hcor; | 	struct xhci_hcor *hcor; | ||||||
| 	struct xhci_doorbell_array *dba; | 	struct xhci_doorbell_array *dba; | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user