mirror of
				https://source.denx.de/u-boot/u-boot.git
				synced 2025-11-04 02:11:25 +01:00 
			
		
		
		
	Merge branch 'next' of https://source.denx.de/u-boot/custodians/u-boot-usb into next
This commit is contained in:
		
						commit
						31d9d64444
					
				@ -16,75 +16,41 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
struct generic_ohci {
 | 
					struct generic_ohci {
 | 
				
			||||||
	ohci_t ohci;
 | 
						ohci_t ohci;
 | 
				
			||||||
	struct clk *clocks;	/* clock list */
 | 
						struct clk_bulk clocks;	/* clock list */
 | 
				
			||||||
	struct reset_ctl *resets; /* reset list */
 | 
						struct reset_ctl_bulk resets; /* reset list */
 | 
				
			||||||
	struct phy phy;
 | 
						struct phy phy;
 | 
				
			||||||
	int clock_count;	/* number of clock in clock list */
 | 
					 | 
				
			||||||
	int reset_count;	/* number of reset in reset list */
 | 
					 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int ohci_usb_probe(struct udevice *dev)
 | 
					static int ohci_usb_probe(struct udevice *dev)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct ohci_regs *regs = dev_read_addr_ptr(dev);
 | 
						struct ohci_regs *regs = dev_read_addr_ptr(dev);
 | 
				
			||||||
	struct generic_ohci *priv = dev_get_priv(dev);
 | 
						struct generic_ohci *priv = dev_get_priv(dev);
 | 
				
			||||||
	int i, err, ret, clock_nb, reset_nb;
 | 
						int err, ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	err = 0;
 | 
						ret = clk_get_bulk(dev, &priv->clocks);
 | 
				
			||||||
	priv->clock_count = 0;
 | 
						if (ret && ret != -ENOENT) {
 | 
				
			||||||
	clock_nb = dev_count_phandle_with_args(dev, "clocks", "#clock-cells",
 | 
							dev_err(dev, "Failed to get clocks (ret=%d)\n", ret);
 | 
				
			||||||
					       0);
 | 
							return ret;
 | 
				
			||||||
	if (clock_nb > 0) {
 | 
					 | 
				
			||||||
		priv->clocks = devm_kcalloc(dev, clock_nb, sizeof(struct clk),
 | 
					 | 
				
			||||||
					    GFP_KERNEL);
 | 
					 | 
				
			||||||
		if (!priv->clocks)
 | 
					 | 
				
			||||||
			return -ENOMEM;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		for (i = 0; i < clock_nb; i++) {
 | 
					 | 
				
			||||||
			err = clk_get_by_index(dev, i, &priv->clocks[i]);
 | 
					 | 
				
			||||||
			if (err < 0)
 | 
					 | 
				
			||||||
				break;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			err = clk_enable(&priv->clocks[i]);
 | 
					 | 
				
			||||||
			if (err && err != -ENOSYS) {
 | 
					 | 
				
			||||||
				dev_err(dev, "failed to enable clock %d\n", i);
 | 
					 | 
				
			||||||
				clk_free(&priv->clocks[i]);
 | 
					 | 
				
			||||||
				goto clk_err;
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			priv->clock_count++;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	} else if (clock_nb != -ENOENT) {
 | 
					 | 
				
			||||||
		dev_err(dev, "failed to get clock phandle(%d)\n", clock_nb);
 | 
					 | 
				
			||||||
		return clock_nb;
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	priv->reset_count = 0;
 | 
						err = clk_enable_bulk(&priv->clocks);
 | 
				
			||||||
	reset_nb = dev_count_phandle_with_args(dev, "resets", "#reset-cells",
 | 
					 | 
				
			||||||
					       0);
 | 
					 | 
				
			||||||
	if (reset_nb > 0) {
 | 
					 | 
				
			||||||
		priv->resets = devm_kcalloc(dev, reset_nb,
 | 
					 | 
				
			||||||
					    sizeof(struct reset_ctl),
 | 
					 | 
				
			||||||
					    GFP_KERNEL);
 | 
					 | 
				
			||||||
		if (!priv->resets)
 | 
					 | 
				
			||||||
			return -ENOMEM;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		for (i = 0; i < reset_nb; i++) {
 | 
					 | 
				
			||||||
			err = reset_get_by_index(dev, i, &priv->resets[i]);
 | 
					 | 
				
			||||||
			if (err < 0)
 | 
					 | 
				
			||||||
				break;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			err = reset_deassert(&priv->resets[i]);
 | 
					 | 
				
			||||||
	if (err) {
 | 
						if (err) {
 | 
				
			||||||
				dev_err(dev, "failed to deassert reset %d\n", i);
 | 
							dev_err(dev, "Failed to enable clocks (err=%d)\n", err);
 | 
				
			||||||
				reset_free(&priv->resets[i]);
 | 
					 | 
				
			||||||
				goto reset_err;
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			priv->reset_count++;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	} else if (reset_nb != -ENOENT) {
 | 
					 | 
				
			||||||
		dev_err(dev, "failed to get reset phandle(%d)\n", reset_nb);
 | 
					 | 
				
			||||||
		goto clk_err;
 | 
							goto clk_err;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						err = reset_get_bulk(dev, &priv->resets);
 | 
				
			||||||
 | 
						if (err && err != -ENOENT) {
 | 
				
			||||||
 | 
							dev_err(dev, "failed to get resets (err=%d)\n", err);
 | 
				
			||||||
 | 
							goto clk_err;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						err = reset_deassert_bulk(&priv->resets);
 | 
				
			||||||
 | 
						if (err) {
 | 
				
			||||||
 | 
							dev_err(dev, "failed to deassert resets (err=%d)\n", err);
 | 
				
			||||||
 | 
							goto reset_err;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	err = generic_setup_phy(dev, &priv->phy, 0);
 | 
						err = generic_setup_phy(dev, &priv->phy, 0);
 | 
				
			||||||
	if (err)
 | 
						if (err)
 | 
				
			||||||
		goto reset_err;
 | 
							goto reset_err;
 | 
				
			||||||
@ -101,13 +67,13 @@ phy_err:
 | 
				
			|||||||
		dev_err(dev, "failed to shutdown usb phy\n");
 | 
							dev_err(dev, "failed to shutdown usb phy\n");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
reset_err:
 | 
					reset_err:
 | 
				
			||||||
	ret = reset_release_all(priv->resets, priv->reset_count);
 | 
						ret = reset_release_bulk(&priv->resets);
 | 
				
			||||||
	if (ret)
 | 
						if (ret)
 | 
				
			||||||
		dev_err(dev, "failed to assert all resets\n");
 | 
							dev_err(dev, "failed to release resets (ret=%d)\n", ret);
 | 
				
			||||||
clk_err:
 | 
					clk_err:
 | 
				
			||||||
	ret = clk_release_all(priv->clocks, priv->clock_count);
 | 
						ret = clk_release_bulk(&priv->clocks);
 | 
				
			||||||
	if (ret)
 | 
						if (ret)
 | 
				
			||||||
		dev_err(dev, "failed to disable all clocks\n");
 | 
							dev_err(dev, "failed to release clocks (ret=%d)\n", ret);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return err;
 | 
						return err;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -125,11 +91,11 @@ static int ohci_usb_remove(struct udevice *dev)
 | 
				
			|||||||
	if (ret)
 | 
						if (ret)
 | 
				
			||||||
		return ret;
 | 
							return ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ret = reset_release_all(priv->resets, priv->reset_count);
 | 
						ret = reset_release_bulk(&priv->resets);
 | 
				
			||||||
	if (ret)
 | 
						if (ret)
 | 
				
			||||||
		return ret;
 | 
							return ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return clk_release_all(priv->clocks, priv->clock_count);
 | 
						return clk_release_bulk(&priv->clocks);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static const struct udevice_id ohci_usb_ids[] = {
 | 
					static const struct udevice_id ohci_usb_ids[] = {
 | 
				
			||||||
 | 
				
			|||||||
@ -249,6 +249,37 @@ static void remove_inactive_children(struct uclass *uc, struct udevice *bus)
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int usb_probe_companion(struct udevice *bus)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct udevice *companion_dev;
 | 
				
			||||||
 | 
						int ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/*
 | 
				
			||||||
 | 
						 * Enforce optional companion controller is marked as such in order to
 | 
				
			||||||
 | 
						 * 1st scan the primary controller, before the companion controller
 | 
				
			||||||
 | 
						 * (ownership is given to companion when low or full speed devices
 | 
				
			||||||
 | 
						 * have been detected).
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						ret = uclass_get_device_by_phandle(UCLASS_USB, bus, "companion", &companion_dev);
 | 
				
			||||||
 | 
						if (!ret) {
 | 
				
			||||||
 | 
							struct usb_bus_priv *companion_bus_priv;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							debug("%s is the companion of %s\n", companion_dev->name, bus->name);
 | 
				
			||||||
 | 
							companion_bus_priv = dev_get_uclass_priv(companion_dev);
 | 
				
			||||||
 | 
							companion_bus_priv->companion = true;
 | 
				
			||||||
 | 
						} else if (ret && ret != -ENOENT && ret != -ENODEV) {
 | 
				
			||||||
 | 
							/*
 | 
				
			||||||
 | 
							 * Treat everything else than no companion or disabled
 | 
				
			||||||
 | 
							 * companion as an error. (It may not be enabled on boards
 | 
				
			||||||
 | 
							 * that have a High-Speed HUB to handle FS and LS traffic).
 | 
				
			||||||
 | 
							 */
 | 
				
			||||||
 | 
							printf("Failed to get companion (ret=%d)\n", ret);
 | 
				
			||||||
 | 
							return ret;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int usb_init(void)
 | 
					int usb_init(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int controllers_initialized = 0;
 | 
						int controllers_initialized = 0;
 | 
				
			||||||
@ -299,6 +330,11 @@ int usb_init(void)
 | 
				
			|||||||
			printf("probe failed, error %d\n", ret);
 | 
								printf("probe failed, error %d\n", ret);
 | 
				
			||||||
			continue;
 | 
								continue;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							ret = usb_probe_companion(bus);
 | 
				
			||||||
 | 
							if (ret)
 | 
				
			||||||
 | 
								continue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		controllers_initialized++;
 | 
							controllers_initialized++;
 | 
				
			||||||
		usb_started = true;
 | 
							usb_started = true;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user