forked from mirrors/linux
		
	Merge branch 'for-next' of master.kernel.org:/pub/scm/linux/kernel/git/balbi/usb into usb-next
* 'for-next' of master.kernel.org:/pub/scm/linux/kernel/git/balbi/usb: usb: gadget: m66592-udc: add pullup function usb: gadget: m66592-udc: add function for external controller usb: gadget: r8a66597-udc: add pullup function usb: gadget: zero: add superspeed support usb: gadget: add SS descriptors to Ethernet gadget usb: gadget: r8a66597-udc: add support for TEST_MODE usb: gadget: m66592-udc: add support for TEST_MODE usb: gadget: r8a66597-udc: Make BUSWAIT configurable through platform data usb: gadget: r8a66597-udc: fix cannot connect after rmmod gadget driver usb: update email address in r8a66597-udc and m66592-udc usb: musb: restore INDEX register in resume path usb: gadget: fix up depencies usb: gadget: fusb300_udc: fix compile warnings usb: gadget: ci13xx_udc.c: fix compile warning usb: gadget: net2272: fix compile warnings usb: gadget: langwell_udc: fix compile warnings usb: gadget: fusb300_udc: drop dead code
This commit is contained in:
		
						commit
						18fbb93fbe
					
				
					 21 changed files with 580 additions and 142 deletions
				
			
		|  | @ -157,6 +157,7 @@ config USB_FSL_USB2 | |||
| 
 | ||||
| config USB_FUSB300 | ||||
| 	tristate "Faraday FUSB300 USB Peripheral Controller" | ||||
| 	depends on !PHYS_ADDR_T_64BIT | ||||
| 	select USB_GADGET_DUALSPEED | ||||
| 	help | ||||
| 	   Faraday usb device controller FUSB300 driver | ||||
|  | @ -427,6 +428,7 @@ config USB_GOKU | |||
| config USB_LANGWELL | ||||
| 	tristate "Intel Langwell USB Device Controller" | ||||
| 	depends on PCI | ||||
| 	depends on !PHYS_ADDR_T_64BIT | ||||
| 	select USB_GADGET_DUALSPEED | ||||
| 	help | ||||
| 	   Intel Langwell USB Device Controller is a High-Speed USB | ||||
|  |  | |||
|  | @ -1214,12 +1214,13 @@ static DEVICE_ATTR(qheads, S_IRUSR, show_qheads, NULL); | |||
|  * | ||||
|  * Check "device.h" for details | ||||
|  */ | ||||
| #define DUMP_ENTRIES	512 | ||||
| static ssize_t show_registers(struct device *dev, | ||||
| 			      struct device_attribute *attr, char *buf) | ||||
| { | ||||
| 	struct ci13xxx *udc = container_of(dev, struct ci13xxx, gadget.dev); | ||||
| 	unsigned long flags; | ||||
| 	u32 dump[512]; | ||||
| 	u32 *dump; | ||||
| 	unsigned i, k, n = 0; | ||||
| 
 | ||||
| 	dbg_trace("[%s] %p\n", __func__, buf); | ||||
|  | @ -1228,8 +1229,14 @@ static ssize_t show_registers(struct device *dev, | |||
| 		return 0; | ||||
| 	} | ||||
| 
 | ||||
| 	dump = kmalloc(sizeof(u32) * DUMP_ENTRIES, GFP_KERNEL); | ||||
| 	if (!dump) { | ||||
| 		dev_err(dev, "%s: out of memory\n", __func__); | ||||
| 		return 0; | ||||
| 	} | ||||
| 
 | ||||
| 	spin_lock_irqsave(udc->lock, flags); | ||||
| 	k = hw_register_read(dump, sizeof(dump)/sizeof(u32)); | ||||
| 	k = hw_register_read(dump, DUMP_ENTRIES); | ||||
| 	spin_unlock_irqrestore(udc->lock, flags); | ||||
| 
 | ||||
| 	for (i = 0; i < k; i++) { | ||||
|  | @ -1237,6 +1244,7 @@ static ssize_t show_registers(struct device *dev, | |||
| 			       "reg[0x%04X] = 0x%08X\n", | ||||
| 			       i * (unsigned)sizeof(u32), dump[i]); | ||||
| 	} | ||||
| 	kfree(dump); | ||||
| 
 | ||||
| 	return n; | ||||
| } | ||||
|  |  | |||
|  | @ -401,7 +401,7 @@ static struct usb_composite_driver eth_driver = { | |||
| 	.name		= "g_ether", | ||||
| 	.dev		= &device_desc, | ||||
| 	.strings	= dev_strings, | ||||
| 	.max_speed	= USB_SPEED_HIGH, | ||||
| 	.max_speed	= USB_SPEED_SUPER, | ||||
| 	.unbind		= __exit_p(eth_unbind), | ||||
| }; | ||||
| 
 | ||||
|  |  | |||
|  | @ -77,7 +77,9 @@ static inline struct f_ecm *func_to_ecm(struct usb_function *f) | |||
| /* peak (theoretical) bulk transfer rate in bits-per-second */ | ||||
| static inline unsigned ecm_bitrate(struct usb_gadget *g) | ||||
| { | ||||
| 	if (gadget_is_dualspeed(g) && g->speed == USB_SPEED_HIGH) | ||||
| 	if (gadget_is_superspeed(g) && g->speed == USB_SPEED_SUPER) | ||||
| 		return 13 * 1024 * 8 * 1000 * 8; | ||||
| 	else if (gadget_is_dualspeed(g) && g->speed == USB_SPEED_HIGH) | ||||
| 		return 13 * 512 * 8 * 1000 * 8; | ||||
| 	else | ||||
| 		return 19 * 64 * 1 * 1000 * 8; | ||||
|  | @ -210,8 +212,10 @@ static struct usb_descriptor_header *ecm_fs_function[] = { | |||
| 	(struct usb_descriptor_header *) &ecm_header_desc, | ||||
| 	(struct usb_descriptor_header *) &ecm_union_desc, | ||||
| 	(struct usb_descriptor_header *) &ecm_desc, | ||||
| 
 | ||||
| 	/* NOTE: status endpoint might need to be removed */ | ||||
| 	(struct usb_descriptor_header *) &fs_ecm_notify_desc, | ||||
| 
 | ||||
| 	/* data interface, altsettings 0 and 1 */ | ||||
| 	(struct usb_descriptor_header *) &ecm_data_nop_intf, | ||||
| 	(struct usb_descriptor_header *) &ecm_data_intf, | ||||
|  | @ -231,6 +235,7 @@ static struct usb_endpoint_descriptor hs_ecm_notify_desc = { | |||
| 	.wMaxPacketSize =	cpu_to_le16(ECM_STATUS_BYTECOUNT), | ||||
| 	.bInterval =		LOG2_STATUS_INTERVAL_MSEC + 4, | ||||
| }; | ||||
| 
 | ||||
| static struct usb_endpoint_descriptor hs_ecm_in_desc = { | ||||
| 	.bLength =		USB_DT_ENDPOINT_SIZE, | ||||
| 	.bDescriptorType =	USB_DT_ENDPOINT, | ||||
|  | @ -255,8 +260,10 @@ static struct usb_descriptor_header *ecm_hs_function[] = { | |||
| 	(struct usb_descriptor_header *) &ecm_header_desc, | ||||
| 	(struct usb_descriptor_header *) &ecm_union_desc, | ||||
| 	(struct usb_descriptor_header *) &ecm_desc, | ||||
| 
 | ||||
| 	/* NOTE: status endpoint might need to be removed */ | ||||
| 	(struct usb_descriptor_header *) &hs_ecm_notify_desc, | ||||
| 
 | ||||
| 	/* data interface, altsettings 0 and 1 */ | ||||
| 	(struct usb_descriptor_header *) &ecm_data_nop_intf, | ||||
| 	(struct usb_descriptor_header *) &ecm_data_intf, | ||||
|  | @ -265,6 +272,76 @@ static struct usb_descriptor_header *ecm_hs_function[] = { | |||
| 	NULL, | ||||
| }; | ||||
| 
 | ||||
| /* super speed support: */ | ||||
| 
 | ||||
| static struct usb_endpoint_descriptor ss_ecm_notify_desc = { | ||||
| 	.bLength =		USB_DT_ENDPOINT_SIZE, | ||||
| 	.bDescriptorType =	USB_DT_ENDPOINT, | ||||
| 
 | ||||
| 	.bEndpointAddress =	USB_DIR_IN, | ||||
| 	.bmAttributes =		USB_ENDPOINT_XFER_INT, | ||||
| 	.wMaxPacketSize =	cpu_to_le16(ECM_STATUS_BYTECOUNT), | ||||
| 	.bInterval =		LOG2_STATUS_INTERVAL_MSEC + 4, | ||||
| }; | ||||
| 
 | ||||
| static struct usb_ss_ep_comp_descriptor ss_ecm_intr_comp_desc = { | ||||
| 	.bLength =		sizeof ss_ecm_intr_comp_desc, | ||||
| 	.bDescriptorType =	USB_DT_SS_ENDPOINT_COMP, | ||||
| 
 | ||||
| 	/* the following 3 values can be tweaked if necessary */ | ||||
| 	/* .bMaxBurst =		0, */ | ||||
| 	/* .bmAttributes =	0, */ | ||||
| 	.wBytesPerInterval =	cpu_to_le16(ECM_STATUS_BYTECOUNT), | ||||
| }; | ||||
| 
 | ||||
| static struct usb_endpoint_descriptor ss_ecm_in_desc = { | ||||
| 	.bLength =		USB_DT_ENDPOINT_SIZE, | ||||
| 	.bDescriptorType =	USB_DT_ENDPOINT, | ||||
| 
 | ||||
| 	.bEndpointAddress =	USB_DIR_IN, | ||||
| 	.bmAttributes =		USB_ENDPOINT_XFER_BULK, | ||||
| 	.wMaxPacketSize =	cpu_to_le16(1024), | ||||
| }; | ||||
| 
 | ||||
| static struct usb_endpoint_descriptor ss_ecm_out_desc = { | ||||
| 	.bLength =		USB_DT_ENDPOINT_SIZE, | ||||
| 	.bDescriptorType =	USB_DT_ENDPOINT, | ||||
| 
 | ||||
| 	.bEndpointAddress =	USB_DIR_OUT, | ||||
| 	.bmAttributes =		USB_ENDPOINT_XFER_BULK, | ||||
| 	.wMaxPacketSize =	cpu_to_le16(1024), | ||||
| }; | ||||
| 
 | ||||
| static struct usb_ss_ep_comp_descriptor ss_ecm_bulk_comp_desc = { | ||||
| 	.bLength =		sizeof ss_ecm_bulk_comp_desc, | ||||
| 	.bDescriptorType =	USB_DT_SS_ENDPOINT_COMP, | ||||
| 
 | ||||
| 	/* the following 2 values can be tweaked if necessary */ | ||||
| 	/* .bMaxBurst =		0, */ | ||||
| 	/* .bmAttributes =	0, */ | ||||
| }; | ||||
| 
 | ||||
| static struct usb_descriptor_header *ecm_ss_function[] = { | ||||
| 	/* CDC ECM control descriptors */ | ||||
| 	(struct usb_descriptor_header *) &ecm_control_intf, | ||||
| 	(struct usb_descriptor_header *) &ecm_header_desc, | ||||
| 	(struct usb_descriptor_header *) &ecm_union_desc, | ||||
| 	(struct usb_descriptor_header *) &ecm_desc, | ||||
| 
 | ||||
| 	/* NOTE: status endpoint might need to be removed */ | ||||
| 	(struct usb_descriptor_header *) &ss_ecm_notify_desc, | ||||
| 	(struct usb_descriptor_header *) &ss_ecm_intr_comp_desc, | ||||
| 
 | ||||
| 	/* data interface, altsettings 0 and 1 */ | ||||
| 	(struct usb_descriptor_header *) &ecm_data_nop_intf, | ||||
| 	(struct usb_descriptor_header *) &ecm_data_intf, | ||||
| 	(struct usb_descriptor_header *) &ss_ecm_in_desc, | ||||
| 	(struct usb_descriptor_header *) &ss_ecm_bulk_comp_desc, | ||||
| 	(struct usb_descriptor_header *) &ss_ecm_out_desc, | ||||
| 	(struct usb_descriptor_header *) &ss_ecm_bulk_comp_desc, | ||||
| 	NULL, | ||||
| }; | ||||
| 
 | ||||
| /* string descriptors: */ | ||||
| 
 | ||||
| static struct usb_string ecm_string_defs[] = { | ||||
|  | @ -679,6 +756,20 @@ ecm_bind(struct usb_configuration *c, struct usb_function *f) | |||
| 			goto fail; | ||||
| 	} | ||||
| 
 | ||||
| 	if (gadget_is_superspeed(c->cdev->gadget)) { | ||||
| 		ss_ecm_in_desc.bEndpointAddress = | ||||
| 				fs_ecm_in_desc.bEndpointAddress; | ||||
| 		ss_ecm_out_desc.bEndpointAddress = | ||||
| 				fs_ecm_out_desc.bEndpointAddress; | ||||
| 		ss_ecm_notify_desc.bEndpointAddress = | ||||
| 				fs_ecm_notify_desc.bEndpointAddress; | ||||
| 
 | ||||
| 		/* copy descriptors, and track endpoint copies */ | ||||
| 		f->ss_descriptors = usb_copy_descriptors(ecm_ss_function); | ||||
| 		if (!f->ss_descriptors) | ||||
| 			goto fail; | ||||
| 	} | ||||
| 
 | ||||
| 	/* NOTE:  all that is done without knowing or caring about
 | ||||
| 	 * the network link ... which is unavailable to this code | ||||
| 	 * until we're activated via set_alt(). | ||||
|  | @ -688,6 +779,7 @@ ecm_bind(struct usb_configuration *c, struct usb_function *f) | |||
| 	ecm->port.close = ecm_close; | ||||
| 
 | ||||
| 	DBG(cdev, "CDC Ethernet: %s speed IN/%s OUT/%s NOTIFY/%s\n", | ||||
| 			gadget_is_superspeed(c->cdev->gadget) ? "super" : | ||||
| 			gadget_is_dualspeed(c->cdev->gadget) ? "dual" : "full", | ||||
| 			ecm->port.in_ep->name, ecm->port.out_ep->name, | ||||
| 			ecm->notify->name); | ||||
|  | @ -696,6 +788,8 @@ ecm_bind(struct usb_configuration *c, struct usb_function *f) | |||
| fail: | ||||
| 	if (f->descriptors) | ||||
| 		usb_free_descriptors(f->descriptors); | ||||
| 	if (f->hs_descriptors) | ||||
| 		usb_free_descriptors(f->hs_descriptors); | ||||
| 
 | ||||
| 	if (ecm->notify_req) { | ||||
| 		kfree(ecm->notify_req->buf); | ||||
|  | @ -722,6 +816,8 @@ ecm_unbind(struct usb_configuration *c, struct usb_function *f) | |||
| 
 | ||||
| 	DBG(c->cdev, "ecm unbind\n"); | ||||
| 
 | ||||
| 	if (gadget_is_superspeed(c->cdev->gadget)) | ||||
| 		usb_free_descriptors(f->ss_descriptors); | ||||
| 	if (gadget_is_dualspeed(c->cdev->gadget)) | ||||
| 		usb_free_descriptors(f->hs_descriptors); | ||||
| 	usb_free_descriptors(f->descriptors); | ||||
|  |  | |||
|  | @ -115,6 +115,45 @@ static struct usb_descriptor_header *eem_hs_function[] __initdata = { | |||
| 	NULL, | ||||
| }; | ||||
| 
 | ||||
| /* super speed support: */ | ||||
| 
 | ||||
| static struct usb_endpoint_descriptor eem_ss_in_desc __initdata = { | ||||
| 	.bLength =		USB_DT_ENDPOINT_SIZE, | ||||
| 	.bDescriptorType =	USB_DT_ENDPOINT, | ||||
| 
 | ||||
| 	.bEndpointAddress =	USB_DIR_IN, | ||||
| 	.bmAttributes =		USB_ENDPOINT_XFER_BULK, | ||||
| 	.wMaxPacketSize =	cpu_to_le16(1024), | ||||
| }; | ||||
| 
 | ||||
| static struct usb_endpoint_descriptor eem_ss_out_desc __initdata = { | ||||
| 	.bLength =		USB_DT_ENDPOINT_SIZE, | ||||
| 	.bDescriptorType =	USB_DT_ENDPOINT, | ||||
| 
 | ||||
| 	.bEndpointAddress =	USB_DIR_OUT, | ||||
| 	.bmAttributes =		USB_ENDPOINT_XFER_BULK, | ||||
| 	.wMaxPacketSize =	cpu_to_le16(1024), | ||||
| }; | ||||
| 
 | ||||
| static struct usb_ss_ep_comp_descriptor eem_ss_bulk_comp_desc __initdata = { | ||||
| 	.bLength =		sizeof eem_ss_bulk_comp_desc, | ||||
| 	.bDescriptorType =	USB_DT_SS_ENDPOINT_COMP, | ||||
| 
 | ||||
| 	/* the following 2 values can be tweaked if necessary */ | ||||
| 	/* .bMaxBurst =		0, */ | ||||
| 	/* .bmAttributes =	0, */ | ||||
| }; | ||||
| 
 | ||||
| static struct usb_descriptor_header *eem_ss_function[] __initdata = { | ||||
| 	/* CDC EEM control descriptors */ | ||||
| 	(struct usb_descriptor_header *) &eem_intf, | ||||
| 	(struct usb_descriptor_header *) &eem_ss_in_desc, | ||||
| 	(struct usb_descriptor_header *) &eem_ss_bulk_comp_desc, | ||||
| 	(struct usb_descriptor_header *) &eem_ss_out_desc, | ||||
| 	(struct usb_descriptor_header *) &eem_ss_bulk_comp_desc, | ||||
| 	NULL, | ||||
| }; | ||||
| 
 | ||||
| /* string descriptors: */ | ||||
| 
 | ||||
| static struct usb_string eem_string_defs[] = { | ||||
|  | @ -265,7 +304,20 @@ eem_bind(struct usb_configuration *c, struct usb_function *f) | |||
| 			goto fail; | ||||
| 	} | ||||
| 
 | ||||
| 	if (gadget_is_superspeed(c->cdev->gadget)) { | ||||
| 		eem_ss_in_desc.bEndpointAddress = | ||||
| 				eem_fs_in_desc.bEndpointAddress; | ||||
| 		eem_ss_out_desc.bEndpointAddress = | ||||
| 				eem_fs_out_desc.bEndpointAddress; | ||||
| 
 | ||||
| 		/* copy descriptors, and track endpoint copies */ | ||||
| 		f->ss_descriptors = usb_copy_descriptors(eem_ss_function); | ||||
| 		if (!f->ss_descriptors) | ||||
| 			goto fail; | ||||
| 	} | ||||
| 
 | ||||
| 	DBG(cdev, "CDC Ethernet (EEM): %s speed IN/%s OUT/%s\n", | ||||
| 			gadget_is_superspeed(c->cdev->gadget) ? "super" : | ||||
| 			gadget_is_dualspeed(c->cdev->gadget) ? "dual" : "full", | ||||
| 			eem->port.in_ep->name, eem->port.out_ep->name); | ||||
| 	return 0; | ||||
|  | @ -273,6 +325,8 @@ eem_bind(struct usb_configuration *c, struct usb_function *f) | |||
| fail: | ||||
| 	if (f->descriptors) | ||||
| 		usb_free_descriptors(f->descriptors); | ||||
| 	if (f->hs_descriptors) | ||||
| 		usb_free_descriptors(f->hs_descriptors); | ||||
| 
 | ||||
| 	/* we might as well release our claims on endpoints */ | ||||
| 	if (eem->port.out_ep->desc) | ||||
|  | @ -292,6 +346,8 @@ eem_unbind(struct usb_configuration *c, struct usb_function *f) | |||
| 
 | ||||
| 	DBG(c->cdev, "eem unbind\n"); | ||||
| 
 | ||||
| 	if (gadget_is_superspeed(c->cdev->gadget)) | ||||
| 		usb_free_descriptors(f->ss_descriptors); | ||||
| 	if (gadget_is_dualspeed(c->cdev->gadget)) | ||||
| 		usb_free_descriptors(f->hs_descriptors); | ||||
| 	usb_free_descriptors(f->descriptors); | ||||
|  |  | |||
|  | @ -118,6 +118,49 @@ static struct usb_descriptor_header *hs_loopback_descs[] = { | |||
| 	NULL, | ||||
| }; | ||||
| 
 | ||||
| /* super speed support: */ | ||||
| 
 | ||||
| static struct usb_endpoint_descriptor ss_loop_source_desc = { | ||||
| 	.bLength =		USB_DT_ENDPOINT_SIZE, | ||||
| 	.bDescriptorType =	USB_DT_ENDPOINT, | ||||
| 
 | ||||
| 	.bmAttributes =		USB_ENDPOINT_XFER_BULK, | ||||
| 	.wMaxPacketSize =	cpu_to_le16(1024), | ||||
| }; | ||||
| 
 | ||||
| struct usb_ss_ep_comp_descriptor ss_loop_source_comp_desc = { | ||||
| 	.bLength =		USB_DT_SS_EP_COMP_SIZE, | ||||
| 	.bDescriptorType =	USB_DT_SS_ENDPOINT_COMP, | ||||
| 	.bMaxBurst =		0, | ||||
| 	.bmAttributes =		0, | ||||
| 	.wBytesPerInterval =	0, | ||||
| }; | ||||
| 
 | ||||
| static struct usb_endpoint_descriptor ss_loop_sink_desc = { | ||||
| 	.bLength =		USB_DT_ENDPOINT_SIZE, | ||||
| 	.bDescriptorType =	USB_DT_ENDPOINT, | ||||
| 
 | ||||
| 	.bmAttributes =		USB_ENDPOINT_XFER_BULK, | ||||
| 	.wMaxPacketSize =	cpu_to_le16(1024), | ||||
| }; | ||||
| 
 | ||||
| struct usb_ss_ep_comp_descriptor ss_loop_sink_comp_desc = { | ||||
| 	.bLength =		USB_DT_SS_EP_COMP_SIZE, | ||||
| 	.bDescriptorType =	USB_DT_SS_ENDPOINT_COMP, | ||||
| 	.bMaxBurst =		0, | ||||
| 	.bmAttributes =		0, | ||||
| 	.wBytesPerInterval =	0, | ||||
| }; | ||||
| 
 | ||||
| static struct usb_descriptor_header *ss_loopback_descs[] = { | ||||
| 	(struct usb_descriptor_header *) &loopback_intf, | ||||
| 	(struct usb_descriptor_header *) &ss_loop_source_desc, | ||||
| 	(struct usb_descriptor_header *) &ss_loop_source_comp_desc, | ||||
| 	(struct usb_descriptor_header *) &ss_loop_sink_desc, | ||||
| 	(struct usb_descriptor_header *) &ss_loop_sink_comp_desc, | ||||
| 	NULL, | ||||
| }; | ||||
| 
 | ||||
| /* function-specific strings: */ | ||||
| 
 | ||||
| static struct usb_string strings_loopback[] = { | ||||
|  | @ -175,8 +218,18 @@ loopback_bind(struct usb_configuration *c, struct usb_function *f) | |||
| 		f->hs_descriptors = hs_loopback_descs; | ||||
| 	} | ||||
| 
 | ||||
| 	/* support super speed hardware */ | ||||
| 	if (gadget_is_superspeed(c->cdev->gadget)) { | ||||
| 		ss_loop_source_desc.bEndpointAddress = | ||||
| 				fs_loop_source_desc.bEndpointAddress; | ||||
| 		ss_loop_sink_desc.bEndpointAddress = | ||||
| 				fs_loop_sink_desc.bEndpointAddress; | ||||
| 		f->ss_descriptors = ss_loopback_descs; | ||||
| 	} | ||||
| 
 | ||||
| 	DBG(cdev, "%s speed %s: IN/%s, OUT/%s\n", | ||||
| 			gadget_is_dualspeed(c->cdev->gadget) ? "dual" : "full", | ||||
| 	    (gadget_is_superspeed(c->cdev->gadget) ? "super" : | ||||
| 	     (gadget_is_dualspeed(c->cdev->gadget) ? "dual" : "full")), | ||||
| 			f->name, loop->in_ep->name, loop->out_ep->name); | ||||
| 	return 0; | ||||
| } | ||||
|  |  | |||
|  | @ -95,7 +95,9 @@ static inline struct f_rndis *func_to_rndis(struct usb_function *f) | |||
| /* peak (theoretical) bulk transfer rate in bits-per-second */ | ||||
| static unsigned int bitrate(struct usb_gadget *g) | ||||
| { | ||||
| 	if (gadget_is_dualspeed(g) && g->speed == USB_SPEED_HIGH) | ||||
| 	if (gadget_is_superspeed(g) && g->speed == USB_SPEED_SUPER) | ||||
| 		return 13 * 1024 * 8 * 1000 * 8; | ||||
| 	else if (gadget_is_dualspeed(g) && g->speed == USB_SPEED_HIGH) | ||||
| 		return 13 * 512 * 8 * 1000 * 8; | ||||
| 	else | ||||
| 		return 19 * 64 * 1 * 1000 * 8; | ||||
|  | @ -216,6 +218,7 @@ static struct usb_endpoint_descriptor fs_out_desc = { | |||
| 
 | ||||
| static struct usb_descriptor_header *eth_fs_function[] = { | ||||
| 	(struct usb_descriptor_header *) &rndis_iad_descriptor, | ||||
| 
 | ||||
| 	/* control interface matches ACM, not Ethernet */ | ||||
| 	(struct usb_descriptor_header *) &rndis_control_intf, | ||||
| 	(struct usb_descriptor_header *) &header_desc, | ||||
|  | @ -223,6 +226,7 @@ static struct usb_descriptor_header *eth_fs_function[] = { | |||
| 	(struct usb_descriptor_header *) &rndis_acm_descriptor, | ||||
| 	(struct usb_descriptor_header *) &rndis_union_desc, | ||||
| 	(struct usb_descriptor_header *) &fs_notify_desc, | ||||
| 
 | ||||
| 	/* data interface has no altsetting */ | ||||
| 	(struct usb_descriptor_header *) &rndis_data_intf, | ||||
| 	(struct usb_descriptor_header *) &fs_in_desc, | ||||
|  | @ -241,6 +245,7 @@ static struct usb_endpoint_descriptor hs_notify_desc = { | |||
| 	.wMaxPacketSize =	cpu_to_le16(STATUS_BYTECOUNT), | ||||
| 	.bInterval =		LOG2_STATUS_INTERVAL_MSEC + 4, | ||||
| }; | ||||
| 
 | ||||
| static struct usb_endpoint_descriptor hs_in_desc = { | ||||
| 	.bLength =		USB_DT_ENDPOINT_SIZE, | ||||
| 	.bDescriptorType =	USB_DT_ENDPOINT, | ||||
|  | @ -261,6 +266,7 @@ static struct usb_endpoint_descriptor hs_out_desc = { | |||
| 
 | ||||
| static struct usb_descriptor_header *eth_hs_function[] = { | ||||
| 	(struct usb_descriptor_header *) &rndis_iad_descriptor, | ||||
| 
 | ||||
| 	/* control interface matches ACM, not Ethernet */ | ||||
| 	(struct usb_descriptor_header *) &rndis_control_intf, | ||||
| 	(struct usb_descriptor_header *) &header_desc, | ||||
|  | @ -268,6 +274,7 @@ static struct usb_descriptor_header *eth_hs_function[] = { | |||
| 	(struct usb_descriptor_header *) &rndis_acm_descriptor, | ||||
| 	(struct usb_descriptor_header *) &rndis_union_desc, | ||||
| 	(struct usb_descriptor_header *) &hs_notify_desc, | ||||
| 
 | ||||
| 	/* data interface has no altsetting */ | ||||
| 	(struct usb_descriptor_header *) &rndis_data_intf, | ||||
| 	(struct usb_descriptor_header *) &hs_in_desc, | ||||
|  | @ -275,6 +282,76 @@ static struct usb_descriptor_header *eth_hs_function[] = { | |||
| 	NULL, | ||||
| }; | ||||
| 
 | ||||
| /* super speed support: */ | ||||
| 
 | ||||
| static struct usb_endpoint_descriptor ss_notify_desc = { | ||||
| 	.bLength =		USB_DT_ENDPOINT_SIZE, | ||||
| 	.bDescriptorType =	USB_DT_ENDPOINT, | ||||
| 
 | ||||
| 	.bEndpointAddress =	USB_DIR_IN, | ||||
| 	.bmAttributes =		USB_ENDPOINT_XFER_INT, | ||||
| 	.wMaxPacketSize =	cpu_to_le16(STATUS_BYTECOUNT), | ||||
| 	.bInterval =		LOG2_STATUS_INTERVAL_MSEC + 4, | ||||
| }; | ||||
| 
 | ||||
| static struct usb_ss_ep_comp_descriptor ss_intr_comp_desc = { | ||||
| 	.bLength =		sizeof ss_intr_comp_desc, | ||||
| 	.bDescriptorType =	USB_DT_SS_ENDPOINT_COMP, | ||||
| 
 | ||||
| 	/* the following 3 values can be tweaked if necessary */ | ||||
| 	/* .bMaxBurst =		0, */ | ||||
| 	/* .bmAttributes =	0, */ | ||||
| 	.wBytesPerInterval =	cpu_to_le16(STATUS_BYTECOUNT), | ||||
| }; | ||||
| 
 | ||||
| static struct usb_endpoint_descriptor ss_in_desc = { | ||||
| 	.bLength =		USB_DT_ENDPOINT_SIZE, | ||||
| 	.bDescriptorType =	USB_DT_ENDPOINT, | ||||
| 
 | ||||
| 	.bEndpointAddress =	USB_DIR_IN, | ||||
| 	.bmAttributes =		USB_ENDPOINT_XFER_BULK, | ||||
| 	.wMaxPacketSize =	cpu_to_le16(1024), | ||||
| }; | ||||
| 
 | ||||
| static struct usb_endpoint_descriptor ss_out_desc = { | ||||
| 	.bLength =		USB_DT_ENDPOINT_SIZE, | ||||
| 	.bDescriptorType =	USB_DT_ENDPOINT, | ||||
| 
 | ||||
| 	.bEndpointAddress =	USB_DIR_OUT, | ||||
| 	.bmAttributes =		USB_ENDPOINT_XFER_BULK, | ||||
| 	.wMaxPacketSize =	cpu_to_le16(1024), | ||||
| }; | ||||
| 
 | ||||
| static struct usb_ss_ep_comp_descriptor ss_bulk_comp_desc = { | ||||
| 	.bLength =		sizeof ss_bulk_comp_desc, | ||||
| 	.bDescriptorType =	USB_DT_SS_ENDPOINT_COMP, | ||||
| 
 | ||||
| 	/* the following 2 values can be tweaked if necessary */ | ||||
| 	/* .bMaxBurst =		0, */ | ||||
| 	/* .bmAttributes =	0, */ | ||||
| }; | ||||
| 
 | ||||
| static struct usb_descriptor_header *eth_ss_function[] = { | ||||
| 	(struct usb_descriptor_header *) &rndis_iad_descriptor, | ||||
| 
 | ||||
| 	/* control interface matches ACM, not Ethernet */ | ||||
| 	(struct usb_descriptor_header *) &rndis_control_intf, | ||||
| 	(struct usb_descriptor_header *) &header_desc, | ||||
| 	(struct usb_descriptor_header *) &call_mgmt_descriptor, | ||||
| 	(struct usb_descriptor_header *) &rndis_acm_descriptor, | ||||
| 	(struct usb_descriptor_header *) &rndis_union_desc, | ||||
| 	(struct usb_descriptor_header *) &ss_notify_desc, | ||||
| 	(struct usb_descriptor_header *) &ss_intr_comp_desc, | ||||
| 
 | ||||
| 	/* data interface has no altsetting */ | ||||
| 	(struct usb_descriptor_header *) &rndis_data_intf, | ||||
| 	(struct usb_descriptor_header *) &ss_in_desc, | ||||
| 	(struct usb_descriptor_header *) &ss_bulk_comp_desc, | ||||
| 	(struct usb_descriptor_header *) &ss_out_desc, | ||||
| 	(struct usb_descriptor_header *) &ss_bulk_comp_desc, | ||||
| 	NULL, | ||||
| }; | ||||
| 
 | ||||
| /* string descriptors: */ | ||||
| 
 | ||||
| static struct usb_string rndis_string_defs[] = { | ||||
|  | @ -670,11 +747,24 @@ rndis_bind(struct usb_configuration *c, struct usb_function *f) | |||
| 
 | ||||
| 		/* copy descriptors, and track endpoint copies */ | ||||
| 		f->hs_descriptors = usb_copy_descriptors(eth_hs_function); | ||||
| 
 | ||||
| 		if (!f->hs_descriptors) | ||||
| 			goto fail; | ||||
| 	} | ||||
| 
 | ||||
| 	if (gadget_is_superspeed(c->cdev->gadget)) { | ||||
| 		ss_in_desc.bEndpointAddress = | ||||
| 				fs_in_desc.bEndpointAddress; | ||||
| 		ss_out_desc.bEndpointAddress = | ||||
| 				fs_out_desc.bEndpointAddress; | ||||
| 		ss_notify_desc.bEndpointAddress = | ||||
| 				fs_notify_desc.bEndpointAddress; | ||||
| 
 | ||||
| 		/* copy descriptors, and track endpoint copies */ | ||||
| 		f->ss_descriptors = usb_copy_descriptors(eth_ss_function); | ||||
| 		if (!f->ss_descriptors) | ||||
| 			goto fail; | ||||
| 	} | ||||
| 
 | ||||
| 	rndis->port.open = rndis_open; | ||||
| 	rndis->port.close = rndis_close; | ||||
| 
 | ||||
|  | @ -699,12 +789,15 @@ rndis_bind(struct usb_configuration *c, struct usb_function *f) | |||
| 	 */ | ||||
| 
 | ||||
| 	DBG(cdev, "RNDIS: %s speed IN/%s OUT/%s NOTIFY/%s\n", | ||||
| 			gadget_is_superspeed(c->cdev->gadget) ? "super" : | ||||
| 			gadget_is_dualspeed(c->cdev->gadget) ? "dual" : "full", | ||||
| 			rndis->port.in_ep->name, rndis->port.out_ep->name, | ||||
| 			rndis->notify->name); | ||||
| 	return 0; | ||||
| 
 | ||||
| fail: | ||||
| 	if (gadget_is_superspeed(c->cdev->gadget) && f->ss_descriptors) | ||||
| 		usb_free_descriptors(f->ss_descriptors); | ||||
| 	if (gadget_is_dualspeed(c->cdev->gadget) && f->hs_descriptors) | ||||
| 		usb_free_descriptors(f->hs_descriptors); | ||||
| 	if (f->descriptors) | ||||
|  | @ -736,6 +829,8 @@ rndis_unbind(struct usb_configuration *c, struct usb_function *f) | |||
| 	rndis_deregister(rndis->config); | ||||
| 	rndis_exit(); | ||||
| 
 | ||||
| 	if (gadget_is_superspeed(c->cdev->gadget)) | ||||
| 		usb_free_descriptors(f->ss_descriptors); | ||||
| 	if (gadget_is_dualspeed(c->cdev->gadget)) | ||||
| 		usb_free_descriptors(f->hs_descriptors); | ||||
| 	usb_free_descriptors(f->descriptors); | ||||
|  |  | |||
|  | @ -131,6 +131,49 @@ static struct usb_descriptor_header *hs_source_sink_descs[] = { | |||
| 	NULL, | ||||
| }; | ||||
| 
 | ||||
| /* super speed support: */ | ||||
| 
 | ||||
| static struct usb_endpoint_descriptor ss_source_desc = { | ||||
| 	.bLength =		USB_DT_ENDPOINT_SIZE, | ||||
| 	.bDescriptorType =	USB_DT_ENDPOINT, | ||||
| 
 | ||||
| 	.bmAttributes =		USB_ENDPOINT_XFER_BULK, | ||||
| 	.wMaxPacketSize =	cpu_to_le16(1024), | ||||
| }; | ||||
| 
 | ||||
| struct usb_ss_ep_comp_descriptor ss_source_comp_desc = { | ||||
| 	.bLength =		USB_DT_SS_EP_COMP_SIZE, | ||||
| 	.bDescriptorType =	USB_DT_SS_ENDPOINT_COMP, | ||||
| 	.bMaxBurst =		0, | ||||
| 	.bmAttributes =		0, | ||||
| 	.wBytesPerInterval =	0, | ||||
| }; | ||||
| 
 | ||||
| static struct usb_endpoint_descriptor ss_sink_desc = { | ||||
| 	.bLength =		USB_DT_ENDPOINT_SIZE, | ||||
| 	.bDescriptorType =	USB_DT_ENDPOINT, | ||||
| 
 | ||||
| 	.bmAttributes =		USB_ENDPOINT_XFER_BULK, | ||||
| 	.wMaxPacketSize =	cpu_to_le16(1024), | ||||
| }; | ||||
| 
 | ||||
| struct usb_ss_ep_comp_descriptor ss_sink_comp_desc = { | ||||
| 	.bLength =		USB_DT_SS_EP_COMP_SIZE, | ||||
| 	.bDescriptorType =	USB_DT_SS_ENDPOINT_COMP, | ||||
| 	.bMaxBurst =		0, | ||||
| 	.bmAttributes =		0, | ||||
| 	.wBytesPerInterval =	0, | ||||
| }; | ||||
| 
 | ||||
| static struct usb_descriptor_header *ss_source_sink_descs[] = { | ||||
| 	(struct usb_descriptor_header *) &source_sink_intf, | ||||
| 	(struct usb_descriptor_header *) &ss_source_desc, | ||||
| 	(struct usb_descriptor_header *) &ss_source_comp_desc, | ||||
| 	(struct usb_descriptor_header *) &ss_sink_desc, | ||||
| 	(struct usb_descriptor_header *) &ss_sink_comp_desc, | ||||
| 	NULL, | ||||
| }; | ||||
| 
 | ||||
| /* function-specific strings: */ | ||||
| 
 | ||||
| static struct usb_string strings_sourcesink[] = { | ||||
|  | @ -187,8 +230,18 @@ sourcesink_bind(struct usb_configuration *c, struct usb_function *f) | |||
| 		f->hs_descriptors = hs_source_sink_descs; | ||||
| 	} | ||||
| 
 | ||||
| 	/* support super speed hardware */ | ||||
| 	if (gadget_is_superspeed(c->cdev->gadget)) { | ||||
| 		ss_source_desc.bEndpointAddress = | ||||
| 				fs_source_desc.bEndpointAddress; | ||||
| 		ss_sink_desc.bEndpointAddress = | ||||
| 				fs_sink_desc.bEndpointAddress; | ||||
| 		f->ss_descriptors = ss_source_sink_descs; | ||||
| 	} | ||||
| 
 | ||||
| 	DBG(cdev, "%s speed %s: IN/%s, OUT/%s\n", | ||||
| 			gadget_is_dualspeed(c->cdev->gadget) ? "dual" : "full", | ||||
| 	    (gadget_is_superspeed(c->cdev->gadget) ? "super" : | ||||
| 	     (gadget_is_dualspeed(c->cdev->gadget) ? "dual" : "full")), | ||||
| 			f->name, ss->in_ep->name, ss->out_ep->name); | ||||
| 	return 0; | ||||
| } | ||||
|  |  | |||
|  | @ -201,6 +201,46 @@ static struct usb_descriptor_header *hs_eth_function[] __initdata = { | |||
| 	NULL, | ||||
| }; | ||||
| 
 | ||||
| /* super speed support: */ | ||||
| 
 | ||||
| static struct usb_endpoint_descriptor ss_subset_in_desc __initdata = { | ||||
| 	.bLength =		USB_DT_ENDPOINT_SIZE, | ||||
| 	.bDescriptorType =	USB_DT_ENDPOINT, | ||||
| 
 | ||||
| 	.bmAttributes =		USB_ENDPOINT_XFER_BULK, | ||||
| 	.wMaxPacketSize =	cpu_to_le16(1024), | ||||
| }; | ||||
| 
 | ||||
| static struct usb_endpoint_descriptor ss_subset_out_desc __initdata = { | ||||
| 	.bLength =		USB_DT_ENDPOINT_SIZE, | ||||
| 	.bDescriptorType =	USB_DT_ENDPOINT, | ||||
| 
 | ||||
| 	.bmAttributes =		USB_ENDPOINT_XFER_BULK, | ||||
| 	.wMaxPacketSize =	cpu_to_le16(1024), | ||||
| }; | ||||
| 
 | ||||
| static struct usb_ss_ep_comp_descriptor ss_subset_bulk_comp_desc __initdata = { | ||||
| 	.bLength =		sizeof ss_subset_bulk_comp_desc, | ||||
| 	.bDescriptorType =	USB_DT_SS_ENDPOINT_COMP, | ||||
| 
 | ||||
| 	/* the following 2 values can be tweaked if necessary */ | ||||
| 	/* .bMaxBurst =		0, */ | ||||
| 	/* .bmAttributes =	0, */ | ||||
| }; | ||||
| 
 | ||||
| static struct usb_descriptor_header *ss_eth_function[] __initdata = { | ||||
| 	(struct usb_descriptor_header *) &subset_data_intf, | ||||
| 	(struct usb_descriptor_header *) &mdlm_header_desc, | ||||
| 	(struct usb_descriptor_header *) &mdlm_desc, | ||||
| 	(struct usb_descriptor_header *) &mdlm_detail_desc, | ||||
| 	(struct usb_descriptor_header *) ðer_desc, | ||||
| 	(struct usb_descriptor_header *) &ss_subset_in_desc, | ||||
| 	(struct usb_descriptor_header *) &ss_subset_bulk_comp_desc, | ||||
| 	(struct usb_descriptor_header *) &ss_subset_out_desc, | ||||
| 	(struct usb_descriptor_header *) &ss_subset_bulk_comp_desc, | ||||
| 	NULL, | ||||
| }; | ||||
| 
 | ||||
| /* string descriptors: */ | ||||
| 
 | ||||
| static struct usb_string geth_string_defs[] = { | ||||
|  | @ -290,6 +330,8 @@ geth_bind(struct usb_configuration *c, struct usb_function *f) | |||
| 
 | ||||
| 	/* copy descriptors, and track endpoint copies */ | ||||
| 	f->descriptors = usb_copy_descriptors(fs_eth_function); | ||||
| 	if (!f->descriptors) | ||||
| 		goto fail; | ||||
| 
 | ||||
| 	/* support all relevant hardware speeds... we expect that when
 | ||||
| 	 * hardware is dual speed, all bulk-capable endpoints work at | ||||
|  | @ -303,6 +345,20 @@ geth_bind(struct usb_configuration *c, struct usb_function *f) | |||
| 
 | ||||
| 		/* copy descriptors, and track endpoint copies */ | ||||
| 		f->hs_descriptors = usb_copy_descriptors(hs_eth_function); | ||||
| 		if (!f->hs_descriptors) | ||||
| 			goto fail; | ||||
| 	} | ||||
| 
 | ||||
| 	if (gadget_is_superspeed(c->cdev->gadget)) { | ||||
| 		ss_subset_in_desc.bEndpointAddress = | ||||
| 				fs_subset_in_desc.bEndpointAddress; | ||||
| 		ss_subset_out_desc.bEndpointAddress = | ||||
| 				fs_subset_out_desc.bEndpointAddress; | ||||
| 
 | ||||
| 		/* copy descriptors, and track endpoint copies */ | ||||
| 		f->ss_descriptors = usb_copy_descriptors(ss_eth_function); | ||||
| 		if (!f->ss_descriptors) | ||||
| 			goto fail; | ||||
| 	} | ||||
| 
 | ||||
| 	/* NOTE:  all that is done without knowing or caring about
 | ||||
|  | @ -311,11 +367,17 @@ geth_bind(struct usb_configuration *c, struct usb_function *f) | |||
| 	 */ | ||||
| 
 | ||||
| 	DBG(cdev, "CDC Subset: %s speed IN/%s OUT/%s\n", | ||||
| 			gadget_is_superspeed(c->cdev->gadget) ? "super" : | ||||
| 			gadget_is_dualspeed(c->cdev->gadget) ? "dual" : "full", | ||||
| 			geth->port.in_ep->name, geth->port.out_ep->name); | ||||
| 	return 0; | ||||
| 
 | ||||
| fail: | ||||
| 	if (f->descriptors) | ||||
| 		usb_free_descriptors(f->descriptors); | ||||
| 	if (f->hs_descriptors) | ||||
| 		usb_free_descriptors(f->hs_descriptors); | ||||
| 
 | ||||
| 	/* we might as well release our claims on endpoints */ | ||||
| 	if (geth->port.out_ep->desc) | ||||
| 		geth->port.out_ep->driver_data = NULL; | ||||
|  | @ -330,6 +392,8 @@ geth_bind(struct usb_configuration *c, struct usb_function *f) | |||
| static void | ||||
| geth_unbind(struct usb_configuration *c, struct usb_function *f) | ||||
| { | ||||
| 	if (gadget_is_superspeed(c->cdev->gadget)) | ||||
| 		usb_free_descriptors(f->ss_descriptors); | ||||
| 	if (gadget_is_dualspeed(c->cdev->gadget)) | ||||
| 		usb_free_descriptors(f->hs_descriptors); | ||||
| 	usb_free_descriptors(f->descriptors); | ||||
|  |  | |||
|  | @ -767,56 +767,6 @@ static void fusb300_rdfifo(struct fusb300_ep *ep, | |||
| 	} while (!reg); | ||||
| } | ||||
| 
 | ||||
| /* write data to fifo */ | ||||
| static void fusb300_wrfifo(struct fusb300_ep *ep, | ||||
| 			   struct fusb300_request *req) | ||||
| { | ||||
| 	int i = 0; | ||||
| 	u8 *tmp; | ||||
| 	u32 data, reg; | ||||
| 	struct fusb300 *fusb300 = ep->fusb300; | ||||
| 
 | ||||
| 	tmp = req->req.buf; | ||||
| 	req->req.actual = req->req.length; | ||||
| 
 | ||||
| 	for (i = (req->req.length >> 2); i > 0; i--) { | ||||
| 		data = *tmp | *(tmp + 1) << 8 | | ||||
| 			*(tmp + 2) << 16 | *(tmp + 3) << 24; | ||||
| 
 | ||||
| 		iowrite32(data, fusb300->reg + | ||||
| 			FUSB300_OFFSET_EPPORT(ep->epnum)); | ||||
| 		tmp += 4; | ||||
| 	} | ||||
| 
 | ||||
| 	switch (req->req.length % 4) { | ||||
| 	case 1: | ||||
| 		data = *tmp; | ||||
| 		iowrite32(data, fusb300->reg + | ||||
| 			FUSB300_OFFSET_EPPORT(ep->epnum)); | ||||
| 		break; | ||||
| 	case 2: | ||||
| 		data = *tmp | *(tmp + 1) << 8; | ||||
| 		iowrite32(data, fusb300->reg + | ||||
| 			FUSB300_OFFSET_EPPORT(ep->epnum)); | ||||
| 		break; | ||||
| 	case 3: | ||||
| 		data = *tmp | *(tmp + 1) << 8 | *(tmp + 2) << 16; | ||||
| 		iowrite32(data, fusb300->reg + | ||||
| 			FUSB300_OFFSET_EPPORT(ep->epnum)); | ||||
| 		break; | ||||
| 	default: | ||||
| 		break; | ||||
| 	} | ||||
| 
 | ||||
| 	do { | ||||
| 		reg = ioread32(fusb300->reg + FUSB300_OFFSET_IGR1); | ||||
| 		reg &= FUSB300_IGR1_SYNF0_EMPTY_INT; | ||||
| 		if (i) | ||||
| 			printk(KERN_INFO"sync fifo is not empty!\n"); | ||||
| 		i++; | ||||
| 	} while (!reg); | ||||
| } | ||||
| 
 | ||||
| static u8 fusb300_get_epnstall(struct fusb300 *fusb300, u8 ep) | ||||
| { | ||||
| 	u8 value; | ||||
|  | @ -1024,17 +974,6 @@ static int setup_packet(struct fusb300 *fusb300, struct usb_ctrlrequest *ctrl) | |||
| 	return ret; | ||||
| } | ||||
| 
 | ||||
| static void fusb300_set_ep_bycnt(struct fusb300_ep *ep, u32 bycnt) | ||||
| { | ||||
| 	struct fusb300 *fusb300 = ep->fusb300; | ||||
| 	u32 reg = ioread32(fusb300->reg + FUSB300_OFFSET_EPFFR(ep->epnum)); | ||||
| 
 | ||||
| 	reg &= ~FUSB300_FFR_BYCNT; | ||||
| 	reg |= bycnt & FUSB300_FFR_BYCNT; | ||||
| 
 | ||||
| 	iowrite32(reg, fusb300->reg + FUSB300_OFFSET_EPFFR(ep->epnum)); | ||||
| } | ||||
| 
 | ||||
| static void done(struct fusb300_ep *ep, struct fusb300_request *req, | ||||
| 		 int status) | ||||
| { | ||||
|  | @ -1058,8 +997,8 @@ static void done(struct fusb300_ep *ep, struct fusb300_request *req, | |||
| 		fusb300_set_cxdone(ep->fusb300); | ||||
| } | ||||
| 
 | ||||
| void fusb300_fill_idma_prdtbl(struct fusb300_ep *ep, | ||||
| 			struct fusb300_request *req) | ||||
| static void fusb300_fill_idma_prdtbl(struct fusb300_ep *ep, dma_addr_t d, | ||||
| 		u32 len) | ||||
| { | ||||
| 	u32 value; | ||||
| 	u32 reg; | ||||
|  | @ -1071,10 +1010,9 @@ void fusb300_fill_idma_prdtbl(struct fusb300_ep *ep, | |||
| 		reg &= FUSB300_EPPRD0_H; | ||||
| 	} while (reg); | ||||
| 
 | ||||
| 	iowrite32((u32) req->req.buf, ep->fusb300->reg + | ||||
| 		FUSB300_OFFSET_EPPRD_W1(ep->epnum)); | ||||
| 	iowrite32(d, ep->fusb300->reg + FUSB300_OFFSET_EPPRD_W1(ep->epnum)); | ||||
| 
 | ||||
| 	value = FUSB300_EPPRD0_BTC(req->req.length) | FUSB300_EPPRD0_H | | ||||
| 	value = FUSB300_EPPRD0_BTC(len) | FUSB300_EPPRD0_H | | ||||
| 		FUSB300_EPPRD0_F | FUSB300_EPPRD0_L | FUSB300_EPPRD0_I; | ||||
| 	iowrite32(value, ep->fusb300->reg + FUSB300_OFFSET_EPPRD_W0(ep->epnum)); | ||||
| 
 | ||||
|  | @ -1111,13 +1049,12 @@ static void  fusb300_set_idma(struct fusb300_ep *ep, | |||
| 			struct fusb300_request *req) | ||||
| { | ||||
| 	dma_addr_t d; | ||||
| 	u8 *tmp = NULL; | ||||
| 
 | ||||
| 	d = dma_map_single(NULL, req->req.buf, req->req.length, DMA_TO_DEVICE); | ||||
| 
 | ||||
| 	if (dma_mapping_error(NULL, d)) { | ||||
| 		kfree(req->req.buf); | ||||
| 		printk(KERN_DEBUG "dma_mapping_error\n"); | ||||
| 		return; | ||||
| 	} | ||||
| 
 | ||||
| 	dma_sync_single_for_device(NULL, d, req->req.length, DMA_TO_DEVICE); | ||||
|  | @ -1125,16 +1062,10 @@ static void  fusb300_set_idma(struct fusb300_ep *ep, | |||
| 	fusb300_enable_bit(ep->fusb300, FUSB300_OFFSET_IGER0, | ||||
| 		FUSB300_IGER0_EEPn_PRD_INT(ep->epnum)); | ||||
| 
 | ||||
| 	tmp = req->req.buf; | ||||
| 	req->req.buf = (u8 *)d; | ||||
| 
 | ||||
| 	fusb300_fill_idma_prdtbl(ep, req); | ||||
| 	fusb300_fill_idma_prdtbl(ep, d, req->req.length); | ||||
| 	/* check idma is done */ | ||||
| 	fusb300_wait_idma_finished(ep); | ||||
| 
 | ||||
| 	req->req.buf = tmp; | ||||
| 
 | ||||
| 	if (d) | ||||
| 	dma_unmap_single(NULL, d, req->req.length, DMA_TO_DEVICE); | ||||
| } | ||||
| 
 | ||||
|  | @ -1143,14 +1074,8 @@ static void in_ep_fifo_handler(struct fusb300_ep *ep) | |||
| 	struct fusb300_request *req = list_entry(ep->queue.next, | ||||
| 					struct fusb300_request, queue); | ||||
| 
 | ||||
| 	if (req->req.length) { | ||||
| #if 0 | ||||
| 		fusb300_set_ep_bycnt(ep, req->req.length); | ||||
| 		fusb300_wrfifo(ep, req); | ||||
| #else | ||||
| 	if (req->req.length) | ||||
| 		fusb300_set_idma(ep, req); | ||||
| #endif | ||||
| 	} | ||||
| 	done(ep, req, 0); | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -593,8 +593,8 @@ static int queue_dtd(struct langwell_ep *ep, struct langwell_request *req) | |||
| 		/* ep0 */ | ||||
| 		dev_vdbg(&dev->pdev->dev, "%s-%s\n", ep->name, DIR_STRING(ep)); | ||||
| 
 | ||||
| 	dev_vdbg(&dev->pdev->dev, "ep_dqh[%d] addr: 0x%08x\n", | ||||
| 			i, (u32)&(dev->ep_dqh[i])); | ||||
| 	dev_vdbg(&dev->pdev->dev, "ep_dqh[%d] addr: 0x%p\n", | ||||
| 			i, &(dev->ep_dqh[i])); | ||||
| 
 | ||||
| 	bit_mask = is_in(ep) ? | ||||
| 		(1 << (ep->ep_num + 16)) : (1 << (ep->ep_num)); | ||||
|  | @ -3271,7 +3271,7 @@ static int langwell_udc_probe(struct pci_dev *pdev, | |||
| 
 | ||||
| 	/* allocate device dQH memory */ | ||||
| 	size = dev->ep_max * sizeof(struct langwell_dqh); | ||||
| 	dev_vdbg(&dev->pdev->dev, "orig size = %d\n", size); | ||||
| 	dev_vdbg(&dev->pdev->dev, "orig size = %zd\n", size); | ||||
| 	if (size < DQH_ALIGNMENT) | ||||
| 		size = DQH_ALIGNMENT; | ||||
| 	else if ((size % DQH_ALIGNMENT) != 0) { | ||||
|  | @ -3286,7 +3286,7 @@ static int langwell_udc_probe(struct pci_dev *pdev, | |||
| 		goto error; | ||||
| 	} | ||||
| 	dev->ep_dqh_size = size; | ||||
| 	dev_vdbg(&dev->pdev->dev, "ep_dqh_size = %d\n", dev->ep_dqh_size); | ||||
| 	dev_vdbg(&dev->pdev->dev, "ep_dqh_size = %zd\n", dev->ep_dqh_size); | ||||
| 
 | ||||
| 	/* initialize ep0 status request structure */ | ||||
| 	dev->status_req = kzalloc(sizeof(struct langwell_request), GFP_KERNEL); | ||||
|  | @ -3470,7 +3470,7 @@ static int langwell_udc_resume(struct pci_dev *pdev) | |||
| 
 | ||||
| 	/* allocate device dQH memory */ | ||||
| 	size = dev->ep_max * sizeof(struct langwell_dqh); | ||||
| 	dev_vdbg(&dev->pdev->dev, "orig size = %d\n", size); | ||||
| 	dev_vdbg(&dev->pdev->dev, "orig size = %zd\n", size); | ||||
| 	if (size < DQH_ALIGNMENT) | ||||
| 		size = DQH_ALIGNMENT; | ||||
| 	else if ((size % DQH_ALIGNMENT) != 0) { | ||||
|  | @ -3484,7 +3484,7 @@ static int langwell_udc_resume(struct pci_dev *pdev) | |||
| 		return -ENOMEM; | ||||
| 	} | ||||
| 	dev->ep_dqh_size = size; | ||||
| 	dev_vdbg(&dev->pdev->dev, "ep_dqh_size = %d\n", dev->ep_dqh_size); | ||||
| 	dev_vdbg(&dev->pdev->dev, "ep_dqh_size = %zd\n", dev->ep_dqh_size); | ||||
| 
 | ||||
| 	/* create dTD dma_pool resource */ | ||||
| 	dev->dtd_pool = dma_pool_create("langwell_dtd", | ||||
|  |  | |||
|  | @ -3,7 +3,7 @@ | |||
|  * | ||||
|  * Copyright (C) 2006-2007 Renesas Solutions Corp. | ||||
|  * | ||||
|  * Author : Yoshihiro Shimoda <shimoda.yoshihiro@renesas.com> | ||||
|  * Author : Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com> | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License as published by | ||||
|  | @ -691,6 +691,7 @@ static void init_controller(struct m66592 *m66592) | |||
| 
 | ||||
| static void disable_controller(struct m66592 *m66592) | ||||
| { | ||||
| 	m66592_bclr(m66592, M66592_UTST, M66592_TESTMODE); | ||||
| 	if (!m66592->pdata->on_chip) { | ||||
| 		m66592_bclr(m66592, M66592_SCKE, M66592_SYSCFG); | ||||
| 		udelay(1); | ||||
|  | @ -780,7 +781,7 @@ static void irq_ep0_write(struct m66592_ep *ep, struct m66592_request *req) | |||
| 	/* write fifo */ | ||||
| 	if (req->req.buf) { | ||||
| 		if (size > 0) | ||||
| 			m66592_write_fifo(m66592, ep->fifoaddr, buf, size); | ||||
| 			m66592_write_fifo(m66592, ep, buf, size); | ||||
| 		if ((size == 0) || ((size % ep->ep.maxpacket) != 0)) | ||||
| 			m66592_bset(m66592, M66592_BVAL, ep->fifoctr); | ||||
| 	} | ||||
|  | @ -826,7 +827,7 @@ static void irq_packet_write(struct m66592_ep *ep, struct m66592_request *req) | |||
| 
 | ||||
| 	/* write fifo */ | ||||
| 	if (req->req.buf) { | ||||
| 		m66592_write_fifo(m66592, ep->fifoaddr, buf, size); | ||||
| 		m66592_write_fifo(m66592, ep, buf, size); | ||||
| 		if ((size == 0) | ||||
| 				|| ((size % ep->ep.maxpacket) != 0) | ||||
| 				|| ((bufsize != ep->ep.maxpacket) | ||||
|  | @ -1048,10 +1049,30 @@ static void clear_feature(struct m66592 *m66592, struct usb_ctrlrequest *ctrl) | |||
| 
 | ||||
| static void set_feature(struct m66592 *m66592, struct usb_ctrlrequest *ctrl) | ||||
| { | ||||
| 	u16 tmp; | ||||
| 	int timeout = 3000; | ||||
| 
 | ||||
| 	switch (ctrl->bRequestType & USB_RECIP_MASK) { | ||||
| 	case USB_RECIP_DEVICE: | ||||
| 		switch (le16_to_cpu(ctrl->wValue)) { | ||||
| 		case USB_DEVICE_TEST_MODE: | ||||
| 			control_end(m66592, 1); | ||||
| 			/* Wait for the completion of status stage */ | ||||
| 			do { | ||||
| 				tmp = m66592_read(m66592, M66592_INTSTS0) & | ||||
| 								M66592_CTSQ; | ||||
| 				udelay(1); | ||||
| 			} while (tmp != M66592_CS_IDST || timeout-- > 0); | ||||
| 
 | ||||
| 			if (tmp == M66592_CS_IDST) | ||||
| 				m66592_bset(m66592, | ||||
| 					    le16_to_cpu(ctrl->wIndex >> 8), | ||||
| 					    M66592_TESTMODE); | ||||
| 			break; | ||||
| 		default: | ||||
| 			pipe_stall(m66592, 0); | ||||
| 			break; | ||||
| 		} | ||||
| 		break; | ||||
| 	case USB_RECIP_INTERFACE: | ||||
| 		control_end(m66592, 1); | ||||
|  | @ -1540,10 +1561,26 @@ static int m66592_get_frame(struct usb_gadget *_gadget) | |||
| 	return m66592_read(m66592, M66592_FRMNUM) & 0x03FF; | ||||
| } | ||||
| 
 | ||||
| static int m66592_pullup(struct usb_gadget *gadget, int is_on) | ||||
| { | ||||
| 	struct m66592 *m66592 = gadget_to_m66592(gadget); | ||||
| 	unsigned long flags; | ||||
| 
 | ||||
| 	spin_lock_irqsave(&m66592->lock, flags); | ||||
| 	if (is_on) | ||||
| 		m66592_bset(m66592, M66592_DPRPU, M66592_SYSCFG); | ||||
| 	else | ||||
| 		m66592_bclr(m66592, M66592_DPRPU, M66592_SYSCFG); | ||||
| 	spin_unlock_irqrestore(&m66592->lock, flags); | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| static struct usb_gadget_ops m66592_gadget_ops = { | ||||
| 	.get_frame		= m66592_get_frame, | ||||
| 	.start			= m66592_start, | ||||
| 	.stop			= m66592_stop, | ||||
| 	.pullup			= m66592_pullup, | ||||
| }; | ||||
| 
 | ||||
| static int __exit m66592_remove(struct platform_device *pdev) | ||||
|  |  | |||
|  | @ -3,7 +3,7 @@ | |||
|  * | ||||
|  * Copyright (C) 2006-2007 Renesas Solutions Corp. | ||||
|  * | ||||
|  * Author : Yoshihiro Shimoda <shimoda.yoshihiro@renesas.com> | ||||
|  * Author : Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com> | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License as published by | ||||
|  | @ -561,11 +561,26 @@ static inline void m66592_write(struct m66592 *m66592, u16 val, | |||
| 	iowrite16(val, m66592->reg + offset); | ||||
| } | ||||
| 
 | ||||
| static inline void m66592_mdfy(struct m66592 *m66592, u16 val, u16 pat, | ||||
| 		unsigned long offset) | ||||
| { | ||||
| 	u16 tmp; | ||||
| 	tmp = m66592_read(m66592, offset); | ||||
| 	tmp = tmp & (~pat); | ||||
| 	tmp = tmp | val; | ||||
| 	m66592_write(m66592, tmp, offset); | ||||
| } | ||||
| 
 | ||||
| #define m66592_bclr(m66592, val, offset)	\ | ||||
| 			m66592_mdfy(m66592, 0, val, offset) | ||||
| #define m66592_bset(m66592, val, offset)	\ | ||||
| 			m66592_mdfy(m66592, val, 0, offset) | ||||
| 
 | ||||
| static inline void m66592_write_fifo(struct m66592 *m66592, | ||||
| 		unsigned long offset, | ||||
| 		struct m66592_ep *ep, | ||||
| 		void *buf, unsigned long len) | ||||
| { | ||||
| 	void __iomem *fifoaddr = m66592->reg + offset; | ||||
| 	void __iomem *fifoaddr = m66592->reg + ep->fifoaddr; | ||||
| 
 | ||||
| 	if (m66592->pdata->on_chip) { | ||||
| 		unsigned long count; | ||||
|  | @ -591,26 +606,15 @@ static inline void m66592_write_fifo(struct m66592 *m66592, | |||
| 		iowrite16_rep(fifoaddr, buf, len); | ||||
| 		if (odd) { | ||||
| 			unsigned char *p = buf + len*2; | ||||
| 			if (m66592->pdata->wr0_shorted_to_wr1) | ||||
| 				m66592_bclr(m66592, M66592_MBW_16, ep->fifosel); | ||||
| 			iowrite8(*p, fifoaddr); | ||||
| 			if (m66592->pdata->wr0_shorted_to_wr1) | ||||
| 				m66592_bset(m66592, M66592_MBW_16, ep->fifosel); | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| static inline void m66592_mdfy(struct m66592 *m66592, u16 val, u16 pat, | ||||
| 		unsigned long offset) | ||||
| { | ||||
| 	u16 tmp; | ||||
| 	tmp = m66592_read(m66592, offset); | ||||
| 	tmp = tmp & (~pat); | ||||
| 	tmp = tmp | val; | ||||
| 	m66592_write(m66592, tmp, offset); | ||||
| } | ||||
| 
 | ||||
| #define m66592_bclr(m66592, val, offset)	\ | ||||
| 			m66592_mdfy(m66592, 0, val, offset) | ||||
| #define m66592_bset(m66592, val, offset)	\ | ||||
| 			m66592_mdfy(m66592, val, 0, offset) | ||||
| 
 | ||||
| #endif	/* ifndef __M66592_UDC_H__ */ | ||||
| 
 | ||||
| 
 | ||||
|  |  | |||
|  | @ -737,8 +737,8 @@ net2272_kick_dma(struct net2272_ep *ep, struct net2272_request *req) | |||
| 	if (req->req.length & 1) | ||||
| 		return -EINVAL; | ||||
| 
 | ||||
| 	dev_vdbg(ep->dev->dev, "kick_dma %s req %p dma %08x\n", | ||||
| 		ep->ep.name, req, req->req.dma); | ||||
| 	dev_vdbg(ep->dev->dev, "kick_dma %s req %p dma %08llx\n", | ||||
| 		ep->ep.name, req, (unsigned long long) req->req.dma); | ||||
| 
 | ||||
| 	net2272_ep_write(ep, EP_RSPSET, 1 << ALT_NAK_OUT_PACKETS); | ||||
| 
 | ||||
|  | @ -856,9 +856,9 @@ net2272_queue(struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags) | |||
| 		req->mapped = 1; | ||||
| 	} | ||||
| 
 | ||||
| 	dev_vdbg(dev->dev, "%s queue req %p, len %d buf %p dma %08x %s\n", | ||||
| 	dev_vdbg(dev->dev, "%s queue req %p, len %d buf %p dma %08llx %s\n", | ||||
| 		_ep->name, _req, _req->length, _req->buf, | ||||
| 		_req->dma, _req->zero ? "zero" : "!zero"); | ||||
| 		(unsigned long long) _req->dma, _req->zero ? "zero" : "!zero"); | ||||
| 
 | ||||
| 	spin_lock_irqsave(&dev->lock, flags); | ||||
| 
 | ||||
|  |  | |||
|  | @ -3,7 +3,7 @@ | |||
|  * | ||||
|  * Copyright (C) 2006-2009 Renesas Solutions Corp. | ||||
|  * | ||||
|  * Author : Yoshihiro Shimoda <shimoda.yoshihiro@renesas.com> | ||||
|  * Author : Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com> | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License as published by | ||||
|  | @ -576,7 +576,11 @@ static void init_controller(struct r8a66597 *r8a66597) | |||
| 	u16 endian = r8a66597->pdata->endian ? BIGEND : 0; | ||||
| 
 | ||||
| 	if (r8a66597->pdata->on_chip) { | ||||
| 		r8a66597_bset(r8a66597, 0x04, SYSCFG1); | ||||
| 		if (r8a66597->pdata->buswait) | ||||
| 			r8a66597_write(r8a66597, r8a66597->pdata->buswait, | ||||
| 					SYSCFG1); | ||||
| 		else | ||||
| 			r8a66597_write(r8a66597, 0x0f, SYSCFG1); | ||||
| 		r8a66597_bset(r8a66597, HSE, SYSCFG0); | ||||
| 
 | ||||
| 		r8a66597_bclr(r8a66597, USBE, SYSCFG0); | ||||
|  | @ -618,6 +622,7 @@ static void disable_controller(struct r8a66597 *r8a66597) | |||
| { | ||||
| 	if (r8a66597->pdata->on_chip) { | ||||
| 		r8a66597_bset(r8a66597, SCKE, SYSCFG0); | ||||
| 		r8a66597_bclr(r8a66597, UTST, TESTMODE); | ||||
| 
 | ||||
| 		/* disable interrupts */ | ||||
| 		r8a66597_write(r8a66597, 0, INTENB0); | ||||
|  | @ -635,6 +640,7 @@ static void disable_controller(struct r8a66597 *r8a66597) | |||
| 		r8a66597_bclr(r8a66597, SCKE, SYSCFG0); | ||||
| 
 | ||||
| 	} else { | ||||
| 		r8a66597_bclr(r8a66597, UTST, TESTMODE); | ||||
| 		r8a66597_bclr(r8a66597, SCKE, SYSCFG0); | ||||
| 		udelay(1); | ||||
| 		r8a66597_bclr(r8a66597, PLLC, SYSCFG0); | ||||
|  | @ -999,10 +1005,29 @@ static void clear_feature(struct r8a66597 *r8a66597, | |||
| 
 | ||||
| static void set_feature(struct r8a66597 *r8a66597, struct usb_ctrlrequest *ctrl) | ||||
| { | ||||
| 	u16 tmp; | ||||
| 	int timeout = 3000; | ||||
| 
 | ||||
| 	switch (ctrl->bRequestType & USB_RECIP_MASK) { | ||||
| 	case USB_RECIP_DEVICE: | ||||
| 		switch (le16_to_cpu(ctrl->wValue)) { | ||||
| 		case USB_DEVICE_TEST_MODE: | ||||
| 			control_end(r8a66597, 1); | ||||
| 			/* Wait for the completion of status stage */ | ||||
| 			do { | ||||
| 				tmp = r8a66597_read(r8a66597, INTSTS0) & CTSQ; | ||||
| 				udelay(1); | ||||
| 			} while (tmp != CS_IDST || timeout-- > 0); | ||||
| 
 | ||||
| 			if (tmp == CS_IDST) | ||||
| 				r8a66597_bset(r8a66597, | ||||
| 					      le16_to_cpu(ctrl->wIndex >> 8), | ||||
| 					      TESTMODE); | ||||
| 			break; | ||||
| 		default: | ||||
| 			pipe_stall(r8a66597, 0); | ||||
| 			break; | ||||
| 		} | ||||
| 		break; | ||||
| 	case USB_RECIP_INTERFACE: | ||||
| 		control_end(r8a66597, 1); | ||||
|  | @ -1444,6 +1469,7 @@ static int r8a66597_start(struct usb_gadget_driver *driver, | |||
| 		goto error; | ||||
| 	} | ||||
| 
 | ||||
| 	init_controller(r8a66597); | ||||
| 	r8a66597_bset(r8a66597, VBSE, INTENB0); | ||||
| 	if (r8a66597_read(r8a66597, INTSTS0) & VBSTS) { | ||||
| 		r8a66597_start_xclock(r8a66597); | ||||
|  | @ -1474,15 +1500,12 @@ static int r8a66597_stop(struct usb_gadget_driver *driver) | |||
| 	spin_lock_irqsave(&r8a66597->lock, flags); | ||||
| 	if (r8a66597->gadget.speed != USB_SPEED_UNKNOWN) | ||||
| 		r8a66597_usb_disconnect(r8a66597); | ||||
| 	r8a66597_bclr(r8a66597, VBSE, INTENB0); | ||||
| 	disable_controller(r8a66597); | ||||
| 	spin_unlock_irqrestore(&r8a66597->lock, flags); | ||||
| 
 | ||||
| 	r8a66597_bclr(r8a66597, VBSE, INTENB0); | ||||
| 
 | ||||
| 	driver->unbind(&r8a66597->gadget); | ||||
| 
 | ||||
| 	init_controller(r8a66597); | ||||
| 	disable_controller(r8a66597); | ||||
| 
 | ||||
| 	device_del(&r8a66597->gadget.dev); | ||||
| 	r8a66597->driver = NULL; | ||||
| 	return 0; | ||||
|  | @ -1495,10 +1518,26 @@ static int r8a66597_get_frame(struct usb_gadget *_gadget) | |||
| 	return r8a66597_read(r8a66597, FRMNUM) & 0x03FF; | ||||
| } | ||||
| 
 | ||||
| static int r8a66597_pullup(struct usb_gadget *gadget, int is_on) | ||||
| { | ||||
| 	struct r8a66597 *r8a66597 = gadget_to_r8a66597(gadget); | ||||
| 	unsigned long flags; | ||||
| 
 | ||||
| 	spin_lock_irqsave(&r8a66597->lock, flags); | ||||
| 	if (is_on) | ||||
| 		r8a66597_bset(r8a66597, DPRPU, SYSCFG0); | ||||
| 	else | ||||
| 		r8a66597_bclr(r8a66597, DPRPU, SYSCFG0); | ||||
| 	spin_unlock_irqrestore(&r8a66597->lock, flags); | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| static struct usb_gadget_ops r8a66597_gadget_ops = { | ||||
| 	.get_frame		= r8a66597_get_frame, | ||||
| 	.start			= r8a66597_start, | ||||
| 	.stop			= r8a66597_stop, | ||||
| 	.pullup			= r8a66597_pullup, | ||||
| }; | ||||
| 
 | ||||
| static int __exit r8a66597_remove(struct platform_device *pdev) | ||||
|  | @ -1646,8 +1685,6 @@ static int __init r8a66597_probe(struct platform_device *pdev) | |||
| 		goto clean_up3; | ||||
| 	r8a66597->ep0_req->complete = nop_completion; | ||||
| 
 | ||||
| 	init_controller(r8a66597); | ||||
| 
 | ||||
| 	ret = usb_add_gadget_udc(&pdev->dev, &r8a66597->gadget); | ||||
| 	if (ret) | ||||
| 		goto err_add_udc; | ||||
|  |  | |||
|  | @ -3,7 +3,7 @@ | |||
|  * | ||||
|  * Copyright (C) 2007-2009 Renesas Solutions Corp. | ||||
|  * | ||||
|  * Author : Yoshihiro Shimoda <shimoda.yoshihiro@renesas.com> | ||||
|  * Author : Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com> | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License as published by | ||||
|  |  | |||
|  | @ -97,16 +97,17 @@ struct eth_dev { | |||
| 
 | ||||
| static unsigned qmult = 5; | ||||
| module_param(qmult, uint, S_IRUGO|S_IWUSR); | ||||
| MODULE_PARM_DESC(qmult, "queue length multiplier at high speed"); | ||||
| MODULE_PARM_DESC(qmult, "queue length multiplier at high/super speed"); | ||||
| 
 | ||||
| #else	/* full speed (low speed doesn't do bulk) */ | ||||
| #define qmult		1 | ||||
| #endif | ||||
| 
 | ||||
| /* for dual-speed hardware, use deeper queues at highspeed */ | ||||
| /* for dual-speed hardware, use deeper queues at high/super speed */ | ||||
| static inline int qlen(struct usb_gadget *gadget) | ||||
| { | ||||
| 	if (gadget_is_dualspeed(gadget) && gadget->speed == USB_SPEED_HIGH) | ||||
| 	if (gadget_is_dualspeed(gadget) && (gadget->speed == USB_SPEED_HIGH || | ||||
| 					    gadget->speed == USB_SPEED_SUPER)) | ||||
| 		return qmult * DEFAULT_QLEN; | ||||
| 	else | ||||
| 		return DEFAULT_QLEN; | ||||
|  | @ -598,9 +599,10 @@ static netdev_tx_t eth_start_xmit(struct sk_buff *skb, | |||
| 
 | ||||
| 	req->length = length; | ||||
| 
 | ||||
| 	/* throttle highspeed IRQ rate back slightly */ | ||||
| 	/* throttle high/super speed IRQ rate back slightly */ | ||||
| 	if (gadget_is_dualspeed(dev->gadget)) | ||||
| 		req->no_interrupt = (dev->gadget->speed == USB_SPEED_HIGH) | ||||
| 		req->no_interrupt = (dev->gadget->speed == USB_SPEED_HIGH || | ||||
| 				     dev->gadget->speed == USB_SPEED_SUPER) | ||||
| 			? ((atomic_read(&dev->tx_qlen) % qmult) != 0) | ||||
| 			: 0; | ||||
| 
 | ||||
|  |  | |||
|  | @ -340,7 +340,7 @@ static struct usb_composite_driver zero_driver = { | |||
| 	.name		= "zero", | ||||
| 	.dev		= &device_desc, | ||||
| 	.strings	= dev_strings, | ||||
| 	.max_speed	= USB_SPEED_HIGH, | ||||
| 	.max_speed	= USB_SPEED_SUPER, | ||||
| 	.unbind		= zero_unbind, | ||||
| 	.suspend	= zero_suspend, | ||||
| 	.resume		= zero_resume, | ||||
|  |  | |||
|  | @ -2282,6 +2282,7 @@ static void musb_restore_context(struct musb *musb) | |||
| 				musb->context.index_regs[i].rxhubport); | ||||
| 		} | ||||
| 	} | ||||
| 	musb_writeb(musb_base, MUSB_INDEX, musb->context.index); | ||||
| } | ||||
| 
 | ||||
| static int musb_suspend(struct device *dev) | ||||
|  |  | |||
|  | @ -38,6 +38,8 @@ struct m66592_platdata { | |||
| 	/* (external controller only) one = 3.3V, zero = 1.5V */ | ||||
| 	unsigned	vif:1; | ||||
| 
 | ||||
| 	/* (external controller only) set one = WR0_N shorted to WR1_N */ | ||||
| 	unsigned	wr0_shorted_to_wr1:1; | ||||
| }; | ||||
| 
 | ||||
| #endif /* __LINUX_USB_M66592_H */ | ||||
|  |  | |||
|  | @ -31,6 +31,9 @@ struct r8a66597_platdata { | |||
| 	/* This callback can control port power instead of DVSTCTR register. */ | ||||
| 	void (*port_power)(int port, int power); | ||||
| 
 | ||||
| 	/* This parameter is for BUSWAIT */ | ||||
| 	u16		buswait; | ||||
| 
 | ||||
| 	/* set one = on chip controller, set zero = external controller */ | ||||
| 	unsigned	on_chip:1; | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue
	
	 Greg Kroah-Hartman
						Greg Kroah-Hartman