xref: /OK3568_Linux_fs/u-boot/drivers/usb/host/usb-uclass.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun  * (C) Copyright 2015 Google, Inc
3*4882a593Smuzhiyun  * Written by Simon Glass <sjg@chromium.org>
4*4882a593Smuzhiyun  *
5*4882a593Smuzhiyun  * usb_match_device() modified from Linux kernel v4.0.
6*4882a593Smuzhiyun  *
7*4882a593Smuzhiyun  * SPDX-License-Identifier:	GPL-2.0+
8*4882a593Smuzhiyun  */
9*4882a593Smuzhiyun 
10*4882a593Smuzhiyun #include <common.h>
11*4882a593Smuzhiyun #include <dm.h>
12*4882a593Smuzhiyun #include <errno.h>
13*4882a593Smuzhiyun #include <memalign.h>
14*4882a593Smuzhiyun #include <usb.h>
15*4882a593Smuzhiyun #include <dm/device-internal.h>
16*4882a593Smuzhiyun #include <dm/lists.h>
17*4882a593Smuzhiyun #include <dm/uclass-internal.h>
18*4882a593Smuzhiyun 
19*4882a593Smuzhiyun DECLARE_GLOBAL_DATA_PTR;
20*4882a593Smuzhiyun 
21*4882a593Smuzhiyun extern bool usb_started; /* flag for the started/stopped USB status */
22*4882a593Smuzhiyun static bool asynch_allowed;
23*4882a593Smuzhiyun 
24*4882a593Smuzhiyun struct usb_uclass_priv {
25*4882a593Smuzhiyun 	int companion_device_count;
26*4882a593Smuzhiyun };
27*4882a593Smuzhiyun 
usb_disable_asynch(int disable)28*4882a593Smuzhiyun int usb_disable_asynch(int disable)
29*4882a593Smuzhiyun {
30*4882a593Smuzhiyun 	int old_value = asynch_allowed;
31*4882a593Smuzhiyun 
32*4882a593Smuzhiyun 	asynch_allowed = !disable;
33*4882a593Smuzhiyun 	return old_value;
34*4882a593Smuzhiyun }
35*4882a593Smuzhiyun 
submit_int_msg(struct usb_device * udev,unsigned long pipe,void * buffer,int length,int interval,bool nonblock)36*4882a593Smuzhiyun int submit_int_msg(struct usb_device *udev, unsigned long pipe, void *buffer,
37*4882a593Smuzhiyun 		   int length, int interval, bool nonblock)
38*4882a593Smuzhiyun {
39*4882a593Smuzhiyun 	struct udevice *bus = udev->controller_dev;
40*4882a593Smuzhiyun 	struct dm_usb_ops *ops = usb_get_ops(bus);
41*4882a593Smuzhiyun 
42*4882a593Smuzhiyun 	if (!ops->interrupt)
43*4882a593Smuzhiyun 		return -ENOSYS;
44*4882a593Smuzhiyun 
45*4882a593Smuzhiyun 	return ops->interrupt(bus, udev, pipe, buffer, length, interval,
46*4882a593Smuzhiyun 			      nonblock);
47*4882a593Smuzhiyun }
48*4882a593Smuzhiyun 
submit_control_msg(struct usb_device * udev,unsigned long pipe,void * buffer,int length,struct devrequest * setup)49*4882a593Smuzhiyun int submit_control_msg(struct usb_device *udev, unsigned long pipe,
50*4882a593Smuzhiyun 		       void *buffer, int length, struct devrequest *setup)
51*4882a593Smuzhiyun {
52*4882a593Smuzhiyun 	struct udevice *bus = udev->controller_dev;
53*4882a593Smuzhiyun 	struct dm_usb_ops *ops = usb_get_ops(bus);
54*4882a593Smuzhiyun 	struct usb_uclass_priv *uc_priv = bus->uclass->priv;
55*4882a593Smuzhiyun 	int err;
56*4882a593Smuzhiyun 
57*4882a593Smuzhiyun 	if (!ops->control)
58*4882a593Smuzhiyun 		return -ENOSYS;
59*4882a593Smuzhiyun 
60*4882a593Smuzhiyun 	err = ops->control(bus, udev, pipe, buffer, length, setup);
61*4882a593Smuzhiyun 	if (setup->request == USB_REQ_SET_FEATURE &&
62*4882a593Smuzhiyun 	    setup->requesttype == USB_RT_PORT &&
63*4882a593Smuzhiyun 	    setup->value == cpu_to_le16(USB_PORT_FEAT_RESET) &&
64*4882a593Smuzhiyun 	    err == -ENXIO) {
65*4882a593Smuzhiyun 		/* Device handed over to companion after port reset */
66*4882a593Smuzhiyun 		uc_priv->companion_device_count++;
67*4882a593Smuzhiyun 	}
68*4882a593Smuzhiyun 
69*4882a593Smuzhiyun 	return err;
70*4882a593Smuzhiyun }
71*4882a593Smuzhiyun 
submit_bulk_msg(struct usb_device * udev,unsigned long pipe,void * buffer,int length)72*4882a593Smuzhiyun int submit_bulk_msg(struct usb_device *udev, unsigned long pipe, void *buffer,
73*4882a593Smuzhiyun 		    int length)
74*4882a593Smuzhiyun {
75*4882a593Smuzhiyun 	struct udevice *bus = udev->controller_dev;
76*4882a593Smuzhiyun 	struct dm_usb_ops *ops = usb_get_ops(bus);
77*4882a593Smuzhiyun 
78*4882a593Smuzhiyun 	if (!ops->bulk)
79*4882a593Smuzhiyun 		return -ENOSYS;
80*4882a593Smuzhiyun 
81*4882a593Smuzhiyun 	return ops->bulk(bus, udev, pipe, buffer, length);
82*4882a593Smuzhiyun }
83*4882a593Smuzhiyun 
create_int_queue(struct usb_device * udev,unsigned long pipe,int queuesize,int elementsize,void * buffer,int interval)84*4882a593Smuzhiyun struct int_queue *create_int_queue(struct usb_device *udev,
85*4882a593Smuzhiyun 		unsigned long pipe, int queuesize, int elementsize,
86*4882a593Smuzhiyun 		void *buffer, int interval)
87*4882a593Smuzhiyun {
88*4882a593Smuzhiyun 	struct udevice *bus = udev->controller_dev;
89*4882a593Smuzhiyun 	struct dm_usb_ops *ops = usb_get_ops(bus);
90*4882a593Smuzhiyun 
91*4882a593Smuzhiyun 	if (!ops->create_int_queue)
92*4882a593Smuzhiyun 		return NULL;
93*4882a593Smuzhiyun 
94*4882a593Smuzhiyun 	return ops->create_int_queue(bus, udev, pipe, queuesize, elementsize,
95*4882a593Smuzhiyun 				     buffer, interval);
96*4882a593Smuzhiyun }
97*4882a593Smuzhiyun 
poll_int_queue(struct usb_device * udev,struct int_queue * queue)98*4882a593Smuzhiyun void *poll_int_queue(struct usb_device *udev, struct int_queue *queue)
99*4882a593Smuzhiyun {
100*4882a593Smuzhiyun 	struct udevice *bus = udev->controller_dev;
101*4882a593Smuzhiyun 	struct dm_usb_ops *ops = usb_get_ops(bus);
102*4882a593Smuzhiyun 
103*4882a593Smuzhiyun 	if (!ops->poll_int_queue)
104*4882a593Smuzhiyun 		return NULL;
105*4882a593Smuzhiyun 
106*4882a593Smuzhiyun 	return ops->poll_int_queue(bus, udev, queue);
107*4882a593Smuzhiyun }
108*4882a593Smuzhiyun 
destroy_int_queue(struct usb_device * udev,struct int_queue * queue)109*4882a593Smuzhiyun int destroy_int_queue(struct usb_device *udev, struct int_queue *queue)
110*4882a593Smuzhiyun {
111*4882a593Smuzhiyun 	struct udevice *bus = udev->controller_dev;
112*4882a593Smuzhiyun 	struct dm_usb_ops *ops = usb_get_ops(bus);
113*4882a593Smuzhiyun 
114*4882a593Smuzhiyun 	if (!ops->destroy_int_queue)
115*4882a593Smuzhiyun 		return -ENOSYS;
116*4882a593Smuzhiyun 
117*4882a593Smuzhiyun 	return ops->destroy_int_queue(bus, udev, queue);
118*4882a593Smuzhiyun }
119*4882a593Smuzhiyun 
usb_alloc_device(struct usb_device * udev)120*4882a593Smuzhiyun int usb_alloc_device(struct usb_device *udev)
121*4882a593Smuzhiyun {
122*4882a593Smuzhiyun 	struct udevice *bus = udev->controller_dev;
123*4882a593Smuzhiyun 	struct dm_usb_ops *ops = usb_get_ops(bus);
124*4882a593Smuzhiyun 
125*4882a593Smuzhiyun 	/* This is only requird by some controllers - current XHCI */
126*4882a593Smuzhiyun 	if (!ops->alloc_device)
127*4882a593Smuzhiyun 		return 0;
128*4882a593Smuzhiyun 
129*4882a593Smuzhiyun 	return ops->alloc_device(bus, udev);
130*4882a593Smuzhiyun }
131*4882a593Smuzhiyun 
usb_reset_root_port(struct usb_device * udev)132*4882a593Smuzhiyun int usb_reset_root_port(struct usb_device *udev)
133*4882a593Smuzhiyun {
134*4882a593Smuzhiyun 	struct udevice *bus = udev->controller_dev;
135*4882a593Smuzhiyun 	struct dm_usb_ops *ops = usb_get_ops(bus);
136*4882a593Smuzhiyun 
137*4882a593Smuzhiyun 	if (!ops->reset_root_port)
138*4882a593Smuzhiyun 		return -ENOSYS;
139*4882a593Smuzhiyun 
140*4882a593Smuzhiyun 	return ops->reset_root_port(bus, udev);
141*4882a593Smuzhiyun }
142*4882a593Smuzhiyun 
usb_update_hub_device(struct usb_device * udev)143*4882a593Smuzhiyun int usb_update_hub_device(struct usb_device *udev)
144*4882a593Smuzhiyun {
145*4882a593Smuzhiyun 	struct udevice *bus = udev->controller_dev;
146*4882a593Smuzhiyun 	struct dm_usb_ops *ops = usb_get_ops(bus);
147*4882a593Smuzhiyun 
148*4882a593Smuzhiyun 	if (!ops->update_hub_device)
149*4882a593Smuzhiyun 		return -ENOSYS;
150*4882a593Smuzhiyun 
151*4882a593Smuzhiyun 	return ops->update_hub_device(bus, udev);
152*4882a593Smuzhiyun }
153*4882a593Smuzhiyun 
usb_get_max_xfer_size(struct usb_device * udev,size_t * size)154*4882a593Smuzhiyun int usb_get_max_xfer_size(struct usb_device *udev, size_t *size)
155*4882a593Smuzhiyun {
156*4882a593Smuzhiyun 	struct udevice *bus = udev->controller_dev;
157*4882a593Smuzhiyun 	struct dm_usb_ops *ops = usb_get_ops(bus);
158*4882a593Smuzhiyun 
159*4882a593Smuzhiyun 	if (!ops->get_max_xfer_size)
160*4882a593Smuzhiyun 		return -ENOSYS;
161*4882a593Smuzhiyun 
162*4882a593Smuzhiyun 	return ops->get_max_xfer_size(bus, size);
163*4882a593Smuzhiyun }
164*4882a593Smuzhiyun 
usb_stop(void)165*4882a593Smuzhiyun int usb_stop(void)
166*4882a593Smuzhiyun {
167*4882a593Smuzhiyun 	struct udevice *bus;
168*4882a593Smuzhiyun 	struct udevice *rh;
169*4882a593Smuzhiyun 	struct uclass *uc;
170*4882a593Smuzhiyun 	struct usb_uclass_priv *uc_priv;
171*4882a593Smuzhiyun 	int err = 0, ret;
172*4882a593Smuzhiyun 
173*4882a593Smuzhiyun 	/* De-activate any devices that have been activated */
174*4882a593Smuzhiyun 	ret = uclass_get(UCLASS_USB, &uc);
175*4882a593Smuzhiyun 	if (ret)
176*4882a593Smuzhiyun 		return ret;
177*4882a593Smuzhiyun 
178*4882a593Smuzhiyun 	uc_priv = uc->priv;
179*4882a593Smuzhiyun 
180*4882a593Smuzhiyun 	uclass_foreach_dev(bus, uc) {
181*4882a593Smuzhiyun 		ret = device_remove(bus, DM_REMOVE_NORMAL);
182*4882a593Smuzhiyun 		if (ret && !err)
183*4882a593Smuzhiyun 			err = ret;
184*4882a593Smuzhiyun 
185*4882a593Smuzhiyun 		/* Locate root hub device */
186*4882a593Smuzhiyun 		device_find_first_child(bus, &rh);
187*4882a593Smuzhiyun 		if (rh) {
188*4882a593Smuzhiyun 			/*
189*4882a593Smuzhiyun 			 * All USB devices are children of root hub.
190*4882a593Smuzhiyun 			 * Unbinding root hub will unbind all of its children.
191*4882a593Smuzhiyun 			 */
192*4882a593Smuzhiyun 			ret = device_unbind(rh);
193*4882a593Smuzhiyun 			if (ret && !err)
194*4882a593Smuzhiyun 				err = ret;
195*4882a593Smuzhiyun 		}
196*4882a593Smuzhiyun 	}
197*4882a593Smuzhiyun 
198*4882a593Smuzhiyun #ifdef CONFIG_USB_STORAGE
199*4882a593Smuzhiyun 	usb_stor_reset();
200*4882a593Smuzhiyun #endif
201*4882a593Smuzhiyun 	uc_priv->companion_device_count = 0;
202*4882a593Smuzhiyun 	usb_started = 0;
203*4882a593Smuzhiyun 
204*4882a593Smuzhiyun 	return err;
205*4882a593Smuzhiyun }
206*4882a593Smuzhiyun 
usb_scan_bus(struct udevice * bus,bool recurse)207*4882a593Smuzhiyun static void usb_scan_bus(struct udevice *bus, bool recurse)
208*4882a593Smuzhiyun {
209*4882a593Smuzhiyun 	struct usb_bus_priv *priv;
210*4882a593Smuzhiyun 	struct udevice *dev;
211*4882a593Smuzhiyun 	int ret;
212*4882a593Smuzhiyun 
213*4882a593Smuzhiyun 	priv = dev_get_uclass_priv(bus);
214*4882a593Smuzhiyun 
215*4882a593Smuzhiyun 	assert(recurse);	/* TODO: Support non-recusive */
216*4882a593Smuzhiyun 
217*4882a593Smuzhiyun 	printf("scanning bus %s for devices... ", bus->name);
218*4882a593Smuzhiyun 	debug("\n");
219*4882a593Smuzhiyun 	ret = usb_scan_device(bus, 0, USB_SPEED_FULL, &dev);
220*4882a593Smuzhiyun 	if (ret)
221*4882a593Smuzhiyun 		printf("failed, error %d\n", ret);
222*4882a593Smuzhiyun 	else if (priv->next_addr == 0)
223*4882a593Smuzhiyun 		printf("No USB Device found\n");
224*4882a593Smuzhiyun 	else
225*4882a593Smuzhiyun 		printf("%d USB Device(s) found\n", priv->next_addr);
226*4882a593Smuzhiyun }
227*4882a593Smuzhiyun 
remove_inactive_children(struct uclass * uc,struct udevice * bus)228*4882a593Smuzhiyun static void remove_inactive_children(struct uclass *uc, struct udevice *bus)
229*4882a593Smuzhiyun {
230*4882a593Smuzhiyun 	uclass_foreach_dev(bus, uc) {
231*4882a593Smuzhiyun 		struct udevice *dev, *next;
232*4882a593Smuzhiyun 
233*4882a593Smuzhiyun 		if (!device_active(bus))
234*4882a593Smuzhiyun 			continue;
235*4882a593Smuzhiyun 		device_foreach_child_safe(dev, next, bus) {
236*4882a593Smuzhiyun 			if (!device_active(dev))
237*4882a593Smuzhiyun 				device_unbind(dev);
238*4882a593Smuzhiyun 		}
239*4882a593Smuzhiyun 	}
240*4882a593Smuzhiyun }
241*4882a593Smuzhiyun 
usb_init(void)242*4882a593Smuzhiyun int usb_init(void)
243*4882a593Smuzhiyun {
244*4882a593Smuzhiyun 	int controllers_initialized = 0;
245*4882a593Smuzhiyun 	struct usb_uclass_priv *uc_priv;
246*4882a593Smuzhiyun 	struct usb_bus_priv *priv;
247*4882a593Smuzhiyun 	struct udevice *bus;
248*4882a593Smuzhiyun 	struct uclass *uc;
249*4882a593Smuzhiyun 	int ret;
250*4882a593Smuzhiyun 
251*4882a593Smuzhiyun 	asynch_allowed = 1;
252*4882a593Smuzhiyun 
253*4882a593Smuzhiyun 	ret = uclass_get(UCLASS_USB, &uc);
254*4882a593Smuzhiyun 	if (ret)
255*4882a593Smuzhiyun 		return ret;
256*4882a593Smuzhiyun 
257*4882a593Smuzhiyun 	uc_priv = uc->priv;
258*4882a593Smuzhiyun 
259*4882a593Smuzhiyun 	uclass_foreach_dev(bus, uc) {
260*4882a593Smuzhiyun 		/* init low_level USB */
261*4882a593Smuzhiyun 		printf("Bus %s: ", bus->name);
262*4882a593Smuzhiyun 
263*4882a593Smuzhiyun #ifdef CONFIG_SANDBOX
264*4882a593Smuzhiyun 		/*
265*4882a593Smuzhiyun 		 * For Sandbox, we need scan the device tree each time when we
266*4882a593Smuzhiyun 		 * start the USB stack, in order to re-create the emulated USB
267*4882a593Smuzhiyun 		 * devices and bind drivers for them before we actually do the
268*4882a593Smuzhiyun 		 * driver probe.
269*4882a593Smuzhiyun 		 */
270*4882a593Smuzhiyun 		ret = dm_scan_fdt_dev(bus);
271*4882a593Smuzhiyun 		if (ret) {
272*4882a593Smuzhiyun 			printf("Sandbox USB device scan failed (%d)\n", ret);
273*4882a593Smuzhiyun 			continue;
274*4882a593Smuzhiyun 		}
275*4882a593Smuzhiyun #endif
276*4882a593Smuzhiyun 
277*4882a593Smuzhiyun 		ret = device_probe(bus);
278*4882a593Smuzhiyun 		if (ret == -ENODEV) {	/* No such device. */
279*4882a593Smuzhiyun 			puts("Port not available.\n");
280*4882a593Smuzhiyun 			controllers_initialized++;
281*4882a593Smuzhiyun 			continue;
282*4882a593Smuzhiyun 		}
283*4882a593Smuzhiyun 
284*4882a593Smuzhiyun 		if (ret) {		/* Other error. */
285*4882a593Smuzhiyun 			printf("probe failed, error %d\n", ret);
286*4882a593Smuzhiyun 			continue;
287*4882a593Smuzhiyun 		}
288*4882a593Smuzhiyun 		controllers_initialized++;
289*4882a593Smuzhiyun 		usb_started = true;
290*4882a593Smuzhiyun 	}
291*4882a593Smuzhiyun 
292*4882a593Smuzhiyun 	/*
293*4882a593Smuzhiyun 	 * lowlevel init done, now scan the bus for devices i.e. search HUBs
294*4882a593Smuzhiyun 	 * and configure them, first scan primary controllers.
295*4882a593Smuzhiyun 	 */
296*4882a593Smuzhiyun 	uclass_foreach_dev(bus, uc) {
297*4882a593Smuzhiyun 		if (!device_active(bus))
298*4882a593Smuzhiyun 			continue;
299*4882a593Smuzhiyun 
300*4882a593Smuzhiyun 		priv = dev_get_uclass_priv(bus);
301*4882a593Smuzhiyun 		if (!priv->companion)
302*4882a593Smuzhiyun 			usb_scan_bus(bus, true);
303*4882a593Smuzhiyun 	}
304*4882a593Smuzhiyun 
305*4882a593Smuzhiyun 	/*
306*4882a593Smuzhiyun 	 * Now that the primary controllers have been scanned and have handed
307*4882a593Smuzhiyun 	 * over any devices they do not understand to their companions, scan
308*4882a593Smuzhiyun 	 * the companions if necessary.
309*4882a593Smuzhiyun 	 */
310*4882a593Smuzhiyun 	if (uc_priv->companion_device_count) {
311*4882a593Smuzhiyun 		uclass_foreach_dev(bus, uc) {
312*4882a593Smuzhiyun 			if (!device_active(bus))
313*4882a593Smuzhiyun 				continue;
314*4882a593Smuzhiyun 
315*4882a593Smuzhiyun 			priv = dev_get_uclass_priv(bus);
316*4882a593Smuzhiyun 			if (priv->companion)
317*4882a593Smuzhiyun 				usb_scan_bus(bus, true);
318*4882a593Smuzhiyun 		}
319*4882a593Smuzhiyun 	}
320*4882a593Smuzhiyun 
321*4882a593Smuzhiyun 	debug("scan end\n");
322*4882a593Smuzhiyun 
323*4882a593Smuzhiyun 	/* Remove any devices that were not found on this scan */
324*4882a593Smuzhiyun 	remove_inactive_children(uc, bus);
325*4882a593Smuzhiyun 
326*4882a593Smuzhiyun 	ret = uclass_get(UCLASS_USB_HUB, &uc);
327*4882a593Smuzhiyun 	if (ret)
328*4882a593Smuzhiyun 		return ret;
329*4882a593Smuzhiyun 	remove_inactive_children(uc, bus);
330*4882a593Smuzhiyun 
331*4882a593Smuzhiyun 	/* if we were not able to find at least one working bus, bail out */
332*4882a593Smuzhiyun 	if (controllers_initialized == 0)
333*4882a593Smuzhiyun 		printf("No working controllers found\n");
334*4882a593Smuzhiyun 
335*4882a593Smuzhiyun 	return usb_started ? 0 : -1;
336*4882a593Smuzhiyun }
337*4882a593Smuzhiyun 
338*4882a593Smuzhiyun /*
339*4882a593Smuzhiyun  * TODO(sjg@chromium.org): Remove this legacy function. At present it is needed
340*4882a593Smuzhiyun  * to support boards which use driver model for USB but not Ethernet, and want
341*4882a593Smuzhiyun  * to use USB Ethernet.
342*4882a593Smuzhiyun  *
343*4882a593Smuzhiyun  * The #if clause is here to ensure that remains the only case.
344*4882a593Smuzhiyun  */
345*4882a593Smuzhiyun #if !defined(CONFIG_DM_ETH) && defined(CONFIG_USB_HOST_ETHER)
find_child_devnum(struct udevice * parent,int devnum)346*4882a593Smuzhiyun static struct usb_device *find_child_devnum(struct udevice *parent, int devnum)
347*4882a593Smuzhiyun {
348*4882a593Smuzhiyun 	struct usb_device *udev;
349*4882a593Smuzhiyun 	struct udevice *dev;
350*4882a593Smuzhiyun 
351*4882a593Smuzhiyun 	if (!device_active(parent))
352*4882a593Smuzhiyun 		return NULL;
353*4882a593Smuzhiyun 	udev = dev_get_parent_priv(parent);
354*4882a593Smuzhiyun 	if (udev->devnum == devnum)
355*4882a593Smuzhiyun 		return udev;
356*4882a593Smuzhiyun 
357*4882a593Smuzhiyun 	for (device_find_first_child(parent, &dev);
358*4882a593Smuzhiyun 	     dev;
359*4882a593Smuzhiyun 	     device_find_next_child(&dev)) {
360*4882a593Smuzhiyun 		udev = find_child_devnum(dev, devnum);
361*4882a593Smuzhiyun 		if (udev)
362*4882a593Smuzhiyun 			return udev;
363*4882a593Smuzhiyun 	}
364*4882a593Smuzhiyun 
365*4882a593Smuzhiyun 	return NULL;
366*4882a593Smuzhiyun }
367*4882a593Smuzhiyun 
usb_get_dev_index(struct udevice * bus,int index)368*4882a593Smuzhiyun struct usb_device *usb_get_dev_index(struct udevice *bus, int index)
369*4882a593Smuzhiyun {
370*4882a593Smuzhiyun 	struct udevice *dev;
371*4882a593Smuzhiyun 	int devnum = index + 1; /* Addresses are allocated from 1 on USB */
372*4882a593Smuzhiyun 
373*4882a593Smuzhiyun 	device_find_first_child(bus, &dev);
374*4882a593Smuzhiyun 	if (!dev)
375*4882a593Smuzhiyun 		return NULL;
376*4882a593Smuzhiyun 
377*4882a593Smuzhiyun 	return find_child_devnum(dev, devnum);
378*4882a593Smuzhiyun }
379*4882a593Smuzhiyun #endif
380*4882a593Smuzhiyun 
usb_setup_ehci_gadget(struct ehci_ctrl ** ctlrp)381*4882a593Smuzhiyun int usb_setup_ehci_gadget(struct ehci_ctrl **ctlrp)
382*4882a593Smuzhiyun {
383*4882a593Smuzhiyun 	struct usb_platdata *plat;
384*4882a593Smuzhiyun 	struct udevice *dev;
385*4882a593Smuzhiyun 	int ret;
386*4882a593Smuzhiyun 
387*4882a593Smuzhiyun 	/* Find the old device and remove it */
388*4882a593Smuzhiyun 	ret = uclass_find_device_by_seq(UCLASS_USB, 0, true, &dev);
389*4882a593Smuzhiyun 	if (ret)
390*4882a593Smuzhiyun 		return ret;
391*4882a593Smuzhiyun 	ret = device_remove(dev, DM_REMOVE_NORMAL);
392*4882a593Smuzhiyun 	if (ret)
393*4882a593Smuzhiyun 		return ret;
394*4882a593Smuzhiyun 
395*4882a593Smuzhiyun 	plat = dev_get_platdata(dev);
396*4882a593Smuzhiyun 	plat->init_type = USB_INIT_DEVICE;
397*4882a593Smuzhiyun 	ret = device_probe(dev);
398*4882a593Smuzhiyun 	if (ret)
399*4882a593Smuzhiyun 		return ret;
400*4882a593Smuzhiyun 	*ctlrp = dev_get_priv(dev);
401*4882a593Smuzhiyun 
402*4882a593Smuzhiyun 	return 0;
403*4882a593Smuzhiyun }
404*4882a593Smuzhiyun 
405*4882a593Smuzhiyun /* returns 0 if no match, 1 if match */
usb_match_device(const struct usb_device_descriptor * desc,const struct usb_device_id * id)406*4882a593Smuzhiyun static int usb_match_device(const struct usb_device_descriptor *desc,
407*4882a593Smuzhiyun 			    const struct usb_device_id *id)
408*4882a593Smuzhiyun {
409*4882a593Smuzhiyun 	if ((id->match_flags & USB_DEVICE_ID_MATCH_VENDOR) &&
410*4882a593Smuzhiyun 	    id->idVendor != le16_to_cpu(desc->idVendor))
411*4882a593Smuzhiyun 		return 0;
412*4882a593Smuzhiyun 
413*4882a593Smuzhiyun 	if ((id->match_flags & USB_DEVICE_ID_MATCH_PRODUCT) &&
414*4882a593Smuzhiyun 	    id->idProduct != le16_to_cpu(desc->idProduct))
415*4882a593Smuzhiyun 		return 0;
416*4882a593Smuzhiyun 
417*4882a593Smuzhiyun 	/* No need to test id->bcdDevice_lo != 0, since 0 is never
418*4882a593Smuzhiyun 	   greater than any unsigned number. */
419*4882a593Smuzhiyun 	if ((id->match_flags & USB_DEVICE_ID_MATCH_DEV_LO) &&
420*4882a593Smuzhiyun 	    (id->bcdDevice_lo > le16_to_cpu(desc->bcdDevice)))
421*4882a593Smuzhiyun 		return 0;
422*4882a593Smuzhiyun 
423*4882a593Smuzhiyun 	if ((id->match_flags & USB_DEVICE_ID_MATCH_DEV_HI) &&
424*4882a593Smuzhiyun 	    (id->bcdDevice_hi < le16_to_cpu(desc->bcdDevice)))
425*4882a593Smuzhiyun 		return 0;
426*4882a593Smuzhiyun 
427*4882a593Smuzhiyun 	if ((id->match_flags & USB_DEVICE_ID_MATCH_DEV_CLASS) &&
428*4882a593Smuzhiyun 	    (id->bDeviceClass != desc->bDeviceClass))
429*4882a593Smuzhiyun 		return 0;
430*4882a593Smuzhiyun 
431*4882a593Smuzhiyun 	if ((id->match_flags & USB_DEVICE_ID_MATCH_DEV_SUBCLASS) &&
432*4882a593Smuzhiyun 	    (id->bDeviceSubClass != desc->bDeviceSubClass))
433*4882a593Smuzhiyun 		return 0;
434*4882a593Smuzhiyun 
435*4882a593Smuzhiyun 	if ((id->match_flags & USB_DEVICE_ID_MATCH_DEV_PROTOCOL) &&
436*4882a593Smuzhiyun 	    (id->bDeviceProtocol != desc->bDeviceProtocol))
437*4882a593Smuzhiyun 		return 0;
438*4882a593Smuzhiyun 
439*4882a593Smuzhiyun 	return 1;
440*4882a593Smuzhiyun }
441*4882a593Smuzhiyun 
442*4882a593Smuzhiyun /* returns 0 if no match, 1 if match */
usb_match_one_id_intf(const struct usb_device_descriptor * desc,const struct usb_interface_descriptor * int_desc,const struct usb_device_id * id)443*4882a593Smuzhiyun static int usb_match_one_id_intf(const struct usb_device_descriptor *desc,
444*4882a593Smuzhiyun 			const struct usb_interface_descriptor *int_desc,
445*4882a593Smuzhiyun 			const struct usb_device_id *id)
446*4882a593Smuzhiyun {
447*4882a593Smuzhiyun 	/* The interface class, subclass, protocol and number should never be
448*4882a593Smuzhiyun 	 * checked for a match if the device class is Vendor Specific,
449*4882a593Smuzhiyun 	 * unless the match record specifies the Vendor ID. */
450*4882a593Smuzhiyun 	if (desc->bDeviceClass == USB_CLASS_VENDOR_SPEC &&
451*4882a593Smuzhiyun 	    !(id->match_flags & USB_DEVICE_ID_MATCH_VENDOR) &&
452*4882a593Smuzhiyun 	    (id->match_flags & (USB_DEVICE_ID_MATCH_INT_CLASS |
453*4882a593Smuzhiyun 				USB_DEVICE_ID_MATCH_INT_SUBCLASS |
454*4882a593Smuzhiyun 				USB_DEVICE_ID_MATCH_INT_PROTOCOL |
455*4882a593Smuzhiyun 				USB_DEVICE_ID_MATCH_INT_NUMBER)))
456*4882a593Smuzhiyun 		return 0;
457*4882a593Smuzhiyun 
458*4882a593Smuzhiyun 	if ((id->match_flags & USB_DEVICE_ID_MATCH_INT_CLASS) &&
459*4882a593Smuzhiyun 	    (id->bInterfaceClass != int_desc->bInterfaceClass))
460*4882a593Smuzhiyun 		return 0;
461*4882a593Smuzhiyun 
462*4882a593Smuzhiyun 	if ((id->match_flags & USB_DEVICE_ID_MATCH_INT_SUBCLASS) &&
463*4882a593Smuzhiyun 	    (id->bInterfaceSubClass != int_desc->bInterfaceSubClass))
464*4882a593Smuzhiyun 		return 0;
465*4882a593Smuzhiyun 
466*4882a593Smuzhiyun 	if ((id->match_flags & USB_DEVICE_ID_MATCH_INT_PROTOCOL) &&
467*4882a593Smuzhiyun 	    (id->bInterfaceProtocol != int_desc->bInterfaceProtocol))
468*4882a593Smuzhiyun 		return 0;
469*4882a593Smuzhiyun 
470*4882a593Smuzhiyun 	if ((id->match_flags & USB_DEVICE_ID_MATCH_INT_NUMBER) &&
471*4882a593Smuzhiyun 	    (id->bInterfaceNumber != int_desc->bInterfaceNumber))
472*4882a593Smuzhiyun 		return 0;
473*4882a593Smuzhiyun 
474*4882a593Smuzhiyun 	return 1;
475*4882a593Smuzhiyun }
476*4882a593Smuzhiyun 
477*4882a593Smuzhiyun /* returns 0 if no match, 1 if match */
usb_match_one_id(struct usb_device_descriptor * desc,struct usb_interface_descriptor * int_desc,const struct usb_device_id * id)478*4882a593Smuzhiyun static int usb_match_one_id(struct usb_device_descriptor *desc,
479*4882a593Smuzhiyun 			    struct usb_interface_descriptor *int_desc,
480*4882a593Smuzhiyun 			    const struct usb_device_id *id)
481*4882a593Smuzhiyun {
482*4882a593Smuzhiyun 	if (!usb_match_device(desc, id))
483*4882a593Smuzhiyun 		return 0;
484*4882a593Smuzhiyun 
485*4882a593Smuzhiyun 	return usb_match_one_id_intf(desc, int_desc, id);
486*4882a593Smuzhiyun }
487*4882a593Smuzhiyun 
488*4882a593Smuzhiyun /**
489*4882a593Smuzhiyun  * usb_find_and_bind_driver() - Find and bind the right USB driver
490*4882a593Smuzhiyun  *
491*4882a593Smuzhiyun  * This only looks at certain fields in the descriptor.
492*4882a593Smuzhiyun  */
usb_find_and_bind_driver(struct udevice * parent,struct usb_device_descriptor * desc,struct usb_interface_descriptor * iface,int bus_seq,int devnum,struct udevice ** devp)493*4882a593Smuzhiyun static int usb_find_and_bind_driver(struct udevice *parent,
494*4882a593Smuzhiyun 				    struct usb_device_descriptor *desc,
495*4882a593Smuzhiyun 				    struct usb_interface_descriptor *iface,
496*4882a593Smuzhiyun 				    int bus_seq, int devnum,
497*4882a593Smuzhiyun 				    struct udevice **devp)
498*4882a593Smuzhiyun {
499*4882a593Smuzhiyun 	struct usb_driver_entry *start, *entry;
500*4882a593Smuzhiyun 	int n_ents;
501*4882a593Smuzhiyun 	int ret;
502*4882a593Smuzhiyun 	char name[30], *str;
503*4882a593Smuzhiyun 
504*4882a593Smuzhiyun 	*devp = NULL;
505*4882a593Smuzhiyun 	debug("%s: Searching for driver\n", __func__);
506*4882a593Smuzhiyun 	start = ll_entry_start(struct usb_driver_entry, usb_driver_entry);
507*4882a593Smuzhiyun 	n_ents = ll_entry_count(struct usb_driver_entry, usb_driver_entry);
508*4882a593Smuzhiyun 	for (entry = start; entry != start + n_ents; entry++) {
509*4882a593Smuzhiyun 		const struct usb_device_id *id;
510*4882a593Smuzhiyun 		struct udevice *dev;
511*4882a593Smuzhiyun 		const struct driver *drv;
512*4882a593Smuzhiyun 		struct usb_dev_platdata *plat;
513*4882a593Smuzhiyun 
514*4882a593Smuzhiyun 		for (id = entry->match; id->match_flags; id++) {
515*4882a593Smuzhiyun 			if (!usb_match_one_id(desc, iface, id))
516*4882a593Smuzhiyun 				continue;
517*4882a593Smuzhiyun 
518*4882a593Smuzhiyun 			drv = entry->driver;
519*4882a593Smuzhiyun 			/*
520*4882a593Smuzhiyun 			 * We could pass the descriptor to the driver as
521*4882a593Smuzhiyun 			 * platdata (instead of NULL) and allow its bind()
522*4882a593Smuzhiyun 			 * method to return -ENOENT if it doesn't support this
523*4882a593Smuzhiyun 			 * device. That way we could continue the search to
524*4882a593Smuzhiyun 			 * find another driver. For now this doesn't seem
525*4882a593Smuzhiyun 			 * necesssary, so just bind the first match.
526*4882a593Smuzhiyun 			 */
527*4882a593Smuzhiyun 			ret = device_bind(parent, drv, drv->name, NULL, -1,
528*4882a593Smuzhiyun 					  &dev);
529*4882a593Smuzhiyun 			if (ret)
530*4882a593Smuzhiyun 				goto error;
531*4882a593Smuzhiyun 			debug("%s: Match found: %s\n", __func__, drv->name);
532*4882a593Smuzhiyun 			dev->driver_data = id->driver_info;
533*4882a593Smuzhiyun 			plat = dev_get_parent_platdata(dev);
534*4882a593Smuzhiyun 			plat->id = *id;
535*4882a593Smuzhiyun 			*devp = dev;
536*4882a593Smuzhiyun 			return 0;
537*4882a593Smuzhiyun 		}
538*4882a593Smuzhiyun 	}
539*4882a593Smuzhiyun 
540*4882a593Smuzhiyun 	/* Bind a generic driver so that the device can be used */
541*4882a593Smuzhiyun 	snprintf(name, sizeof(name), "generic_bus_%x_dev_%x", bus_seq, devnum);
542*4882a593Smuzhiyun 	str = strdup(name);
543*4882a593Smuzhiyun 	if (!str)
544*4882a593Smuzhiyun 		return -ENOMEM;
545*4882a593Smuzhiyun 	ret = device_bind_driver(parent, "usb_dev_generic_drv", str, devp);
546*4882a593Smuzhiyun 
547*4882a593Smuzhiyun error:
548*4882a593Smuzhiyun 	debug("%s: No match found: %d\n", __func__, ret);
549*4882a593Smuzhiyun 	return ret;
550*4882a593Smuzhiyun }
551*4882a593Smuzhiyun 
552*4882a593Smuzhiyun /**
553*4882a593Smuzhiyun  * usb_find_child() - Find an existing device which matches our needs
554*4882a593Smuzhiyun  *
555*4882a593Smuzhiyun  *
556*4882a593Smuzhiyun  */
usb_find_child(struct udevice * parent,struct usb_device_descriptor * desc,struct usb_interface_descriptor * iface,struct udevice ** devp)557*4882a593Smuzhiyun static int usb_find_child(struct udevice *parent,
558*4882a593Smuzhiyun 			  struct usb_device_descriptor *desc,
559*4882a593Smuzhiyun 			  struct usb_interface_descriptor *iface,
560*4882a593Smuzhiyun 			  struct udevice **devp)
561*4882a593Smuzhiyun {
562*4882a593Smuzhiyun 	struct udevice *dev;
563*4882a593Smuzhiyun 
564*4882a593Smuzhiyun 	*devp = NULL;
565*4882a593Smuzhiyun 	for (device_find_first_child(parent, &dev);
566*4882a593Smuzhiyun 	     dev;
567*4882a593Smuzhiyun 	     device_find_next_child(&dev)) {
568*4882a593Smuzhiyun 		struct usb_dev_platdata *plat = dev_get_parent_platdata(dev);
569*4882a593Smuzhiyun 
570*4882a593Smuzhiyun 		/* If this device is already in use, skip it */
571*4882a593Smuzhiyun 		if (device_active(dev))
572*4882a593Smuzhiyun 			continue;
573*4882a593Smuzhiyun 		debug("   %s: name='%s', plat=%d, desc=%d\n", __func__,
574*4882a593Smuzhiyun 		      dev->name, plat->id.bDeviceClass, desc->bDeviceClass);
575*4882a593Smuzhiyun 		if (usb_match_one_id(desc, iface, &plat->id)) {
576*4882a593Smuzhiyun 			*devp = dev;
577*4882a593Smuzhiyun 			return 0;
578*4882a593Smuzhiyun 		}
579*4882a593Smuzhiyun 	}
580*4882a593Smuzhiyun 
581*4882a593Smuzhiyun 	return -ENOENT;
582*4882a593Smuzhiyun }
583*4882a593Smuzhiyun 
usb_scan_device(struct udevice * parent,int port,enum usb_device_speed speed,struct udevice ** devp)584*4882a593Smuzhiyun int usb_scan_device(struct udevice *parent, int port,
585*4882a593Smuzhiyun 		    enum usb_device_speed speed, struct udevice **devp)
586*4882a593Smuzhiyun {
587*4882a593Smuzhiyun 	struct udevice *dev;
588*4882a593Smuzhiyun 	bool created = false;
589*4882a593Smuzhiyun 	struct usb_dev_platdata *plat;
590*4882a593Smuzhiyun 	struct usb_bus_priv *priv;
591*4882a593Smuzhiyun 	struct usb_device *parent_udev;
592*4882a593Smuzhiyun 	int ret;
593*4882a593Smuzhiyun 	ALLOC_CACHE_ALIGN_BUFFER(struct usb_device, udev, 1);
594*4882a593Smuzhiyun 	struct usb_interface_descriptor *iface = &udev->config.if_desc[0].desc;
595*4882a593Smuzhiyun 
596*4882a593Smuzhiyun 	*devp = NULL;
597*4882a593Smuzhiyun 	memset(udev, '\0', sizeof(*udev));
598*4882a593Smuzhiyun 	udev->controller_dev = usb_get_bus(parent);
599*4882a593Smuzhiyun 	priv = dev_get_uclass_priv(udev->controller_dev);
600*4882a593Smuzhiyun 
601*4882a593Smuzhiyun 	/*
602*4882a593Smuzhiyun 	 * Somewhat nasty, this. We create a local device and use the normal
603*4882a593Smuzhiyun 	 * USB stack to read its descriptor. Then we know what type of device
604*4882a593Smuzhiyun 	 * to create for real.
605*4882a593Smuzhiyun 	 *
606*4882a593Smuzhiyun 	 * udev->dev is set to the parent, since we don't have a real device
607*4882a593Smuzhiyun 	 * yet. The USB stack should not access udev.dev anyway, except perhaps
608*4882a593Smuzhiyun 	 * to find the controller, and the controller will either be @parent,
609*4882a593Smuzhiyun 	 * or some parent of @parent.
610*4882a593Smuzhiyun 	 *
611*4882a593Smuzhiyun 	 * Another option might be to create the device as a generic USB
612*4882a593Smuzhiyun 	 * device, then morph it into the correct one when we know what it
613*4882a593Smuzhiyun 	 * should be. This means that a generic USB device would morph into
614*4882a593Smuzhiyun 	 * a network controller, or a USB flash stick, for example. However,
615*4882a593Smuzhiyun 	 * we don't support such morphing and it isn't clear that it would
616*4882a593Smuzhiyun 	 * be easy to do.
617*4882a593Smuzhiyun 	 *
618*4882a593Smuzhiyun 	 * Yet another option is to split out the USB stack parts of udev
619*4882a593Smuzhiyun 	 * into something like a 'struct urb' (as Linux does) which can exist
620*4882a593Smuzhiyun 	 * independently of any device. This feels cleaner, but calls for quite
621*4882a593Smuzhiyun 	 * a big change to the USB stack.
622*4882a593Smuzhiyun 	 *
623*4882a593Smuzhiyun 	 * For now, the approach is to set up an empty udev, read its
624*4882a593Smuzhiyun 	 * descriptor and assign it an address, then bind a real device and
625*4882a593Smuzhiyun 	 * stash the resulting information into the device's parent
626*4882a593Smuzhiyun 	 * platform data. Then when we probe it, usb_child_pre_probe() is called
627*4882a593Smuzhiyun 	 * and it will pull the information out of the stash.
628*4882a593Smuzhiyun 	 */
629*4882a593Smuzhiyun 	udev->dev = parent;
630*4882a593Smuzhiyun 	udev->speed = speed;
631*4882a593Smuzhiyun 	udev->devnum = priv->next_addr + 1;
632*4882a593Smuzhiyun 	udev->portnr = port;
633*4882a593Smuzhiyun 	debug("Calling usb_setup_device(), portnr=%d\n", udev->portnr);
634*4882a593Smuzhiyun 	parent_udev = device_get_uclass_id(parent) == UCLASS_USB_HUB ?
635*4882a593Smuzhiyun 		dev_get_parent_priv(parent) : NULL;
636*4882a593Smuzhiyun 	ret = usb_setup_device(udev, priv->desc_before_addr, parent_udev);
637*4882a593Smuzhiyun 	debug("read_descriptor for '%s': ret=%d\n", parent->name, ret);
638*4882a593Smuzhiyun 	if (ret)
639*4882a593Smuzhiyun 		return ret;
640*4882a593Smuzhiyun 	ret = usb_find_child(parent, &udev->descriptor, iface, &dev);
641*4882a593Smuzhiyun 	debug("** usb_find_child returns %d\n", ret);
642*4882a593Smuzhiyun 	if (ret) {
643*4882a593Smuzhiyun 		if (ret != -ENOENT)
644*4882a593Smuzhiyun 			return ret;
645*4882a593Smuzhiyun 		ret = usb_find_and_bind_driver(parent, &udev->descriptor, iface,
646*4882a593Smuzhiyun 					       udev->controller_dev->seq,
647*4882a593Smuzhiyun 					       udev->devnum, &dev);
648*4882a593Smuzhiyun 		if (ret)
649*4882a593Smuzhiyun 			return ret;
650*4882a593Smuzhiyun 		created = true;
651*4882a593Smuzhiyun 	}
652*4882a593Smuzhiyun 	plat = dev_get_parent_platdata(dev);
653*4882a593Smuzhiyun 	debug("%s: Probing '%s', plat=%p\n", __func__, dev->name, plat);
654*4882a593Smuzhiyun 	plat->devnum = udev->devnum;
655*4882a593Smuzhiyun 	plat->udev = udev;
656*4882a593Smuzhiyun 	priv->next_addr++;
657*4882a593Smuzhiyun 	ret = device_probe(dev);
658*4882a593Smuzhiyun 	if (ret) {
659*4882a593Smuzhiyun 		debug("%s: Device '%s' probe failed\n", __func__, dev->name);
660*4882a593Smuzhiyun 		priv->next_addr--;
661*4882a593Smuzhiyun 		if (created)
662*4882a593Smuzhiyun 			device_unbind(dev);
663*4882a593Smuzhiyun 		return ret;
664*4882a593Smuzhiyun 	}
665*4882a593Smuzhiyun 	*devp = dev;
666*4882a593Smuzhiyun 
667*4882a593Smuzhiyun 	return 0;
668*4882a593Smuzhiyun }
669*4882a593Smuzhiyun 
670*4882a593Smuzhiyun /*
671*4882a593Smuzhiyun  * Detect if a USB device has been plugged or unplugged.
672*4882a593Smuzhiyun  */
usb_detect_change(void)673*4882a593Smuzhiyun int usb_detect_change(void)
674*4882a593Smuzhiyun {
675*4882a593Smuzhiyun 	struct udevice *hub;
676*4882a593Smuzhiyun 	struct uclass *uc;
677*4882a593Smuzhiyun 	int change = 0;
678*4882a593Smuzhiyun 	int ret;
679*4882a593Smuzhiyun 
680*4882a593Smuzhiyun 	ret = uclass_get(UCLASS_USB_HUB, &uc);
681*4882a593Smuzhiyun 	if (ret)
682*4882a593Smuzhiyun 		return ret;
683*4882a593Smuzhiyun 
684*4882a593Smuzhiyun 	uclass_foreach_dev(hub, uc) {
685*4882a593Smuzhiyun 		struct usb_device *udev;
686*4882a593Smuzhiyun 		struct udevice *dev;
687*4882a593Smuzhiyun 
688*4882a593Smuzhiyun 		if (!device_active(hub))
689*4882a593Smuzhiyun 			continue;
690*4882a593Smuzhiyun 		for (device_find_first_child(hub, &dev);
691*4882a593Smuzhiyun 		     dev;
692*4882a593Smuzhiyun 		     device_find_next_child(&dev)) {
693*4882a593Smuzhiyun 			struct usb_port_status status;
694*4882a593Smuzhiyun 
695*4882a593Smuzhiyun 			if (!device_active(dev))
696*4882a593Smuzhiyun 				continue;
697*4882a593Smuzhiyun 
698*4882a593Smuzhiyun 			udev = dev_get_parent_priv(dev);
699*4882a593Smuzhiyun 			if (usb_get_port_status(udev, udev->portnr, &status)
700*4882a593Smuzhiyun 					< 0)
701*4882a593Smuzhiyun 				/* USB request failed */
702*4882a593Smuzhiyun 				continue;
703*4882a593Smuzhiyun 
704*4882a593Smuzhiyun 			if (le16_to_cpu(status.wPortChange) &
705*4882a593Smuzhiyun 			    USB_PORT_STAT_C_CONNECTION)
706*4882a593Smuzhiyun 				change++;
707*4882a593Smuzhiyun 		}
708*4882a593Smuzhiyun 	}
709*4882a593Smuzhiyun 
710*4882a593Smuzhiyun 	return change;
711*4882a593Smuzhiyun }
712*4882a593Smuzhiyun 
usb_child_post_bind(struct udevice * dev)713*4882a593Smuzhiyun static int usb_child_post_bind(struct udevice *dev)
714*4882a593Smuzhiyun {
715*4882a593Smuzhiyun 	struct usb_dev_platdata *plat = dev_get_parent_platdata(dev);
716*4882a593Smuzhiyun 	int val;
717*4882a593Smuzhiyun 
718*4882a593Smuzhiyun 	if (!dev_of_valid(dev))
719*4882a593Smuzhiyun 		return 0;
720*4882a593Smuzhiyun 
721*4882a593Smuzhiyun 	/* We only support matching a few things */
722*4882a593Smuzhiyun 	val = dev_read_u32_default(dev, "usb,device-class", -1);
723*4882a593Smuzhiyun 	if (val != -1) {
724*4882a593Smuzhiyun 		plat->id.match_flags |= USB_DEVICE_ID_MATCH_DEV_CLASS;
725*4882a593Smuzhiyun 		plat->id.bDeviceClass = val;
726*4882a593Smuzhiyun 	}
727*4882a593Smuzhiyun 	val = dev_read_u32_default(dev, "usb,interface-class", -1);
728*4882a593Smuzhiyun 	if (val != -1) {
729*4882a593Smuzhiyun 		plat->id.match_flags |= USB_DEVICE_ID_MATCH_INT_CLASS;
730*4882a593Smuzhiyun 		plat->id.bInterfaceClass = val;
731*4882a593Smuzhiyun 	}
732*4882a593Smuzhiyun 
733*4882a593Smuzhiyun 	return 0;
734*4882a593Smuzhiyun }
735*4882a593Smuzhiyun 
usb_get_bus(struct udevice * dev)736*4882a593Smuzhiyun struct udevice *usb_get_bus(struct udevice *dev)
737*4882a593Smuzhiyun {
738*4882a593Smuzhiyun 	struct udevice *bus;
739*4882a593Smuzhiyun 
740*4882a593Smuzhiyun 	for (bus = dev; bus && device_get_uclass_id(bus) != UCLASS_USB; )
741*4882a593Smuzhiyun 		bus = bus->parent;
742*4882a593Smuzhiyun 	if (!bus) {
743*4882a593Smuzhiyun 		/* By design this cannot happen */
744*4882a593Smuzhiyun 		assert(bus);
745*4882a593Smuzhiyun 		debug("USB HUB '%s' does not have a controller\n", dev->name);
746*4882a593Smuzhiyun 	}
747*4882a593Smuzhiyun 
748*4882a593Smuzhiyun 	return bus;
749*4882a593Smuzhiyun }
750*4882a593Smuzhiyun 
usb_child_pre_probe(struct udevice * dev)751*4882a593Smuzhiyun int usb_child_pre_probe(struct udevice *dev)
752*4882a593Smuzhiyun {
753*4882a593Smuzhiyun 	struct usb_device *udev = dev_get_parent_priv(dev);
754*4882a593Smuzhiyun 	struct usb_dev_platdata *plat = dev_get_parent_platdata(dev);
755*4882a593Smuzhiyun 	int ret;
756*4882a593Smuzhiyun 
757*4882a593Smuzhiyun 	if (plat->udev) {
758*4882a593Smuzhiyun 		/*
759*4882a593Smuzhiyun 		 * Copy over all the values set in the on stack struct
760*4882a593Smuzhiyun 		 * usb_device in usb_scan_device() to our final struct
761*4882a593Smuzhiyun 		 * usb_device for this dev.
762*4882a593Smuzhiyun 		 */
763*4882a593Smuzhiyun 		*udev = *(plat->udev);
764*4882a593Smuzhiyun 		/* And clear plat->udev as it will not be valid for long */
765*4882a593Smuzhiyun 		plat->udev = NULL;
766*4882a593Smuzhiyun 		udev->dev = dev;
767*4882a593Smuzhiyun 	} else {
768*4882a593Smuzhiyun 		/*
769*4882a593Smuzhiyun 		 * This happens with devices which are explicitly bound
770*4882a593Smuzhiyun 		 * instead of being discovered through usb_scan_device()
771*4882a593Smuzhiyun 		 * such as sandbox emul devices.
772*4882a593Smuzhiyun 		 */
773*4882a593Smuzhiyun 		udev->dev = dev;
774*4882a593Smuzhiyun 		udev->controller_dev = usb_get_bus(dev);
775*4882a593Smuzhiyun 		udev->devnum = plat->devnum;
776*4882a593Smuzhiyun 
777*4882a593Smuzhiyun 		/*
778*4882a593Smuzhiyun 		 * udev did not go through usb_scan_device(), so we need to
779*4882a593Smuzhiyun 		 * select the config and read the config descriptors.
780*4882a593Smuzhiyun 		 */
781*4882a593Smuzhiyun 		ret = usb_select_config(udev);
782*4882a593Smuzhiyun 		if (ret)
783*4882a593Smuzhiyun 			return ret;
784*4882a593Smuzhiyun 	}
785*4882a593Smuzhiyun 
786*4882a593Smuzhiyun 	return 0;
787*4882a593Smuzhiyun }
788*4882a593Smuzhiyun 
789*4882a593Smuzhiyun UCLASS_DRIVER(usb) = {
790*4882a593Smuzhiyun 	.id		= UCLASS_USB,
791*4882a593Smuzhiyun 	.name		= "usb",
792*4882a593Smuzhiyun 	.flags		= DM_UC_FLAG_SEQ_ALIAS,
793*4882a593Smuzhiyun 	.post_bind	= dm_scan_fdt_dev,
794*4882a593Smuzhiyun 	.priv_auto_alloc_size = sizeof(struct usb_uclass_priv),
795*4882a593Smuzhiyun 	.per_child_auto_alloc_size = sizeof(struct usb_device),
796*4882a593Smuzhiyun 	.per_device_auto_alloc_size = sizeof(struct usb_bus_priv),
797*4882a593Smuzhiyun 	.child_post_bind = usb_child_post_bind,
798*4882a593Smuzhiyun 	.child_pre_probe = usb_child_pre_probe,
799*4882a593Smuzhiyun 	.per_child_platdata_auto_alloc_size = sizeof(struct usb_dev_platdata),
800*4882a593Smuzhiyun };
801*4882a593Smuzhiyun 
802*4882a593Smuzhiyun UCLASS_DRIVER(usb_dev_generic) = {
803*4882a593Smuzhiyun 	.id		= UCLASS_USB_DEV_GENERIC,
804*4882a593Smuzhiyun 	.name		= "usb_dev_generic",
805*4882a593Smuzhiyun };
806*4882a593Smuzhiyun 
807*4882a593Smuzhiyun U_BOOT_DRIVER(usb_dev_generic_drv) = {
808*4882a593Smuzhiyun 	.id		= UCLASS_USB_DEV_GENERIC,
809*4882a593Smuzhiyun 	.name		= "usb_dev_generic_drv",
810*4882a593Smuzhiyun };
811