dwc3: move phy operation to core.c
Those operations can be used for peripheral operation as well as host operation. Signed-off-by: Jean-Jacques Hiblot <jjhiblot@ti.com> # Conflicts: # drivers/usb/dwc3/core.c # drivers/usb/host/xhci-dwc3.c
This commit is contained in:
		
							parent
							
								
									20bebd8666
								
							
						
					
					
						commit
						d648a50c0a
					
				|  | @ -19,7 +19,7 @@ | ||||||
| #include <asm/dma-mapping.h> | #include <asm/dma-mapping.h> | ||||||
| #include <linux/ioport.h> | #include <linux/ioport.h> | ||||||
| #include <dm.h> | #include <dm.h> | ||||||
| 
 | #include <generic-phy.h> | ||||||
| #include <linux/usb/ch9.h> | #include <linux/usb/ch9.h> | ||||||
| #include <linux/usb/gadget.h> | #include <linux/usb/gadget.h> | ||||||
| 
 | 
 | ||||||
|  | @ -789,6 +789,91 @@ MODULE_AUTHOR("Felipe Balbi <balbi@ti.com>"); | ||||||
| MODULE_LICENSE("GPL v2"); | MODULE_LICENSE("GPL v2"); | ||||||
| MODULE_DESCRIPTION("DesignWare USB3 DRD Controller Driver"); | MODULE_DESCRIPTION("DesignWare USB3 DRD Controller Driver"); | ||||||
| 
 | 
 | ||||||
|  | #if CONFIG_IS_ENABLED(PHY) && CONFIG_IS_ENABLED(DM_USB) | ||||||
|  | int dwc3_setup_phy(struct udevice *dev, struct phy **array, int *num_phys) | ||||||
|  | { | ||||||
|  | 	int i, ret, count; | ||||||
|  | 	struct phy *usb_phys; | ||||||
|  | 
 | ||||||
|  | 	/* Return if no phy declared */ | ||||||
|  | 	if (!dev_read_prop(dev, "phys", NULL)) | ||||||
|  | 		return 0; | ||||||
|  | 	count = dev_count_phandle_with_args(dev, "phys", "#phy-cells"); | ||||||
|  | 	if (count <= 0) | ||||||
|  | 		return count; | ||||||
|  | 
 | ||||||
|  | 	usb_phys = devm_kcalloc(dev, count, sizeof(struct phy), | ||||||
|  | 				GFP_KERNEL); | ||||||
|  | 	if (!usb_phys) | ||||||
|  | 		return -ENOMEM; | ||||||
|  | 
 | ||||||
|  | 	for (i = 0; i < count; i++) { | ||||||
|  | 		ret = generic_phy_get_by_index(dev, i, &usb_phys[i]); | ||||||
|  | 		if (ret && ret != -ENOENT) { | ||||||
|  | 			pr_err("Failed to get USB PHY%d for %s\n", | ||||||
|  | 			       i, dev->name); | ||||||
|  | 			return ret; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	for (i = 0; i < count; i++) { | ||||||
|  | 		ret = generic_phy_init(&usb_phys[i]); | ||||||
|  | 		if (ret) { | ||||||
|  | 			pr_err("Can't init USB PHY%d for %s\n", | ||||||
|  | 			       i, dev->name); | ||||||
|  | 			goto phys_init_err; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	for (i = 0; i < count; i++) { | ||||||
|  | 		ret = generic_phy_power_on(&usb_phys[i]); | ||||||
|  | 		if (ret) { | ||||||
|  | 			pr_err("Can't power USB PHY%d for %s\n", | ||||||
|  | 			       i, dev->name); | ||||||
|  | 			goto phys_poweron_err; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	*array = usb_phys; | ||||||
|  | 	*num_phys =  count; | ||||||
|  | 	return 0; | ||||||
|  | 
 | ||||||
|  | phys_poweron_err: | ||||||
|  | 	for (i = count - 1; i >= 0; i--) | ||||||
|  | 		generic_phy_power_off(&usb_phys[i]); | ||||||
|  | 
 | ||||||
|  | 	for (i = 0; i < count; i++) | ||||||
|  | 		generic_phy_exit(&usb_phys[i]); | ||||||
|  | 
 | ||||||
|  | 	return ret; | ||||||
|  | 
 | ||||||
|  | phys_init_err: | ||||||
|  | 	for (; i >= 0; i--) | ||||||
|  | 		generic_phy_exit(&usb_phys[i]); | ||||||
|  | 
 | ||||||
|  | 	return ret; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | int dwc3_shutdown_phy(struct udevice *dev, struct phy *usb_phys, int num_phys) | ||||||
|  | { | ||||||
|  | 	int i, ret; | ||||||
|  | 
 | ||||||
|  | 	for (i = 0; i < num_phys; i++) { | ||||||
|  | 		if (!generic_phy_valid(&usb_phys[i])) | ||||||
|  | 			continue; | ||||||
|  | 
 | ||||||
|  | 		ret = generic_phy_power_off(&usb_phys[i]); | ||||||
|  | 		ret |= generic_phy_exit(&usb_phys[i]); | ||||||
|  | 		if (ret) { | ||||||
|  | 			pr_err("Can't shutdown USB PHY%d for %s\n", | ||||||
|  | 			       i, dev->name); | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return 0; | ||||||
|  | } | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
| #if CONFIG_IS_ENABLED(DM_USB_GADGET) | #if CONFIG_IS_ENABLED(DM_USB_GADGET) | ||||||
| int dwc3_init(struct dwc3 *dwc) | int dwc3_init(struct dwc3 *dwc) | ||||||
| { | { | ||||||
|  | @ -840,5 +925,4 @@ void dwc3_remove(struct dwc3 *dwc) | ||||||
| 	dwc3_core_exit(dwc); | 	dwc3_core_exit(dwc); | ||||||
| 	kfree(dwc->mem); | 	kfree(dwc->mem); | ||||||
| } | } | ||||||
| 
 |  | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
|  | @ -12,6 +12,7 @@ | ||||||
| #include <fdtdec.h> | #include <fdtdec.h> | ||||||
| #include <generic-phy.h> | #include <generic-phy.h> | ||||||
| #include <usb.h> | #include <usb.h> | ||||||
|  | #include <dwc3-uboot.h> | ||||||
| 
 | 
 | ||||||
| #include "xhci.h" | #include "xhci.h" | ||||||
| #include <asm/io.h> | #include <asm/io.h> | ||||||
|  | @ -110,105 +111,21 @@ void dwc3_set_fladj(struct dwc3 *dwc3_reg, u32 val) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| #if CONFIG_IS_ENABLED(DM_USB) | #if CONFIG_IS_ENABLED(DM_USB) | ||||||
| static int xhci_dwc3_setup_phy(struct udevice *dev) |  | ||||||
| { |  | ||||||
| 	struct xhci_dwc3_platdata *plat = dev_get_platdata(dev); |  | ||||||
| 	int i, ret, count; |  | ||||||
| 
 |  | ||||||
| 	/* Return if no phy declared */ |  | ||||||
| 	if (!dev_read_prop(dev, "phys", NULL)) |  | ||||||
| 		return 0; |  | ||||||
| 
 |  | ||||||
| 	count = dev_count_phandle_with_args(dev, "phys", "#phy-cells"); |  | ||||||
| 	if (count <= 0) |  | ||||||
| 		return count; |  | ||||||
| 
 |  | ||||||
| 	plat->usb_phys = devm_kcalloc(dev, count, sizeof(struct phy), |  | ||||||
| 				      GFP_KERNEL); |  | ||||||
| 	if (!plat->usb_phys) |  | ||||||
| 		return -ENOMEM; |  | ||||||
| 
 |  | ||||||
| 	for (i = 0; i < count; i++) { |  | ||||||
| 		ret = generic_phy_get_by_index(dev, i, &plat->usb_phys[i]); |  | ||||||
| 		if (ret && ret != -ENOENT) { |  | ||||||
| 			pr_err("Failed to get USB PHY%d for %s\n", |  | ||||||
| 			       i, dev->name); |  | ||||||
| 			return ret; |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		++plat->num_phys; |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	for (i = 0; i < plat->num_phys; i++) { |  | ||||||
| 		ret = generic_phy_init(&plat->usb_phys[i]); |  | ||||||
| 		if (ret) { |  | ||||||
| 			pr_err("Can't init USB PHY%d for %s\n", |  | ||||||
| 			       i, dev->name); |  | ||||||
| 			goto phys_init_err; |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	for (i = 0; i < plat->num_phys; i++) { |  | ||||||
| 		ret = generic_phy_power_on(&plat->usb_phys[i]); |  | ||||||
| 		if (ret) { |  | ||||||
| 			pr_err("Can't power USB PHY%d for %s\n", |  | ||||||
| 			       i, dev->name); |  | ||||||
| 			goto phys_poweron_err; |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	return 0; |  | ||||||
| 
 |  | ||||||
| phys_poweron_err: |  | ||||||
| 	for (; i >= 0; i--) |  | ||||||
| 		generic_phy_power_off(&plat->usb_phys[i]); |  | ||||||
| 
 |  | ||||||
| 	for (i = 0; i < plat->num_phys; i++) |  | ||||||
| 		generic_phy_exit(&plat->usb_phys[i]); |  | ||||||
| 
 |  | ||||||
| 	return ret; |  | ||||||
| 
 |  | ||||||
| phys_init_err: |  | ||||||
| 	for (; i >= 0; i--) |  | ||||||
| 		generic_phy_exit(&plat->usb_phys[i]); |  | ||||||
| 
 |  | ||||||
| 	return ret; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| static int xhci_dwc3_shutdown_phy(struct udevice *dev) |  | ||||||
| { |  | ||||||
| 	struct xhci_dwc3_platdata *plat = dev_get_platdata(dev); |  | ||||||
| 	int i, ret; |  | ||||||
| 
 |  | ||||||
| 	for (i = 0; i < plat->num_phys; i++) { |  | ||||||
| 		if (!generic_phy_valid(&plat->usb_phys[i])) |  | ||||||
| 			continue; |  | ||||||
| 
 |  | ||||||
| 		ret = generic_phy_power_off(&plat->usb_phys[i]); |  | ||||||
| 		ret |= generic_phy_exit(&plat->usb_phys[i]); |  | ||||||
| 		if (ret) { |  | ||||||
| 			pr_err("Can't shutdown USB PHY%d for %s\n", |  | ||||||
| 			       i, dev->name); |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	return 0; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| static int xhci_dwc3_probe(struct udevice *dev) | static int xhci_dwc3_probe(struct udevice *dev) | ||||||
| { | { | ||||||
| 	struct xhci_hcor *hcor; | 	struct xhci_hcor *hcor; | ||||||
| 	struct xhci_hccr *hccr; | 	struct xhci_hccr *hccr; | ||||||
| 	struct dwc3 *dwc3_reg; | 	struct dwc3 *dwc3_reg; | ||||||
| 	enum usb_dr_mode dr_mode; | 	enum usb_dr_mode dr_mode; | ||||||
|  | 	struct xhci_dwc3_platdata *plat = dev_get_platdata(dev); | ||||||
| 	int ret; | 	int ret; | ||||||
| 
 | 
 | ||||||
| 	hccr = (struct xhci_hccr *)((uintptr_t)dev_read_addr(dev)); | 	hccr = (struct xhci_hccr *)((uintptr_t)dev_read_addr(dev)); | ||||||
| 	hcor = (struct xhci_hcor *)((uintptr_t)hccr + | 	hcor = (struct xhci_hcor *)((uintptr_t)hccr + | ||||||
| 			HC_LENGTH(xhci_readl(&(hccr)->cr_capbase))); | 			HC_LENGTH(xhci_readl(&(hccr)->cr_capbase))); | ||||||
| 
 | 
 | ||||||
| 	ret = xhci_dwc3_setup_phy(dev); | 	ret = dwc3_setup_phy(dev, &plat->usb_phys, &plat->num_phys); | ||||||
| 	if (ret) | 	if (ret && (ret != -ENOTSUPP)) | ||||||
| 		return ret; | 		return ret; | ||||||
| 
 | 
 | ||||||
| 	dwc3_reg = (struct dwc3 *)((char *)(hccr) + DWC3_REG_OFFSET); | 	dwc3_reg = (struct dwc3 *)((char *)(hccr) + DWC3_REG_OFFSET); | ||||||
|  | @ -227,7 +144,9 @@ static int xhci_dwc3_probe(struct udevice *dev) | ||||||
| 
 | 
 | ||||||
| static int xhci_dwc3_remove(struct udevice *dev) | static int xhci_dwc3_remove(struct udevice *dev) | ||||||
| { | { | ||||||
| 	xhci_dwc3_shutdown_phy(dev); | 	struct xhci_dwc3_platdata *plat = dev_get_platdata(dev); | ||||||
|  | 
 | ||||||
|  | 	dwc3_shutdown_phy(dev, plat->usb_phys, plat->num_phys); | ||||||
| 
 | 
 | ||||||
| 	return xhci_deregister(dev); | 	return xhci_deregister(dev); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -38,4 +38,23 @@ struct dwc3_device { | ||||||
| int dwc3_uboot_init(struct dwc3_device *dev); | int dwc3_uboot_init(struct dwc3_device *dev); | ||||||
| void dwc3_uboot_exit(int index); | void dwc3_uboot_exit(int index); | ||||||
| void dwc3_uboot_handle_interrupt(int index); | void dwc3_uboot_handle_interrupt(int index); | ||||||
|  | 
 | ||||||
|  | struct phy; | ||||||
|  | #if CONFIG_IS_ENABLED(PHY) && CONFIG_IS_ENABLED(DM_USB) | ||||||
|  | int dwc3_setup_phy(struct udevice *dev, struct phy **array, int *num_phys); | ||||||
|  | int dwc3_shutdown_phy(struct udevice *dev, struct phy *usb_phys, int num_phys); | ||||||
|  | #else | ||||||
|  | static inline int dwc3_setup_phy(struct udevice *dev, struct phy **array, | ||||||
|  | 				 int *num_phys) | ||||||
|  | { | ||||||
|  | 	return -ENOTSUPP; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static inline int dwc3_shutdown_phy(struct udevice *dev, struct phy *usb_phys, | ||||||
|  | 				    int num_phys) | ||||||
|  | { | ||||||
|  | 	return -ENOTSUPP; | ||||||
|  | } | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
| #endif /* __DWC3_UBOOT_H_ */ | #endif /* __DWC3_UBOOT_H_ */ | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue