diff options
Diffstat (limited to 'drivers/usb/gadget/pch_udc.c')
-rw-r--r-- | drivers/usb/gadget/pch_udc.c | 67 |
1 files changed, 14 insertions, 53 deletions
diff --git a/drivers/usb/gadget/pch_udc.c b/drivers/usb/gadget/pch_udc.c index 6490c0040e3a..a787a8ef672b 100644 --- a/drivers/usb/gadget/pch_udc.c +++ b/drivers/usb/gadget/pch_udc.c | |||
@@ -375,6 +375,7 @@ struct pch_udc_dev { | |||
375 | struct pch_udc_cfg_data cfg_data; | 375 | struct pch_udc_cfg_data cfg_data; |
376 | struct pch_vbus_gpio_data vbus_gpio; | 376 | struct pch_vbus_gpio_data vbus_gpio; |
377 | }; | 377 | }; |
378 | #define to_pch_udc(g) (container_of((g), struct pch_udc_dev, gadget)) | ||
378 | 379 | ||
379 | #define PCH_UDC_PCI_BAR 1 | 380 | #define PCH_UDC_PCI_BAR 1 |
380 | #define PCI_DEVICE_ID_INTEL_EG20T_UDC 0x8808 | 381 | #define PCI_DEVICE_ID_INTEL_EG20T_UDC 0x8808 |
@@ -384,7 +385,6 @@ struct pch_udc_dev { | |||
384 | 385 | ||
385 | static const char ep0_string[] = "ep0in"; | 386 | static const char ep0_string[] = "ep0in"; |
386 | static DEFINE_SPINLOCK(udc_stall_spinlock); /* stall spin lock */ | 387 | static DEFINE_SPINLOCK(udc_stall_spinlock); /* stall spin lock */ |
387 | struct pch_udc_dev *pch_udc; /* pointer to device object */ | ||
388 | static bool speed_fs; | 388 | static bool speed_fs; |
389 | module_param_named(speed_fs, speed_fs, bool, S_IRUGO); | 389 | module_param_named(speed_fs, speed_fs, bool, S_IRUGO); |
390 | MODULE_PARM_DESC(speed_fs, "true for Full speed operation"); | 390 | MODULE_PARM_DESC(speed_fs, "true for Full speed operation"); |
@@ -1235,9 +1235,10 @@ static int pch_udc_pcd_vbus_draw(struct usb_gadget *gadget, unsigned int mA) | |||
1235 | return -EOPNOTSUPP; | 1235 | return -EOPNOTSUPP; |
1236 | } | 1236 | } |
1237 | 1237 | ||
1238 | static int pch_udc_start(struct usb_gadget_driver *driver, | 1238 | static int pch_udc_start(struct usb_gadget *g, |
1239 | int (*bind)(struct usb_gadget *, struct usb_gadget_driver *)); | 1239 | struct usb_gadget_driver *driver); |
1240 | static int pch_udc_stop(struct usb_gadget_driver *driver); | 1240 | static int pch_udc_stop(struct usb_gadget *g, |
1241 | struct usb_gadget_driver *driver); | ||
1241 | static const struct usb_gadget_ops pch_udc_ops = { | 1242 | static const struct usb_gadget_ops pch_udc_ops = { |
1242 | .get_frame = pch_udc_pcd_get_frame, | 1243 | .get_frame = pch_udc_pcd_get_frame, |
1243 | .wakeup = pch_udc_pcd_wakeup, | 1244 | .wakeup = pch_udc_pcd_wakeup, |
@@ -1245,8 +1246,8 @@ static const struct usb_gadget_ops pch_udc_ops = { | |||
1245 | .pullup = pch_udc_pcd_pullup, | 1246 | .pullup = pch_udc_pcd_pullup, |
1246 | .vbus_session = pch_udc_pcd_vbus_session, | 1247 | .vbus_session = pch_udc_pcd_vbus_session, |
1247 | .vbus_draw = pch_udc_pcd_vbus_draw, | 1248 | .vbus_draw = pch_udc_pcd_vbus_draw, |
1248 | .start = pch_udc_start, | 1249 | .udc_start = pch_udc_start, |
1249 | .stop = pch_udc_stop, | 1250 | .udc_stop = pch_udc_stop, |
1250 | }; | 1251 | }; |
1251 | 1252 | ||
1252 | /** | 1253 | /** |
@@ -2981,40 +2982,15 @@ static int init_dma_pools(struct pch_udc_dev *dev) | |||
2981 | return 0; | 2982 | return 0; |
2982 | } | 2983 | } |
2983 | 2984 | ||
2984 | static int pch_udc_start(struct usb_gadget_driver *driver, | 2985 | static int pch_udc_start(struct usb_gadget *g, |
2985 | int (*bind)(struct usb_gadget *, struct usb_gadget_driver *)) | 2986 | struct usb_gadget_driver *driver) |
2986 | { | 2987 | { |
2987 | struct pch_udc_dev *dev = pch_udc; | 2988 | struct pch_udc_dev *dev = to_pch_udc(g); |
2988 | int retval; | ||
2989 | |||
2990 | if (!driver || (driver->max_speed == USB_SPEED_UNKNOWN) || !bind || | ||
2991 | !driver->setup || !driver->unbind || !driver->disconnect) { | ||
2992 | dev_err(&dev->pdev->dev, | ||
2993 | "%s: invalid driver parameter\n", __func__); | ||
2994 | return -EINVAL; | ||
2995 | } | ||
2996 | 2989 | ||
2997 | if (!dev) | ||
2998 | return -ENODEV; | ||
2999 | |||
3000 | if (dev->driver) { | ||
3001 | dev_err(&dev->pdev->dev, "%s: already bound\n", __func__); | ||
3002 | return -EBUSY; | ||
3003 | } | ||
3004 | driver->driver.bus = NULL; | 2990 | driver->driver.bus = NULL; |
3005 | dev->driver = driver; | 2991 | dev->driver = driver; |
3006 | dev->gadget.dev.driver = &driver->driver; | 2992 | dev->gadget.dev.driver = &driver->driver; |
3007 | 2993 | ||
3008 | /* Invoke the bind routine of the gadget driver */ | ||
3009 | retval = bind(&dev->gadget, driver); | ||
3010 | |||
3011 | if (retval) { | ||
3012 | dev_err(&dev->pdev->dev, "%s: binding to %s returning %d\n", | ||
3013 | __func__, driver->driver.name, retval); | ||
3014 | dev->driver = NULL; | ||
3015 | dev->gadget.dev.driver = NULL; | ||
3016 | return retval; | ||
3017 | } | ||
3018 | /* get ready for ep0 traffic */ | 2994 | /* get ready for ep0 traffic */ |
3019 | pch_udc_setup_ep0(dev); | 2995 | pch_udc_setup_ep0(dev); |
3020 | 2996 | ||
@@ -3026,30 +3002,21 @@ static int pch_udc_start(struct usb_gadget_driver *driver, | |||
3026 | return 0; | 3002 | return 0; |
3027 | } | 3003 | } |
3028 | 3004 | ||
3029 | static int pch_udc_stop(struct usb_gadget_driver *driver) | 3005 | static int pch_udc_stop(struct usb_gadget *g, |
3006 | struct usb_gadget_driver *driver) | ||
3030 | { | 3007 | { |
3031 | struct pch_udc_dev *dev = pch_udc; | 3008 | struct pch_udc_dev *dev = to_pch_udc(g); |
3032 | |||
3033 | if (!dev) | ||
3034 | return -ENODEV; | ||
3035 | |||
3036 | if (!driver || (driver != dev->driver)) { | ||
3037 | dev_err(&dev->pdev->dev, | ||
3038 | "%s: invalid driver parameter\n", __func__); | ||
3039 | return -EINVAL; | ||
3040 | } | ||
3041 | 3009 | ||
3042 | pch_udc_disable_interrupts(dev, UDC_DEVINT_MSK); | 3010 | pch_udc_disable_interrupts(dev, UDC_DEVINT_MSK); |
3043 | 3011 | ||
3044 | /* Assures that there are no pending requests with this driver */ | 3012 | /* Assures that there are no pending requests with this driver */ |
3045 | driver->disconnect(&dev->gadget); | ||
3046 | driver->unbind(&dev->gadget); | ||
3047 | dev->gadget.dev.driver = NULL; | 3013 | dev->gadget.dev.driver = NULL; |
3048 | dev->driver = NULL; | 3014 | dev->driver = NULL; |
3049 | dev->connected = 0; | 3015 | dev->connected = 0; |
3050 | 3016 | ||
3051 | /* set SD */ | 3017 | /* set SD */ |
3052 | pch_udc_set_disconnect(dev); | 3018 | pch_udc_set_disconnect(dev); |
3019 | |||
3053 | return 0; | 3020 | return 0; |
3054 | } | 3021 | } |
3055 | 3022 | ||
@@ -3164,11 +3131,6 @@ static int pch_udc_probe(struct pci_dev *pdev, | |||
3164 | int retval; | 3131 | int retval; |
3165 | struct pch_udc_dev *dev; | 3132 | struct pch_udc_dev *dev; |
3166 | 3133 | ||
3167 | /* one udc only */ | ||
3168 | if (pch_udc) { | ||
3169 | pr_err("%s: already probed\n", __func__); | ||
3170 | return -EBUSY; | ||
3171 | } | ||
3172 | /* init */ | 3134 | /* init */ |
3173 | dev = kzalloc(sizeof *dev, GFP_KERNEL); | 3135 | dev = kzalloc(sizeof *dev, GFP_KERNEL); |
3174 | if (!dev) { | 3136 | if (!dev) { |
@@ -3207,7 +3169,6 @@ static int pch_udc_probe(struct pci_dev *pdev, | |||
3207 | retval = -ENODEV; | 3169 | retval = -ENODEV; |
3208 | goto finished; | 3170 | goto finished; |
3209 | } | 3171 | } |
3210 | pch_udc = dev; | ||
3211 | /* initialize the hardware */ | 3172 | /* initialize the hardware */ |
3212 | if (pch_udc_pcd_init(dev)) { | 3173 | if (pch_udc_pcd_init(dev)) { |
3213 | retval = -ENODEV; | 3174 | retval = -ENODEV; |