forked from mirrors/linux
		
	usb: cdns3: add quirk for enable runtime pm by default
Some vendors (eg: NXP) may want to enable runtime pm by default for power saving, add one quirk for it. Reviewed-by: Jun Li <jun.li@nxp.com> Signed-off-by: Peter Chen <peter.chen@nxp.com>
This commit is contained in:
		
							parent
							
								
									1cc6edd8a9
								
							
						
					
					
						commit
						7cea965775
					
				
					 3 changed files with 23 additions and 4 deletions
				
			
		|  | @ -559,7 +559,8 @@ static int cdns3_probe(struct platform_device *pdev) | ||||||
| 	device_set_wakeup_capable(dev, true); | 	device_set_wakeup_capable(dev, true); | ||||||
| 	pm_runtime_set_active(dev); | 	pm_runtime_set_active(dev); | ||||||
| 	pm_runtime_enable(dev); | 	pm_runtime_enable(dev); | ||||||
| 	pm_runtime_forbid(dev); | 	if (!(cdns->pdata->quirks & CDNS3_DEFAULT_PM_RUNTIME_ALLOW)) | ||||||
|  | 		pm_runtime_forbid(dev); | ||||||
| 
 | 
 | ||||||
| 	/*
 | 	/*
 | ||||||
| 	 * The controller needs less time between bus and controller suspend, | 	 * The controller needs less time between bus and controller suspend, | ||||||
|  |  | ||||||
|  | @ -42,6 +42,8 @@ struct cdns3_role_driver { | ||||||
| struct cdns3_platform_data { | struct cdns3_platform_data { | ||||||
| 	int (*platform_suspend)(struct device *dev, | 	int (*platform_suspend)(struct device *dev, | ||||||
| 			bool suspend, bool wakeup); | 			bool suspend, bool wakeup); | ||||||
|  | 	unsigned long quirks; | ||||||
|  | #define CDNS3_DEFAULT_PM_RUNTIME_ALLOW	BIT(0) | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| /**
 | /**
 | ||||||
|  | @ -73,6 +75,7 @@ struct cdns3_platform_data { | ||||||
|  * @wakeup_pending: wakeup interrupt pending |  * @wakeup_pending: wakeup interrupt pending | ||||||
|  * @pdata: platform data from glue layer |  * @pdata: platform data from glue layer | ||||||
|  * @lock: spinlock structure |  * @lock: spinlock structure | ||||||
|  |  * @xhci_plat_data: xhci private data structure pointer | ||||||
|  */ |  */ | ||||||
| struct cdns3 { | struct cdns3 { | ||||||
| 	struct device			*dev; | 	struct device			*dev; | ||||||
|  | @ -106,6 +109,7 @@ struct cdns3 { | ||||||
| 	bool				wakeup_pending; | 	bool				wakeup_pending; | ||||||
| 	struct cdns3_platform_data	*pdata; | 	struct cdns3_platform_data	*pdata; | ||||||
| 	spinlock_t			lock; | 	spinlock_t			lock; | ||||||
|  | 	struct xhci_plat_priv		*xhci_plat_data; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| int cdns3_hw_role_switch(struct cdns3 *cdns); | int cdns3_hw_role_switch(struct cdns3 *cdns); | ||||||
|  |  | ||||||
|  | @ -52,15 +52,25 @@ static int __cdns3_host_init(struct cdns3 *cdns) | ||||||
| 		goto err1; | 		goto err1; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	ret = platform_device_add_data(xhci, &xhci_plat_cdns3_xhci, | 	cdns->xhci_plat_data = kmemdup(&xhci_plat_cdns3_xhci, | ||||||
|  | 			sizeof(struct xhci_plat_priv), GFP_KERNEL); | ||||||
|  | 	if (!cdns->xhci_plat_data) { | ||||||
|  | 		ret = -ENOMEM; | ||||||
|  | 		goto err1; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if (cdns->pdata->quirks & CDNS3_DEFAULT_PM_RUNTIME_ALLOW) | ||||||
|  | 		cdns->xhci_plat_data->quirks |= XHCI_DEFAULT_PM_RUNTIME_ALLOW; | ||||||
|  | 
 | ||||||
|  | 	ret = platform_device_add_data(xhci, cdns->xhci_plat_data, | ||||||
| 			sizeof(struct xhci_plat_priv)); | 			sizeof(struct xhci_plat_priv)); | ||||||
| 	if (ret) | 	if (ret) | ||||||
| 		goto err1; | 		goto free_memory; | ||||||
| 
 | 
 | ||||||
| 	ret = platform_device_add(xhci); | 	ret = platform_device_add(xhci); | ||||||
| 	if (ret) { | 	if (ret) { | ||||||
| 		dev_err(cdns->dev, "failed to register xHCI device\n"); | 		dev_err(cdns->dev, "failed to register xHCI device\n"); | ||||||
| 		goto err1; | 		goto free_memory; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	/* Glue needs to access xHCI region register for Power management */ | 	/* Glue needs to access xHCI region register for Power management */ | ||||||
|  | @ -69,6 +79,9 @@ static int __cdns3_host_init(struct cdns3 *cdns) | ||||||
| 		cdns->xhci_regs = hcd->regs; | 		cdns->xhci_regs = hcd->regs; | ||||||
| 
 | 
 | ||||||
| 	return 0; | 	return 0; | ||||||
|  | 
 | ||||||
|  | free_memory: | ||||||
|  | 	kfree(cdns->xhci_plat_data); | ||||||
| err1: | err1: | ||||||
| 	platform_device_put(xhci); | 	platform_device_put(xhci); | ||||||
| 	return ret; | 	return ret; | ||||||
|  | @ -102,6 +115,7 @@ int xhci_cdns3_suspend_quirk(struct usb_hcd *hcd) | ||||||
| 
 | 
 | ||||||
| static void cdns3_host_exit(struct cdns3 *cdns) | static void cdns3_host_exit(struct cdns3 *cdns) | ||||||
| { | { | ||||||
|  | 	kfree(cdns->xhci_plat_data); | ||||||
| 	platform_device_unregister(cdns->host_dev); | 	platform_device_unregister(cdns->host_dev); | ||||||
| 	cdns->host_dev = NULL; | 	cdns->host_dev = NULL; | ||||||
| 	cdns3_drd_host_off(cdns); | 	cdns3_drd_host_off(cdns); | ||||||
|  |  | ||||||
		Loading…
	
		Reference in a new issue
	
	 Peter Chen
						Peter Chen