Patchwork [3/7] usb: gadget: fsl_udc: convert to new ulc style

login
register
mail settings
Submitter Christoph Fritz
Date Oct. 19, 2012, 10:24 a.m.
Message ID <1350642285-8145-3-git-send-email-chf.fritz@googlemail.com>
Download mbox | patch
Permalink /patch/192638/
State Not Applicable
Headers show

Comments

Christoph Fritz - Oct. 19, 2012, 10:24 a.m.
Convert to new UDC style registration and remove
global 'udc_controller' pointer.

Signed-off-by: Christoph Fritz <chf.fritz@googlemail.com>
---
 drivers/usb/gadget/fsl_udc_core.c |  289 +++++++++++++++++--------------------
 1 files changed, 131 insertions(+), 158 deletions(-)
Felipe Balbi - Oct. 19, 2012, 10:27 a.m.
Hi,

typo on Subject. Should be udc, not ulc.

On Fri, Oct 19, 2012 at 12:24:41PM +0200, Christoph Fritz wrote:
> Convert to new UDC style registration and remove
> global 'udc_controller' pointer.
> 
> Signed-off-by: Christoph Fritz <chf.fritz@googlemail.com>
> ---
>  drivers/usb/gadget/fsl_udc_core.c |  289 +++++++++++++++++--------------------
>  1 files changed, 131 insertions(+), 158 deletions(-)
> 
> diff --git a/drivers/usb/gadget/fsl_udc_core.c b/drivers/usb/gadget/fsl_udc_core.c
> index 0a0d6a6..d113f39 100644
> --- a/drivers/usb/gadget/fsl_udc_core.c
> +++ b/drivers/usb/gadget/fsl_udc_core.c
> @@ -63,9 +63,6 @@ static struct usb_dr_device *dr_regs;
>  
>  static struct usb_sys_interface *usb_sys_regs;
>  
> -/* it is initialized in probe()  */
> -static struct fsl_udc *udc_controller = NULL;
> -
>  static const struct usb_endpoint_descriptor
>  fsl_ep0_desc = {
>  	.bLength =		USB_DT_ENDPOINT_SIZE,
> @@ -783,12 +780,14 @@ static void fsl_queue_td(struct fsl_ep *ep, struct fsl_req *req)
>  }
>  
>  /* Fill in the dTD structure
> + * @udc: driver private data
>   * @req: request that the transfer belongs to
>   * @length: return actually data length of the dTD
>   * @dma: return dma address of the dTD
>   * @is_last: return flag if it is the last dTD of the request
>   * return: pointer to the built dTD */
> -static struct ep_td_struct *fsl_build_dtd(struct fsl_req *req, unsigned *length,
> +static struct ep_td_struct *fsl_build_dtd(struct fsl_udc *udc,
> +		struct fsl_req *req, unsigned *length,
>  		dma_addr_t *dma, int *is_last, gfp_t gfp_flags)

I would split this patch a little. First I would patch the missing
arguments to these functions under the excuse that a later patch will
get rid of the udc_controller pointer, then the next patch would do the
conversion to new style.

It will be a lot easier to review ;-)

>  {
>  	u32 swap_temp;
> @@ -798,7 +797,7 @@ static struct ep_td_struct *fsl_build_dtd(struct fsl_req *req, unsigned *length,
>  	*length = min(req->req.length - req->req.actual,
>  			(unsigned)EP_MAX_LENGTH_TRANSFER);
>  
> -	dtd = dma_pool_alloc(udc_controller->td_pool, gfp_flags, dma);
> +	dtd = dma_pool_alloc(udc->td_pool, gfp_flags, dma);
>  	if (dtd == NULL)
>  		return dtd;
>  
> @@ -848,7 +847,8 @@ static struct ep_td_struct *fsl_build_dtd(struct fsl_req *req, unsigned *length,
>  }
>  
>  /* Generate dtd chain for a request */
> -static int fsl_req_to_dtd(struct fsl_req *req, gfp_t gfp_flags)
> +static int fsl_req_to_dtd(struct fsl_udc *udc, struct fsl_req *req,
> +		gfp_t gfp_flags)
>  {
>  	unsigned	count;
>  	int		is_last;
> @@ -857,7 +857,8 @@ static int fsl_req_to_dtd(struct fsl_req *req, gfp_t gfp_flags)
>  	dma_addr_t dma;
>  
>  	do {
> -		dtd = fsl_build_dtd(req, &count, &dma, &is_last, gfp_flags);
> +		dtd = fsl_build_dtd(udc, req, &count, &dma, &is_last,
> +				gfp_flags);
>  		if (dtd == NULL)
>  			return -ENOMEM;
>  
> @@ -932,7 +933,7 @@ fsl_ep_queue(struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags)
>  	req->dtd_count = 0;
>  
>  	/* build dtds and push them to device queue */
> -	if (!fsl_req_to_dtd(req, gfp_flags)) {
> +	if (!fsl_req_to_dtd(udc, req, gfp_flags)) {
>  		spin_lock_irqsave(&udc->lock, flags);
>  		fsl_queue_td(ep, req);
>  	} else {
> @@ -1258,9 +1259,10 @@ static int fsl_pullup(struct usb_gadget *gadget, int is_on)
>  	return 0;
>  }
>  
> -static int fsl_start(struct usb_gadget_driver *driver,
> -		int (*bind)(struct usb_gadget *, struct usb_gadget_driver *));
> -static int fsl_stop(struct usb_gadget_driver *driver);
> +static int fsl_udc_start(struct usb_gadget *gadget,
> +		struct usb_gadget_driver *driver);
> +static int fsl_udc_stop(struct usb_gadget *gadget,
> +		struct usb_gadget_driver *driver);
>  /* defined in gadget.h */
>  static struct usb_gadget_ops fsl_gadget_ops = {
>  	.get_frame = fsl_get_frame,
> @@ -1269,8 +1271,8 @@ static struct usb_gadget_ops fsl_gadget_ops = {
>  	.vbus_session = fsl_vbus_session,
>  	.vbus_draw = fsl_vbus_draw,
>  	.pullup = fsl_pullup,
> -	.start = fsl_start,
> -	.stop = fsl_stop,
> +	.udc_start = fsl_udc_start,
> +	.udc_stop = fsl_udc_stop,
>  };
>  
>  /* Set protocol stall on ep0, protocol stall will automatically be cleared
> @@ -1314,7 +1316,7 @@ static int ep0_prime_status(struct fsl_udc *udc, int direction)
>  			ep_is_in(ep) ? DMA_TO_DEVICE : DMA_FROM_DEVICE);
>  	req->mapped = 1;
>  
> -	if (fsl_req_to_dtd(req, GFP_ATOMIC) == 0)
> +	if (fsl_req_to_dtd(udc, req, GFP_ATOMIC) == 0)
>  		fsl_queue_td(ep, req);
>  	else
>  		return -ENOMEM;
> @@ -1398,7 +1400,7 @@ static void ch9getstatus(struct fsl_udc *udc, u8 request_type, u16 value,
>  	req->mapped = 1;
>  
>  	/* prime the data phase */
> -	if ((fsl_req_to_dtd(req, GFP_ATOMIC) == 0))
> +	if ((fsl_req_to_dtd(udc, req, GFP_ATOMIC) == 0))
>  		fsl_queue_td(ep, req);
>  	else			/* no mem */
>  		goto stall;
> @@ -1422,7 +1424,7 @@ static void setup_received_irq(struct fsl_udc *udc,
>  
>  	udc_reset_ep_queue(udc, 0);
>  
> -	/* We process some stardard setup requests here */
> +	/* We process some standard setup requests here */
>  	switch (setup->bRequest) {
>  	case USB_REQ_GET_STATUS:
>  		/* Data+Status phase from udc */
> @@ -1954,114 +1956,82 @@ static irqreturn_t fsl_udc_irq(int irq, void *_udc)
>   * Hook to gadget drivers
>   * Called by initialization code of gadget drivers
>  *----------------------------------------------------------------*/
> -static int fsl_start(struct usb_gadget_driver *driver,
> -		int (*bind)(struct usb_gadget *, struct usb_gadget_driver *))
> +static int fsl_udc_start(struct usb_gadget *gadget,
> +	struct usb_gadget_driver *driver)
>  {
> +	struct fsl_udc *udc;
>  	int retval = -ENODEV;
> -	unsigned long flags = 0;
> +	unsigned long flags;
>  
> -	if (!udc_controller)
> +	udc = container_of(gadget, struct fsl_udc, gadget);
> +	if (!udc)
>  		return -ENODEV;
>  
>  	if (!driver || driver->max_speed < USB_SPEED_FULL
> -			|| !bind || !driver->disconnect || !driver->setup)
> +			|| !driver->disconnect || !driver->setup)
>  		return -EINVAL;
>  
> -	if (udc_controller->driver)
> -		return -EBUSY;
> -
>  	/* lock is needed but whether should use this lock or another */
> -	spin_lock_irqsave(&udc_controller->lock, flags);
> +	spin_lock_irqsave(&udc->lock, flags);
>  
>  	driver->driver.bus = NULL;
> -	/* hook up the driver */
> -	udc_controller->driver = driver;
> -	udc_controller->gadget.dev.driver = &driver->driver;
> -	spin_unlock_irqrestore(&udc_controller->lock, flags);
> -
> -	/* bind udc driver to gadget driver */
> -	retval = bind(&udc_controller->gadget, driver);
> -	if (retval) {
> -		VDBG("bind to %s --> %d", driver->driver.name, retval);
> -		udc_controller->gadget.dev.driver = NULL;
> -		udc_controller->driver = NULL;
> -		goto out;
> -	}
>  
> -	if (!IS_ERR_OR_NULL(udc_controller->transceiver)) {
> +	if (!IS_ERR_OR_NULL(udc->transceiver)) {
>  		/* Suspend the controller until OTG enable it */
> -		udc_controller->stopped = 1;
> +		udc->stopped = 1;
>  		printk(KERN_INFO "Suspend udc for OTG auto detect\n");
>  
>  		/* connect to bus through transceiver */
> -		if (!IS_ERR_OR_NULL(udc_controller->transceiver)) {
> -			retval = otg_set_peripheral(
> -					udc_controller->transceiver->otg,
> -						    &udc_controller->gadget);
> +		if (!IS_ERR_OR_NULL(udc->transceiver)) {
> +			retval = otg_set_peripheral(udc->transceiver->otg,
> +					&udc->gadget);
>  			if (retval < 0) {
>  				ERR("can't bind to transceiver\n");
> -				driver->unbind(&udc_controller->gadget);
> -				udc_controller->gadget.dev.driver = 0;
> -				udc_controller->driver = 0;
>  				return retval;
>  			}
>  		}
>  	} else {
> -		/* Enable DR IRQ reg and set USBCMD reg Run bit */
> -		dr_controller_run(udc_controller);
> -		udc_controller->usb_state = USB_STATE_ATTACHED;
> -		udc_controller->ep0_state = WAIT_FOR_SETUP;
> -		udc_controller->ep0_dir = 0;
> +		/* hook up the driver */
> +		udc->driver = driver;
> +		udc->gadget.dev.driver = &driver->driver;
> +		dr_controller_run(udc);
> +		udc->usb_state = USB_STATE_ATTACHED;
> +		udc->ep0_state = WAIT_FOR_SETUP;
> +		udc->ep0_dir = USB_DIR_OUT;
>  	}
> -	printk(KERN_INFO "%s: bind to driver %s\n",
> -			udc_controller->gadget.name, driver->driver.name);
> +	spin_unlock_irqrestore(&udc->lock, flags);
>  
> -out:
> -	if (retval)
> -		printk(KERN_WARNING "gadget driver register failed %d\n",
> -		       retval);
> -	return retval;
> +	return 0;
>  }
>  
>  /* Disconnect from gadget driver */
> -static int fsl_stop(struct usb_gadget_driver *driver)
> +static int fsl_udc_stop(struct usb_gadget *gadget,
> +	struct usb_gadget_driver *driver)
>  {
> +	struct fsl_udc *udc;
>  	struct fsl_ep *loop_ep;
>  	unsigned long flags;
>  
> -	if (!udc_controller)
> -		return -ENODEV;
> -
> -	if (!driver || driver != udc_controller->driver || !driver->unbind)
> -		return -EINVAL;
> -
> -	if (!IS_ERR_OR_NULL(udc_controller->transceiver))
> -		otg_set_peripheral(udc_controller->transceiver->otg, NULL);
> +	udc = container_of(gadget, struct fsl_udc, gadget);
>  
>  	/* stop DR, disable intr */
> -	dr_controller_stop(udc_controller);
> +	dr_controller_stop(udc);
>  
>  	/* in fact, no needed */
> -	udc_controller->usb_state = USB_STATE_ATTACHED;
> -	udc_controller->ep0_state = WAIT_FOR_SETUP;
> -	udc_controller->ep0_dir = 0;
> +	udc->usb_state = USB_STATE_ATTACHED;
> +	udc->ep0_state = WAIT_FOR_SETUP;
> +	udc->ep0_dir = USB_DIR_OUT;
>  
>  	/* stand operation */
> -	spin_lock_irqsave(&udc_controller->lock, flags);
> -	udc_controller->gadget.speed = USB_SPEED_UNKNOWN;
> -	nuke(&udc_controller->eps[0], -ESHUTDOWN);
> -	list_for_each_entry(loop_ep, &udc_controller->gadget.ep_list,
> -			ep.ep_list)
> +	spin_lock_irqsave(&udc->lock, flags);
> +	udc->gadget.speed = USB_SPEED_UNKNOWN;
> +	nuke(&udc->eps[0], -ESHUTDOWN);
> +	list_for_each_entry(loop_ep, &udc->gadget.ep_list, ep.ep_list)
>  		nuke(loop_ep, -ESHUTDOWN);
> -	spin_unlock_irqrestore(&udc_controller->lock, flags);
> -
> -	/* report disconnect; the controller is already quiesced */
> -	driver->disconnect(&udc_controller->gadget);
> +	spin_unlock_irqrestore(&udc->lock, flags);
>  
> -	/* unbind gadget and unhook driver. */
> -	driver->unbind(&udc_controller->gadget);
> -	udc_controller->gadget.dev.driver = NULL;
> -	udc_controller->driver = NULL;
> +	udc->gadget.dev.driver = NULL;
> +	udc->driver = NULL;
>  
>  	printk(KERN_WARNING "unregistered gadget driver '%s'\n",
>  	       driver->driver.name);
> @@ -2088,8 +2058,8 @@ static int fsl_proc_read(char *page, char **start, off_t off, int count,
>  	u32 tmp_reg;
>  	struct fsl_ep *ep = NULL;
>  	struct fsl_req *req;
> +	struct fsl_udc *udc = _dev;
>  
> -	struct fsl_udc *udc = udc_controller;
>  	if (off != 0)
>  		return 0;
>  
> @@ -2318,7 +2288,7 @@ static int fsl_proc_read(char *page, char **start, off_t off, int count,
>  }
>  
>  #define create_proc_file()	create_proc_read_entry(proc_filename, \
> -				0, NULL, fsl_proc_read, NULL)
> +				0, NULL, fsl_proc_read, udc)
>  
>  #define remove_proc_file()	remove_proc_entry(proc_filename, NULL)
>  
> @@ -2334,10 +2304,12 @@ static int fsl_proc_read(char *page, char **start, off_t off, int count,
>  /* Release udc structures */
>  static void fsl_udc_release(struct device *dev)
>  {
> -	complete(udc_controller->done);
> -	dma_free_coherent(dev->parent, udc_controller->ep_qh_size,
> -			udc_controller->ep_qh, udc_controller->ep_qh_dma);
> -	kfree(udc_controller);
> +	struct fsl_udc *udc = container_of(dev, struct fsl_udc, gadget.dev);
> +
> +	complete(udc->done);
> +	dma_free_coherent(dev->parent, udc->ep_qh_size,
> +			udc->ep_qh, udc->ep_qh_dma);
> +	kfree(udc);
>  }
>  
>  /******************************************************************
> @@ -2436,6 +2408,7 @@ static int __init struct_ep_setup(struct fsl_udc *udc, unsigned char index,
>   */
>  static int __init fsl_udc_probe(struct platform_device *pdev)
>  {
> +	struct fsl_udc *udc;
>  	struct fsl_usb2_platform_data *pdata;
>  	struct resource *res;
>  	int ret = -ENODEV;
> @@ -2447,21 +2420,21 @@ static int __init fsl_udc_probe(struct platform_device *pdev)
>  		return -ENODEV;
>  	}
>  
> -	udc_controller = kzalloc(sizeof(struct fsl_udc), GFP_KERNEL);
> -	if (udc_controller == NULL) {
> +	udc = kzalloc(sizeof(struct fsl_udc), GFP_KERNEL);
> +	if (udc == NULL) {
>  		ERR("malloc udc failed\n");
>  		return -ENOMEM;
>  	}
>  
>  	pdata = pdev->dev.platform_data;
> -	udc_controller->pdata = pdata;
> -	spin_lock_init(&udc_controller->lock);
> -	udc_controller->stopped = 1;
> +	udc->pdata = pdata;
> +	spin_lock_init(&udc->lock);
> +	udc->stopped = 1;
>  
>  #ifdef CONFIG_USB_OTG
>  	if (pdata->operating_mode == FSL_USB2_DR_OTG) {
> -		udc_controller->transceiver = usb_get_phy(USB_PHY_TYPE_USB2);
> -		if (IS_ERR_OR_NULL(udc_controller->transceiver)) {
> +		udc->transceiver = usb_get_phy(USB_PHY_TYPE_USB2);
> +		if (IS_ERR_OR_NULL(udc->transceiver)) {
>  			ERR("Can't find OTG driver!\n");
>  			ret = -ENODEV;
>  			goto err_kfree;
> @@ -2522,90 +2495,90 @@ static int __init fsl_udc_probe(struct platform_device *pdev)
>  	}
>  	/* Get max device endpoints */
>  	/* DEN is bidirectional ep number, max_ep doubles the number */
> -	udc_controller->max_ep = (dccparams & DCCPARAMS_DEN_MASK) * 2;
> +	udc->max_ep = (dccparams & DCCPARAMS_DEN_MASK) * 2;
>  
> -	udc_controller->irq = platform_get_irq(pdev, 0);
> -	if (!udc_controller->irq) {
> +	udc->irq = platform_get_irq(pdev, 0);
> +	if (!udc->irq) {
>  		ret = -ENODEV;
>  		goto err_iounmap;
>  	}
>  
> -	ret = request_irq(udc_controller->irq, fsl_udc_irq, IRQF_SHARED,
> -			driver_name, udc_controller);
> +	ret = request_irq(udc->irq, fsl_udc_irq, IRQF_SHARED,
> +			driver_name, udc);
>  	if (ret != 0) {
>  		ERR("cannot request irq %d err %d\n",
> -				udc_controller->irq, ret);
> +				udc->irq, ret);
>  		goto err_iounmap;
>  	}
>  
>  	/* Initialize the udc structure including QH member and other member */
> -	if (struct_udc_setup(udc_controller, pdev)) {
> +	if (struct_udc_setup(udc, pdev)) {
>  		ERR("Can't initialize udc data structure\n");
>  		ret = -ENOMEM;
>  		goto err_free_irq;
>  	}
>  
> -	if (IS_ERR_OR_NULL(udc_controller->transceiver)) {
> +	if (IS_ERR_OR_NULL(udc->transceiver)) {
>  		/* initialize usb hw reg except for regs for EP,
>  		 * leave usbintr reg untouched */
> -		dr_controller_setup(udc_controller);
> +		dr_controller_setup(udc);
>  	}
>  
>  	fsl_udc_clk_finalize(pdev);
>  
>  	/* Setup gadget structure */
> -	udc_controller->gadget.ops = &fsl_gadget_ops;
> -	udc_controller->gadget.max_speed = USB_SPEED_HIGH;
> -	udc_controller->gadget.ep0 = &udc_controller->eps[0].ep;
> -	INIT_LIST_HEAD(&udc_controller->gadget.ep_list);
> -	udc_controller->gadget.speed = USB_SPEED_UNKNOWN;
> -	udc_controller->gadget.name = driver_name;
> +	udc->gadget.ops = &fsl_gadget_ops;
> +	udc->gadget.max_speed = USB_SPEED_HIGH;
> +	udc->gadget.ep0 = &udc->eps[0].ep;
> +	INIT_LIST_HEAD(&udc->gadget.ep_list);
> +	udc->gadget.speed = USB_SPEED_UNKNOWN;
> +	udc->gadget.name = driver_name;
>  	udc->vbus_active = true;
>  
>  	/* Setup gadget.dev and register with kernel */
> -	dev_set_name(&udc_controller->gadget.dev, "gadget");
> -	udc_controller->gadget.dev.release = fsl_udc_release;
> -	udc_controller->gadget.dev.parent = &pdev->dev;
> -	udc_controller->gadget.dev.of_node = pdev->dev.of_node;
> -	ret = device_register(&udc_controller->gadget.dev);
> +	dev_set_name(&udc->gadget.dev, "gadget");
> +	udc->gadget.dev.release = fsl_udc_release;
> +	udc->gadget.dev.parent = &pdev->dev;
> +	udc->gadget.dev.of_node = pdev->dev.of_node;
> +	ret = device_register(&udc->gadget.dev);
>  	if (ret < 0)
>  		goto err_free_irq;
>  
> -	if (!IS_ERR_OR_NULL(udc_controller->transceiver))
> -		udc_controller->gadget.is_otg = 1;
> +	if (!IS_ERR_OR_NULL(udc->transceiver))
> +		udc->gadget.is_otg = 1;
>  
>  	/* setup QH and epctrl for ep0 */
> -	ep0_setup(udc_controller);
> +	ep0_setup(udc);
>  
>  	/* setup udc->eps[] for ep0 */
> -	struct_ep_setup(udc_controller, 0, "ep0", 0);
> +	struct_ep_setup(udc, 0, "ep0", 0);
>  	/* for ep0: the desc defined here;
>  	 * for other eps, gadget layer called ep_enable with defined desc
>  	 */
> -	udc_controller->eps[0].ep.desc = &fsl_ep0_desc;
> -	udc_controller->eps[0].ep.maxpacket = USB_MAX_CTRL_PAYLOAD;
> +	udc->eps[0].ep.desc = &fsl_ep0_desc;
> +	udc->eps[0].ep.maxpacket = USB_MAX_CTRL_PAYLOAD;
>  
>  	/* setup the udc->eps[] for non-control endpoints and link
>  	 * to gadget.ep_list */
> -	for (i = 1; i < (int)(udc_controller->max_ep / 2); i++) {
> +	for (i = 1; i < (int)(udc->max_ep / 2); i++) {
>  		char name[14];
>  
>  		sprintf(name, "ep%dout", i);
> -		struct_ep_setup(udc_controller, i * 2, name, 1);
> +		struct_ep_setup(udc, i * 2, name, 1);
>  		sprintf(name, "ep%din", i);
> -		struct_ep_setup(udc_controller, i * 2 + 1, name, 1);
> +		struct_ep_setup(udc, i * 2 + 1, name, 1);
>  	}
>  
>  	/* use dma_pool for TD management */
> -	udc_controller->td_pool = dma_pool_create("udc_td", &pdev->dev,
> +	udc->td_pool = dma_pool_create("udc_td", &pdev->dev,
>  			sizeof(struct ep_td_struct),
>  			DTD_ALIGNMENT, UDC_DMA_BOUNDARY);
> -	if (udc_controller->td_pool == NULL) {
> +	if (udc->td_pool == NULL) {
>  		ret = -ENOMEM;
>  		goto err_unregister;
>  	}
>  
> -	ret = usb_add_gadget_udc(&pdev->dev, &udc_controller->gadget);
> +	ret = usb_add_gadget_udc(&pdev->dev, &udc->gadget);
>  	if (ret)
>  		goto err_del_udc;
>  
> @@ -2613,11 +2586,11 @@ static int __init fsl_udc_probe(struct platform_device *pdev)
>  	return 0;
>  
>  err_del_udc:
> -	dma_pool_destroy(udc_controller->td_pool);
> +	dma_pool_destroy(udc->td_pool);
>  err_unregister:
> -	device_unregister(&udc_controller->gadget.dev);
> +	device_unregister(&udc->gadget.dev);
>  err_free_irq:
> -	free_irq(udc_controller->irq, udc_controller);
> +	free_irq(udc->irq, udc);
>  err_iounmap:
>  	if (pdata->exit)
>  		pdata->exit(pdev);
> @@ -2628,8 +2601,7 @@ err_release_mem_region:
>  	if (pdata->operating_mode == FSL_USB2_DR_DEVICE)
>  		release_mem_region(res->start, resource_size(res));
>  err_kfree:
> -	kfree(udc_controller);
> -	udc_controller = NULL;
> +	kfree(udc);
>  	return ret;
>  }
>  
> @@ -2638,16 +2610,13 @@ err_kfree:
>   */
>  static int __exit fsl_udc_remove(struct platform_device *pdev)
>  {
> +	struct fsl_udc *udc = dev_get_drvdata(&pdev->dev);
>  	struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
>  	struct fsl_usb2_platform_data *pdata = pdev->dev.platform_data;
> -
>  	DECLARE_COMPLETION(done);
>  
> -	if (!udc_controller)
> -		return -ENODEV;
> -
> -	usb_del_gadget_udc(&udc_controller->gadget);
> -	udc_controller->done = &done;
> +	usb_del_gadget_udc(&udc->gadget);
> +	udc->done = &done;
>  
>  	fsl_udc_clk_release();
>  
> @@ -2655,17 +2624,17 @@ static int __exit fsl_udc_remove(struct platform_device *pdev)
>  	remove_proc_file();
>  
>  	/* Free allocated memory */
> -	kfree(udc_controller->status_req->req.buf);
> -	kfree(udc_controller->status_req);
> -	kfree(udc_controller->eps);
> +	kfree(udc->status_req->req.buf);
> +	kfree(udc->status_req);
> +	kfree(udc->eps);
>  
> -	dma_pool_destroy(udc_controller->td_pool);
> -	free_irq(udc_controller->irq, udc_controller);
> +	dma_pool_destroy(udc->td_pool);
> +	free_irq(udc->irq, udc);
>  	iounmap(dr_regs);
>  	if (pdata->operating_mode == FSL_USB2_DR_DEVICE)
>  		release_mem_region(res->start, resource_size(res));
>  
> -	device_unregister(&udc_controller->gadget.dev);
> +	device_unregister(&udc->gadget.dev);
>  	/* free udc --wait for the release() finished */
>  	wait_for_completion(&done);
>  
> @@ -2685,7 +2654,8 @@ static int __exit fsl_udc_remove(struct platform_device *pdev)
>   -----------------------------------------------------------------*/
>  static int fsl_udc_suspend(struct platform_device *pdev, pm_message_t state)
>  {
> -	dr_controller_stop(udc_controller);
> +	struct fsl_udc *udc = dev_get_drvdata(&pdev->dev);
> +	dr_controller_stop(udc);
>  	return 0;
>  }
>  
> @@ -2695,20 +2665,21 @@ static int fsl_udc_suspend(struct platform_device *pdev, pm_message_t state)
>   *-----------------------------------------------------------------*/
>  static int fsl_udc_resume(struct platform_device *pdev)
>  {
> +	struct fsl_udc *udc = dev_get_drvdata(&pdev->dev);
>  	/* Enable DR irq reg and set controller Run */
> -	if (udc_controller->stopped) {
> -		dr_controller_setup(udc_controller);
> -		dr_controller_run(udc_controller);
> +	if (udc->stopped) {
> +		dr_controller_setup(udc);
> +		dr_controller_run(udc);
>  	}
> -	udc_controller->usb_state = USB_STATE_ATTACHED;
> -	udc_controller->ep0_state = WAIT_FOR_SETUP;
> -	udc_controller->ep0_dir = 0;
> +	udc->usb_state = USB_STATE_ATTACHED;
> +	udc->ep0_state = WAIT_FOR_SETUP;
> +	udc->ep0_dir = USB_DIR_OUT;
>  	return 0;
>  }
>  
>  static int fsl_udc_otg_suspend(struct device *dev, pm_message_t state)
>  {
> -	struct fsl_udc *udc = udc_controller;
> +	struct fsl_udc *udc = container_of(dev, struct fsl_udc, gadget.dev);
>  	u32 mode, usbcmd;
>  
>  	mode = fsl_readl(&dr_regs->usbmode) & USB_MODE_CTRL_MODE_MASK;
> @@ -2744,15 +2715,17 @@ static int fsl_udc_otg_suspend(struct device *dev, pm_message_t state)
>  
>  static int fsl_udc_otg_resume(struct device *dev)
>  {
> +	struct fsl_udc *udc = container_of(dev, struct fsl_udc, gadget.dev);
> +
>  	pr_debug("%s(): stopped %d  already_stopped %d\n", __func__,
> -		 udc_controller->stopped, udc_controller->already_stopped);
> +		 udc->stopped, udc->already_stopped);
>  
>  	/*
>  	 * If the controller was stopped at suspend time, then
>  	 * don't resume it now.
>  	 */
> -	if (udc_controller->already_stopped) {
> -		udc_controller->already_stopped = 0;
> +	if (udc->already_stopped) {
> +		udc->already_stopped = 0;
>  		pr_debug("gadget was already stopped, leaving early\n");
>  		return 0;
>  	}
> -- 
> 1.7.2.5
>

Patch

diff --git a/drivers/usb/gadget/fsl_udc_core.c b/drivers/usb/gadget/fsl_udc_core.c
index 0a0d6a6..d113f39 100644
--- a/drivers/usb/gadget/fsl_udc_core.c
+++ b/drivers/usb/gadget/fsl_udc_core.c
@@ -63,9 +63,6 @@  static struct usb_dr_device *dr_regs;
 
 static struct usb_sys_interface *usb_sys_regs;
 
-/* it is initialized in probe()  */
-static struct fsl_udc *udc_controller = NULL;
-
 static const struct usb_endpoint_descriptor
 fsl_ep0_desc = {
 	.bLength =		USB_DT_ENDPOINT_SIZE,
@@ -783,12 +780,14 @@  static void fsl_queue_td(struct fsl_ep *ep, struct fsl_req *req)
 }
 
 /* Fill in the dTD structure
+ * @udc: driver private data
  * @req: request that the transfer belongs to
  * @length: return actually data length of the dTD
  * @dma: return dma address of the dTD
  * @is_last: return flag if it is the last dTD of the request
  * return: pointer to the built dTD */
-static struct ep_td_struct *fsl_build_dtd(struct fsl_req *req, unsigned *length,
+static struct ep_td_struct *fsl_build_dtd(struct fsl_udc *udc,
+		struct fsl_req *req, unsigned *length,
 		dma_addr_t *dma, int *is_last, gfp_t gfp_flags)
 {
 	u32 swap_temp;
@@ -798,7 +797,7 @@  static struct ep_td_struct *fsl_build_dtd(struct fsl_req *req, unsigned *length,
 	*length = min(req->req.length - req->req.actual,
 			(unsigned)EP_MAX_LENGTH_TRANSFER);
 
-	dtd = dma_pool_alloc(udc_controller->td_pool, gfp_flags, dma);
+	dtd = dma_pool_alloc(udc->td_pool, gfp_flags, dma);
 	if (dtd == NULL)
 		return dtd;
 
@@ -848,7 +847,8 @@  static struct ep_td_struct *fsl_build_dtd(struct fsl_req *req, unsigned *length,
 }
 
 /* Generate dtd chain for a request */
-static int fsl_req_to_dtd(struct fsl_req *req, gfp_t gfp_flags)
+static int fsl_req_to_dtd(struct fsl_udc *udc, struct fsl_req *req,
+		gfp_t gfp_flags)
 {
 	unsigned	count;
 	int		is_last;
@@ -857,7 +857,8 @@  static int fsl_req_to_dtd(struct fsl_req *req, gfp_t gfp_flags)
 	dma_addr_t dma;
 
 	do {
-		dtd = fsl_build_dtd(req, &count, &dma, &is_last, gfp_flags);
+		dtd = fsl_build_dtd(udc, req, &count, &dma, &is_last,
+				gfp_flags);
 		if (dtd == NULL)
 			return -ENOMEM;
 
@@ -932,7 +933,7 @@  fsl_ep_queue(struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags)
 	req->dtd_count = 0;
 
 	/* build dtds and push them to device queue */
-	if (!fsl_req_to_dtd(req, gfp_flags)) {
+	if (!fsl_req_to_dtd(udc, req, gfp_flags)) {
 		spin_lock_irqsave(&udc->lock, flags);
 		fsl_queue_td(ep, req);
 	} else {
@@ -1258,9 +1259,10 @@  static int fsl_pullup(struct usb_gadget *gadget, int is_on)
 	return 0;
 }
 
-static int fsl_start(struct usb_gadget_driver *driver,
-		int (*bind)(struct usb_gadget *, struct usb_gadget_driver *));
-static int fsl_stop(struct usb_gadget_driver *driver);
+static int fsl_udc_start(struct usb_gadget *gadget,
+		struct usb_gadget_driver *driver);
+static int fsl_udc_stop(struct usb_gadget *gadget,
+		struct usb_gadget_driver *driver);
 /* defined in gadget.h */
 static struct usb_gadget_ops fsl_gadget_ops = {
 	.get_frame = fsl_get_frame,
@@ -1269,8 +1271,8 @@  static struct usb_gadget_ops fsl_gadget_ops = {
 	.vbus_session = fsl_vbus_session,
 	.vbus_draw = fsl_vbus_draw,
 	.pullup = fsl_pullup,
-	.start = fsl_start,
-	.stop = fsl_stop,
+	.udc_start = fsl_udc_start,
+	.udc_stop = fsl_udc_stop,
 };
 
 /* Set protocol stall on ep0, protocol stall will automatically be cleared
@@ -1314,7 +1316,7 @@  static int ep0_prime_status(struct fsl_udc *udc, int direction)
 			ep_is_in(ep) ? DMA_TO_DEVICE : DMA_FROM_DEVICE);
 	req->mapped = 1;
 
-	if (fsl_req_to_dtd(req, GFP_ATOMIC) == 0)
+	if (fsl_req_to_dtd(udc, req, GFP_ATOMIC) == 0)
 		fsl_queue_td(ep, req);
 	else
 		return -ENOMEM;
@@ -1398,7 +1400,7 @@  static void ch9getstatus(struct fsl_udc *udc, u8 request_type, u16 value,
 	req->mapped = 1;
 
 	/* prime the data phase */
-	if ((fsl_req_to_dtd(req, GFP_ATOMIC) == 0))
+	if ((fsl_req_to_dtd(udc, req, GFP_ATOMIC) == 0))
 		fsl_queue_td(ep, req);
 	else			/* no mem */
 		goto stall;
@@ -1422,7 +1424,7 @@  static void setup_received_irq(struct fsl_udc *udc,
 
 	udc_reset_ep_queue(udc, 0);
 
-	/* We process some stardard setup requests here */
+	/* We process some standard setup requests here */
 	switch (setup->bRequest) {
 	case USB_REQ_GET_STATUS:
 		/* Data+Status phase from udc */
@@ -1954,114 +1956,82 @@  static irqreturn_t fsl_udc_irq(int irq, void *_udc)
  * Hook to gadget drivers
  * Called by initialization code of gadget drivers
 *----------------------------------------------------------------*/
-static int fsl_start(struct usb_gadget_driver *driver,
-		int (*bind)(struct usb_gadget *, struct usb_gadget_driver *))
+static int fsl_udc_start(struct usb_gadget *gadget,
+	struct usb_gadget_driver *driver)
 {
+	struct fsl_udc *udc;
 	int retval = -ENODEV;
-	unsigned long flags = 0;
+	unsigned long flags;
 
-	if (!udc_controller)
+	udc = container_of(gadget, struct fsl_udc, gadget);
+	if (!udc)
 		return -ENODEV;
 
 	if (!driver || driver->max_speed < USB_SPEED_FULL
-			|| !bind || !driver->disconnect || !driver->setup)
+			|| !driver->disconnect || !driver->setup)
 		return -EINVAL;
 
-	if (udc_controller->driver)
-		return -EBUSY;
-
 	/* lock is needed but whether should use this lock or another */
-	spin_lock_irqsave(&udc_controller->lock, flags);
+	spin_lock_irqsave(&udc->lock, flags);
 
 	driver->driver.bus = NULL;
-	/* hook up the driver */
-	udc_controller->driver = driver;
-	udc_controller->gadget.dev.driver = &driver->driver;
-	spin_unlock_irqrestore(&udc_controller->lock, flags);
-
-	/* bind udc driver to gadget driver */
-	retval = bind(&udc_controller->gadget, driver);
-	if (retval) {
-		VDBG("bind to %s --> %d", driver->driver.name, retval);
-		udc_controller->gadget.dev.driver = NULL;
-		udc_controller->driver = NULL;
-		goto out;
-	}
 
-	if (!IS_ERR_OR_NULL(udc_controller->transceiver)) {
+	if (!IS_ERR_OR_NULL(udc->transceiver)) {
 		/* Suspend the controller until OTG enable it */
-		udc_controller->stopped = 1;
+		udc->stopped = 1;
 		printk(KERN_INFO "Suspend udc for OTG auto detect\n");
 
 		/* connect to bus through transceiver */
-		if (!IS_ERR_OR_NULL(udc_controller->transceiver)) {
-			retval = otg_set_peripheral(
-					udc_controller->transceiver->otg,
-						    &udc_controller->gadget);
+		if (!IS_ERR_OR_NULL(udc->transceiver)) {
+			retval = otg_set_peripheral(udc->transceiver->otg,
+					&udc->gadget);
 			if (retval < 0) {
 				ERR("can't bind to transceiver\n");
-				driver->unbind(&udc_controller->gadget);
-				udc_controller->gadget.dev.driver = 0;
-				udc_controller->driver = 0;
 				return retval;
 			}
 		}
 	} else {
-		/* Enable DR IRQ reg and set USBCMD reg Run bit */
-		dr_controller_run(udc_controller);
-		udc_controller->usb_state = USB_STATE_ATTACHED;
-		udc_controller->ep0_state = WAIT_FOR_SETUP;
-		udc_controller->ep0_dir = 0;
+		/* hook up the driver */
+		udc->driver = driver;
+		udc->gadget.dev.driver = &driver->driver;
+		dr_controller_run(udc);
+		udc->usb_state = USB_STATE_ATTACHED;
+		udc->ep0_state = WAIT_FOR_SETUP;
+		udc->ep0_dir = USB_DIR_OUT;
 	}
-	printk(KERN_INFO "%s: bind to driver %s\n",
-			udc_controller->gadget.name, driver->driver.name);
+	spin_unlock_irqrestore(&udc->lock, flags);
 
-out:
-	if (retval)
-		printk(KERN_WARNING "gadget driver register failed %d\n",
-		       retval);
-	return retval;
+	return 0;
 }
 
 /* Disconnect from gadget driver */
-static int fsl_stop(struct usb_gadget_driver *driver)
+static int fsl_udc_stop(struct usb_gadget *gadget,
+	struct usb_gadget_driver *driver)
 {
+	struct fsl_udc *udc;
 	struct fsl_ep *loop_ep;
 	unsigned long flags;
 
-	if (!udc_controller)
-		return -ENODEV;
-
-	if (!driver || driver != udc_controller->driver || !driver->unbind)
-		return -EINVAL;
-
-	if (!IS_ERR_OR_NULL(udc_controller->transceiver))
-		otg_set_peripheral(udc_controller->transceiver->otg, NULL);
+	udc = container_of(gadget, struct fsl_udc, gadget);
 
 	/* stop DR, disable intr */
-	dr_controller_stop(udc_controller);
+	dr_controller_stop(udc);
 
 	/* in fact, no needed */
-	udc_controller->usb_state = USB_STATE_ATTACHED;
-	udc_controller->ep0_state = WAIT_FOR_SETUP;
-	udc_controller->ep0_dir = 0;
+	udc->usb_state = USB_STATE_ATTACHED;
+	udc->ep0_state = WAIT_FOR_SETUP;
+	udc->ep0_dir = USB_DIR_OUT;
 
 	/* stand operation */
-	spin_lock_irqsave(&udc_controller->lock, flags);
-	udc_controller->gadget.speed = USB_SPEED_UNKNOWN;
-	nuke(&udc_controller->eps[0], -ESHUTDOWN);
-	list_for_each_entry(loop_ep, &udc_controller->gadget.ep_list,
-			ep.ep_list)
+	spin_lock_irqsave(&udc->lock, flags);
+	udc->gadget.speed = USB_SPEED_UNKNOWN;
+	nuke(&udc->eps[0], -ESHUTDOWN);
+	list_for_each_entry(loop_ep, &udc->gadget.ep_list, ep.ep_list)
 		nuke(loop_ep, -ESHUTDOWN);
-	spin_unlock_irqrestore(&udc_controller->lock, flags);
-
-	/* report disconnect; the controller is already quiesced */
-	driver->disconnect(&udc_controller->gadget);
+	spin_unlock_irqrestore(&udc->lock, flags);
 
-	/* unbind gadget and unhook driver. */
-	driver->unbind(&udc_controller->gadget);
-	udc_controller->gadget.dev.driver = NULL;
-	udc_controller->driver = NULL;
+	udc->gadget.dev.driver = NULL;
+	udc->driver = NULL;
 
 	printk(KERN_WARNING "unregistered gadget driver '%s'\n",
 	       driver->driver.name);
@@ -2088,8 +2058,8 @@  static int fsl_proc_read(char *page, char **start, off_t off, int count,
 	u32 tmp_reg;
 	struct fsl_ep *ep = NULL;
 	struct fsl_req *req;
+	struct fsl_udc *udc = _dev;
 
-	struct fsl_udc *udc = udc_controller;
 	if (off != 0)
 		return 0;
 
@@ -2318,7 +2288,7 @@  static int fsl_proc_read(char *page, char **start, off_t off, int count,
 }
 
 #define create_proc_file()	create_proc_read_entry(proc_filename, \
-				0, NULL, fsl_proc_read, NULL)
+				0, NULL, fsl_proc_read, udc)
 
 #define remove_proc_file()	remove_proc_entry(proc_filename, NULL)
 
@@ -2334,10 +2304,12 @@  static int fsl_proc_read(char *page, char **start, off_t off, int count,
 /* Release udc structures */
 static void fsl_udc_release(struct device *dev)
 {
-	complete(udc_controller->done);
-	dma_free_coherent(dev->parent, udc_controller->ep_qh_size,
-			udc_controller->ep_qh, udc_controller->ep_qh_dma);
-	kfree(udc_controller);
+	struct fsl_udc *udc = container_of(dev, struct fsl_udc, gadget.dev);
+
+	complete(udc->done);
+	dma_free_coherent(dev->parent, udc->ep_qh_size,
+			udc->ep_qh, udc->ep_qh_dma);
+	kfree(udc);
 }
 
 /******************************************************************
@@ -2436,6 +2408,7 @@  static int __init struct_ep_setup(struct fsl_udc *udc, unsigned char index,
  */
 static int __init fsl_udc_probe(struct platform_device *pdev)
 {
+	struct fsl_udc *udc;
 	struct fsl_usb2_platform_data *pdata;
 	struct resource *res;
 	int ret = -ENODEV;
@@ -2447,21 +2420,21 @@  static int __init fsl_udc_probe(struct platform_device *pdev)
 		return -ENODEV;
 	}
 
-	udc_controller = kzalloc(sizeof(struct fsl_udc), GFP_KERNEL);
-	if (udc_controller == NULL) {
+	udc = kzalloc(sizeof(struct fsl_udc), GFP_KERNEL);
+	if (udc == NULL) {
 		ERR("malloc udc failed\n");
 		return -ENOMEM;
 	}
 
 	pdata = pdev->dev.platform_data;
-	udc_controller->pdata = pdata;
-	spin_lock_init(&udc_controller->lock);
-	udc_controller->stopped = 1;
+	udc->pdata = pdata;
+	spin_lock_init(&udc->lock);
+	udc->stopped = 1;
 
 #ifdef CONFIG_USB_OTG
 	if (pdata->operating_mode == FSL_USB2_DR_OTG) {
-		udc_controller->transceiver = usb_get_phy(USB_PHY_TYPE_USB2);
-		if (IS_ERR_OR_NULL(udc_controller->transceiver)) {
+		udc->transceiver = usb_get_phy(USB_PHY_TYPE_USB2);
+		if (IS_ERR_OR_NULL(udc->transceiver)) {
 			ERR("Can't find OTG driver!\n");
 			ret = -ENODEV;
 			goto err_kfree;
@@ -2522,90 +2495,90 @@  static int __init fsl_udc_probe(struct platform_device *pdev)
 	}
 	/* Get max device endpoints */
 	/* DEN is bidirectional ep number, max_ep doubles the number */
-	udc_controller->max_ep = (dccparams & DCCPARAMS_DEN_MASK) * 2;
+	udc->max_ep = (dccparams & DCCPARAMS_DEN_MASK) * 2;
 
-	udc_controller->irq = platform_get_irq(pdev, 0);
-	if (!udc_controller->irq) {
+	udc->irq = platform_get_irq(pdev, 0);
+	if (!udc->irq) {
 		ret = -ENODEV;
 		goto err_iounmap;
 	}
 
-	ret = request_irq(udc_controller->irq, fsl_udc_irq, IRQF_SHARED,
-			driver_name, udc_controller);
+	ret = request_irq(udc->irq, fsl_udc_irq, IRQF_SHARED,
+			driver_name, udc);
 	if (ret != 0) {
 		ERR("cannot request irq %d err %d\n",
-				udc_controller->irq, ret);
+				udc->irq, ret);
 		goto err_iounmap;
 	}
 
 	/* Initialize the udc structure including QH member and other member */
-	if (struct_udc_setup(udc_controller, pdev)) {
+	if (struct_udc_setup(udc, pdev)) {
 		ERR("Can't initialize udc data structure\n");
 		ret = -ENOMEM;
 		goto err_free_irq;
 	}
 
-	if (IS_ERR_OR_NULL(udc_controller->transceiver)) {
+	if (IS_ERR_OR_NULL(udc->transceiver)) {
 		/* initialize usb hw reg except for regs for EP,
 		 * leave usbintr reg untouched */
-		dr_controller_setup(udc_controller);
+		dr_controller_setup(udc);
 	}
 
 	fsl_udc_clk_finalize(pdev);
 
 	/* Setup gadget structure */
-	udc_controller->gadget.ops = &fsl_gadget_ops;
-	udc_controller->gadget.max_speed = USB_SPEED_HIGH;
-	udc_controller->gadget.ep0 = &udc_controller->eps[0].ep;
-	INIT_LIST_HEAD(&udc_controller->gadget.ep_list);
-	udc_controller->gadget.speed = USB_SPEED_UNKNOWN;
-	udc_controller->gadget.name = driver_name;
+	udc->gadget.ops = &fsl_gadget_ops;
+	udc->gadget.max_speed = USB_SPEED_HIGH;
+	udc->gadget.ep0 = &udc->eps[0].ep;
+	INIT_LIST_HEAD(&udc->gadget.ep_list);
+	udc->gadget.speed = USB_SPEED_UNKNOWN;
+	udc->gadget.name = driver_name;
 	udc->vbus_active = true;
 
 	/* Setup gadget.dev and register with kernel */
-	dev_set_name(&udc_controller->gadget.dev, "gadget");
-	udc_controller->gadget.dev.release = fsl_udc_release;
-	udc_controller->gadget.dev.parent = &pdev->dev;
-	udc_controller->gadget.dev.of_node = pdev->dev.of_node;
-	ret = device_register(&udc_controller->gadget.dev);
+	dev_set_name(&udc->gadget.dev, "gadget");
+	udc->gadget.dev.release = fsl_udc_release;
+	udc->gadget.dev.parent = &pdev->dev;
+	udc->gadget.dev.of_node = pdev->dev.of_node;
+	ret = device_register(&udc->gadget.dev);
 	if (ret < 0)
 		goto err_free_irq;
 
-	if (!IS_ERR_OR_NULL(udc_controller->transceiver))
-		udc_controller->gadget.is_otg = 1;
+	if (!IS_ERR_OR_NULL(udc->transceiver))
+		udc->gadget.is_otg = 1;
 
 	/* setup QH and epctrl for ep0 */
-	ep0_setup(udc_controller);
+	ep0_setup(udc);
 
 	/* setup udc->eps[] for ep0 */
-	struct_ep_setup(udc_controller, 0, "ep0", 0);
+	struct_ep_setup(udc, 0, "ep0", 0);
 	/* for ep0: the desc defined here;
 	 * for other eps, gadget layer called ep_enable with defined desc
 	 */
-	udc_controller->eps[0].ep.desc = &fsl_ep0_desc;
-	udc_controller->eps[0].ep.maxpacket = USB_MAX_CTRL_PAYLOAD;
+	udc->eps[0].ep.desc = &fsl_ep0_desc;
+	udc->eps[0].ep.maxpacket = USB_MAX_CTRL_PAYLOAD;
 
 	/* setup the udc->eps[] for non-control endpoints and link
 	 * to gadget.ep_list */
-	for (i = 1; i < (int)(udc_controller->max_ep / 2); i++) {
+	for (i = 1; i < (int)(udc->max_ep / 2); i++) {
 		char name[14];
 
 		sprintf(name, "ep%dout", i);
-		struct_ep_setup(udc_controller, i * 2, name, 1);
+		struct_ep_setup(udc, i * 2, name, 1);
 		sprintf(name, "ep%din", i);
-		struct_ep_setup(udc_controller, i * 2 + 1, name, 1);
+		struct_ep_setup(udc, i * 2 + 1, name, 1);
 	}
 
 	/* use dma_pool for TD management */
-	udc_controller->td_pool = dma_pool_create("udc_td", &pdev->dev,
+	udc->td_pool = dma_pool_create("udc_td", &pdev->dev,
 			sizeof(struct ep_td_struct),
 			DTD_ALIGNMENT, UDC_DMA_BOUNDARY);
-	if (udc_controller->td_pool == NULL) {
+	if (udc->td_pool == NULL) {
 		ret = -ENOMEM;
 		goto err_unregister;
 	}
 
-	ret = usb_add_gadget_udc(&pdev->dev, &udc_controller->gadget);
+	ret = usb_add_gadget_udc(&pdev->dev, &udc->gadget);
 	if (ret)
 		goto err_del_udc;
 
@@ -2613,11 +2586,11 @@  static int __init fsl_udc_probe(struct platform_device *pdev)
 	return 0;
 
 err_del_udc:
-	dma_pool_destroy(udc_controller->td_pool);
+	dma_pool_destroy(udc->td_pool);
 err_unregister:
-	device_unregister(&udc_controller->gadget.dev);
+	device_unregister(&udc->gadget.dev);
 err_free_irq:
-	free_irq(udc_controller->irq, udc_controller);
+	free_irq(udc->irq, udc);
 err_iounmap:
 	if (pdata->exit)
 		pdata->exit(pdev);
@@ -2628,8 +2601,7 @@  err_release_mem_region:
 	if (pdata->operating_mode == FSL_USB2_DR_DEVICE)
 		release_mem_region(res->start, resource_size(res));
 err_kfree:
-	kfree(udc_controller);
-	udc_controller = NULL;
+	kfree(udc);
 	return ret;
 }
 
@@ -2638,16 +2610,13 @@  err_kfree:
  */
 static int __exit fsl_udc_remove(struct platform_device *pdev)
 {
+	struct fsl_udc *udc = dev_get_drvdata(&pdev->dev);
 	struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	struct fsl_usb2_platform_data *pdata = pdev->dev.platform_data;
-
 	DECLARE_COMPLETION(done);
 
-	if (!udc_controller)
-		return -ENODEV;
-
-	usb_del_gadget_udc(&udc_controller->gadget);
-	udc_controller->done = &done;
+	usb_del_gadget_udc(&udc->gadget);
+	udc->done = &done;
 
 	fsl_udc_clk_release();
 
@@ -2655,17 +2624,17 @@  static int __exit fsl_udc_remove(struct platform_device *pdev)
 	remove_proc_file();
 
 	/* Free allocated memory */
-	kfree(udc_controller->status_req->req.buf);
-	kfree(udc_controller->status_req);
-	kfree(udc_controller->eps);
+	kfree(udc->status_req->req.buf);
+	kfree(udc->status_req);
+	kfree(udc->eps);
 
-	dma_pool_destroy(udc_controller->td_pool);
-	free_irq(udc_controller->irq, udc_controller);
+	dma_pool_destroy(udc->td_pool);
+	free_irq(udc->irq, udc);
 	iounmap(dr_regs);
 	if (pdata->operating_mode == FSL_USB2_DR_DEVICE)
 		release_mem_region(res->start, resource_size(res));
 
-	device_unregister(&udc_controller->gadget.dev);
+	device_unregister(&udc->gadget.dev);
 	/* free udc --wait for the release() finished */
 	wait_for_completion(&done);
 
@@ -2685,7 +2654,8 @@  static int __exit fsl_udc_remove(struct platform_device *pdev)
  -----------------------------------------------------------------*/
 static int fsl_udc_suspend(struct platform_device *pdev, pm_message_t state)
 {
-	dr_controller_stop(udc_controller);
+	struct fsl_udc *udc = dev_get_drvdata(&pdev->dev);
+	dr_controller_stop(udc);
 	return 0;
 }
 
@@ -2695,20 +2665,21 @@  static int fsl_udc_suspend(struct platform_device *pdev, pm_message_t state)
  *-----------------------------------------------------------------*/
 static int fsl_udc_resume(struct platform_device *pdev)
 {
+	struct fsl_udc *udc = dev_get_drvdata(&pdev->dev);
 	/* Enable DR irq reg and set controller Run */
-	if (udc_controller->stopped) {
-		dr_controller_setup(udc_controller);
-		dr_controller_run(udc_controller);
+	if (udc->stopped) {
+		dr_controller_setup(udc);
+		dr_controller_run(udc);
 	}
-	udc_controller->usb_state = USB_STATE_ATTACHED;
-	udc_controller->ep0_state = WAIT_FOR_SETUP;
-	udc_controller->ep0_dir = 0;
+	udc->usb_state = USB_STATE_ATTACHED;
+	udc->ep0_state = WAIT_FOR_SETUP;
+	udc->ep0_dir = USB_DIR_OUT;
 	return 0;
 }
 
 static int fsl_udc_otg_suspend(struct device *dev, pm_message_t state)
 {
-	struct fsl_udc *udc = udc_controller;
+	struct fsl_udc *udc = container_of(dev, struct fsl_udc, gadget.dev);
 	u32 mode, usbcmd;
 
 	mode = fsl_readl(&dr_regs->usbmode) & USB_MODE_CTRL_MODE_MASK;
@@ -2744,15 +2715,17 @@  static int fsl_udc_otg_suspend(struct device *dev, pm_message_t state)
 
 static int fsl_udc_otg_resume(struct device *dev)
 {
+	struct fsl_udc *udc = container_of(dev, struct fsl_udc, gadget.dev);
+
 	pr_debug("%s(): stopped %d  already_stopped %d\n", __func__,
-		 udc_controller->stopped, udc_controller->already_stopped);
+		 udc->stopped, udc->already_stopped);
 
 	/*
 	 * If the controller was stopped at suspend time, then
 	 * don't resume it now.
 	 */
-	if (udc_controller->already_stopped) {
-		udc_controller->already_stopped = 0;
+	if (udc->already_stopped) {
+		udc->already_stopped = 0;
 		pr_debug("gadget was already stopped, leaving early\n");
 		return 0;
 	}