mirror of
				git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
				synced 2025-10-31 16:54:21 +00:00 
			
		
		
		
	usb: dwc3: core: re-factor init and exit paths
The idea of this patch is for dwc3_core_init() to abstract all the details about how to initialize dwc3 and dwc3_core_exit() to do the same for teardown. With this, we can simplify suspend/resume operations by a large margin and always know that we're going to start dwc3 from a known starting point. Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
This commit is contained in:
		
							parent
							
								
									bcdb3272e8
								
							
						
					
					
						commit
						c499ff71ff
					
				
					 1 changed files with 60 additions and 58 deletions
				
			
		|  | @ -506,6 +506,21 @@ static int dwc3_phy_setup(struct dwc3 *dwc) | |||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| static void dwc3_core_exit(struct dwc3 *dwc) | ||||
| { | ||||
| 	dwc3_event_buffers_cleanup(dwc); | ||||
| 
 | ||||
| 	usb_phy_shutdown(dwc->usb2_phy); | ||||
| 	usb_phy_shutdown(dwc->usb3_phy); | ||||
| 	phy_exit(dwc->usb2_generic_phy); | ||||
| 	phy_exit(dwc->usb3_generic_phy); | ||||
| 
 | ||||
| 	usb_phy_set_suspend(dwc->usb2_phy, 1); | ||||
| 	usb_phy_set_suspend(dwc->usb3_phy, 1); | ||||
| 	phy_power_off(dwc->usb2_generic_phy); | ||||
| 	phy_power_off(dwc->usb3_generic_phy); | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  * dwc3_core_init - Low-level initialization of DWC3 Core | ||||
|  * @dwc: Pointer to our controller context structure | ||||
|  | @ -555,6 +570,10 @@ static int dwc3_core_init(struct dwc3 *dwc) | |||
| 	if (ret) | ||||
| 		goto err0; | ||||
| 
 | ||||
| 	ret = dwc3_phy_setup(dwc); | ||||
| 	if (ret) | ||||
| 		goto err0; | ||||
| 
 | ||||
| 	reg = dwc3_readl(dwc->regs, DWC3_GCTL); | ||||
| 	reg &= ~DWC3_GCTL_SCALEDOWN_MASK; | ||||
| 
 | ||||
|  | @ -621,22 +640,45 @@ static int dwc3_core_init(struct dwc3 *dwc) | |||
| 	if (dwc->revision < DWC3_REVISION_190A) | ||||
| 		reg |= DWC3_GCTL_U2RSTECN; | ||||
| 
 | ||||
| 	dwc3_core_num_eps(dwc); | ||||
| 
 | ||||
| 	dwc3_writel(dwc->regs, DWC3_GCTL, reg); | ||||
| 
 | ||||
| 	ret = dwc3_alloc_scratch_buffers(dwc); | ||||
| 	if (ret) | ||||
| 		goto err1; | ||||
| 	dwc3_core_num_eps(dwc); | ||||
| 
 | ||||
| 	ret = dwc3_setup_scratch_buffers(dwc); | ||||
| 	if (ret) | ||||
| 		goto err1; | ||||
| 
 | ||||
| 	/* Adjust Frame Length */ | ||||
| 	dwc3_frame_length_adjustment(dwc); | ||||
| 
 | ||||
| 	usb_phy_set_suspend(dwc->usb2_phy, 0); | ||||
| 	usb_phy_set_suspend(dwc->usb3_phy, 0); | ||||
| 	ret = phy_power_on(dwc->usb2_generic_phy); | ||||
| 	if (ret < 0) | ||||
| 		goto err2; | ||||
| 
 | ||||
| 	ret = phy_power_on(dwc->usb3_generic_phy); | ||||
| 	if (ret < 0) | ||||
| 		goto err3; | ||||
| 
 | ||||
| 	ret = dwc3_event_buffers_setup(dwc); | ||||
| 	if (ret) { | ||||
| 		dev_err(dwc->dev, "failed to setup event buffers\n"); | ||||
| 		goto err4; | ||||
| 	} | ||||
| 
 | ||||
| 	return 0; | ||||
| 
 | ||||
| err4: | ||||
| 	phy_power_off(dwc->usb2_generic_phy); | ||||
| 
 | ||||
| err3: | ||||
| 	phy_power_off(dwc->usb3_generic_phy); | ||||
| 
 | ||||
| err2: | ||||
| 	dwc3_free_scratch_buffers(dwc); | ||||
| 	usb_phy_set_suspend(dwc->usb2_phy, 1); | ||||
| 	usb_phy_set_suspend(dwc->usb3_phy, 1); | ||||
| 	dwc3_core_exit(dwc); | ||||
| 
 | ||||
| err1: | ||||
| 	usb_phy_shutdown(dwc->usb2_phy); | ||||
|  | @ -648,15 +690,6 @@ err0: | |||
| 	return ret; | ||||
| } | ||||
| 
 | ||||
| static void dwc3_core_exit(struct dwc3 *dwc) | ||||
| { | ||||
| 	dwc3_free_scratch_buffers(dwc); | ||||
| 	usb_phy_shutdown(dwc->usb2_phy); | ||||
| 	usb_phy_shutdown(dwc->usb3_phy); | ||||
| 	phy_exit(dwc->usb2_generic_phy); | ||||
| 	phy_exit(dwc->usb3_generic_phy); | ||||
| } | ||||
| 
 | ||||
| static int dwc3_core_get_phy(struct dwc3 *dwc) | ||||
| { | ||||
| 	struct device		*dev = dwc->dev; | ||||
|  | @ -951,10 +984,6 @@ static int dwc3_probe(struct platform_device *pdev) | |||
| 	platform_set_drvdata(pdev, dwc); | ||||
| 	dwc3_cache_hwparams(dwc); | ||||
| 
 | ||||
| 	ret = dwc3_phy_setup(dwc); | ||||
| 	if (ret) | ||||
| 		goto err0; | ||||
| 
 | ||||
| 	ret = dwc3_core_get_phy(dwc); | ||||
| 	if (ret) | ||||
| 		goto err0; | ||||
|  | @ -975,7 +1004,7 @@ static int dwc3_probe(struct platform_device *pdev) | |||
| 	if (ret) { | ||||
| 		dev_err(dwc->dev, "failed to allocate event buffers\n"); | ||||
| 		ret = -ENOMEM; | ||||
| 		goto err1; | ||||
| 		goto err0; | ||||
| 	} | ||||
| 
 | ||||
| 	if (IS_ENABLED(CONFIG_USB_DWC3_HOST)) | ||||
|  | @ -986,10 +1015,14 @@ static int dwc3_probe(struct platform_device *pdev) | |||
| 	if (dwc->dr_mode == USB_DR_MODE_UNKNOWN) | ||||
| 		dwc->dr_mode = USB_DR_MODE_OTG; | ||||
| 
 | ||||
| 	ret = dwc3_alloc_scratch_buffers(dwc); | ||||
| 	if (ret) | ||||
| 		goto err1; | ||||
| 
 | ||||
| 	ret = dwc3_core_init(dwc); | ||||
| 	if (ret) { | ||||
| 		dev_err(dev, "failed to initialize core\n"); | ||||
| 		goto err1; | ||||
| 		goto err2; | ||||
| 	} | ||||
| 
 | ||||
| 	/* Check the maximum_speed parameter */ | ||||
|  | @ -1019,47 +1052,20 @@ static int dwc3_probe(struct platform_device *pdev) | |||
| 		break; | ||||
| 	} | ||||
| 
 | ||||
| 	/* Adjust Frame Length */ | ||||
| 	dwc3_frame_length_adjustment(dwc); | ||||
| 
 | ||||
| 	usb_phy_set_suspend(dwc->usb2_phy, 0); | ||||
| 	usb_phy_set_suspend(dwc->usb3_phy, 0); | ||||
| 	ret = phy_power_on(dwc->usb2_generic_phy); | ||||
| 	if (ret < 0) | ||||
| 		goto err2; | ||||
| 
 | ||||
| 	ret = phy_power_on(dwc->usb3_generic_phy); | ||||
| 	if (ret < 0) | ||||
| 		goto err3; | ||||
| 
 | ||||
| 	ret = dwc3_event_buffers_setup(dwc); | ||||
| 	if (ret) { | ||||
| 		dev_err(dwc->dev, "failed to setup event buffers\n"); | ||||
| 		goto err4; | ||||
| 	} | ||||
| 
 | ||||
| 	ret = dwc3_core_init_mode(dwc); | ||||
| 	if (ret) | ||||
| 		goto err5; | ||||
| 		goto err3; | ||||
| 
 | ||||
| 	dwc3_debugfs_init(dwc); | ||||
| 	pm_runtime_allow(dev); | ||||
| 
 | ||||
| 	return 0; | ||||
| 
 | ||||
| err5: | ||||
| err3: | ||||
| 	dwc3_event_buffers_cleanup(dwc); | ||||
| 
 | ||||
| err4: | ||||
| 	phy_power_off(dwc->usb3_generic_phy); | ||||
| 
 | ||||
| err3: | ||||
| 	phy_power_off(dwc->usb2_generic_phy); | ||||
| 
 | ||||
| err2: | ||||
| 	usb_phy_set_suspend(dwc->usb2_phy, 1); | ||||
| 	usb_phy_set_suspend(dwc->usb3_phy, 1); | ||||
| 	dwc3_core_exit(dwc); | ||||
| 	dwc3_free_scratch_buffers(dwc); | ||||
| 
 | ||||
| err1: | ||||
| 	dwc3_free_event_buffers(dwc); | ||||
|  | @ -1090,17 +1096,13 @@ static int dwc3_remove(struct platform_device *pdev) | |||
| 
 | ||||
| 	dwc3_debugfs_exit(dwc); | ||||
| 	dwc3_core_exit_mode(dwc); | ||||
| 	dwc3_event_buffers_cleanup(dwc); | ||||
| 	dwc3_free_event_buffers(dwc); | ||||
| 
 | ||||
| 	usb_phy_set_suspend(dwc->usb2_phy, 1); | ||||
| 	usb_phy_set_suspend(dwc->usb3_phy, 1); | ||||
| 	phy_power_off(dwc->usb2_generic_phy); | ||||
| 	phy_power_off(dwc->usb3_generic_phy); | ||||
| 
 | ||||
| 	dwc3_core_exit(dwc); | ||||
| 	dwc3_ulpi_exit(dwc); | ||||
| 
 | ||||
| 	dwc3_free_event_buffers(dwc); | ||||
| 	dwc3_free_scratch_buffers(dwc); | ||||
| 
 | ||||
| 	pm_runtime_put_sync(&pdev->dev); | ||||
| 	pm_runtime_disable(&pdev->dev); | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
	Add table
		
		Reference in a new issue
	
	 Felipe Balbi
						Felipe Balbi