diff options
-rw-r--r-- | drivers/usb/gadget/fsl_usb2_udc.c | 59 | ||||
-rw-r--r-- | drivers/usb/gadget/fsl_usb2_udc.h | 4 |
2 files changed, 38 insertions, 25 deletions
diff --git a/drivers/usb/gadget/fsl_usb2_udc.c b/drivers/usb/gadget/fsl_usb2_udc.c index 5ea32c30878d..e4aa29fc2939 100644 --- a/drivers/usb/gadget/fsl_usb2_udc.c +++ b/drivers/usb/gadget/fsl_usb2_udc.c | |||
@@ -2189,27 +2189,19 @@ static void fsl_udc_release(struct device *dev) | |||
2189 | * init resource for globle controller | 2189 | * init resource for globle controller |
2190 | * Return the udc handle on success or NULL on failure | 2190 | * Return the udc handle on success or NULL on failure |
2191 | ------------------------------------------------------------------*/ | 2191 | ------------------------------------------------------------------*/ |
2192 | static struct fsl_udc *__init struct_udc_setup(struct platform_device *pdev) | 2192 | static int __init struct_udc_setup(struct fsl_udc *udc, |
2193 | struct platform_device *pdev) | ||
2193 | { | 2194 | { |
2194 | struct fsl_udc *udc; | ||
2195 | struct fsl_usb2_platform_data *pdata; | 2195 | struct fsl_usb2_platform_data *pdata; |
2196 | size_t size; | 2196 | size_t size; |
2197 | 2197 | ||
2198 | udc = kzalloc(sizeof(struct fsl_udc), GFP_KERNEL); | ||
2199 | if (udc == NULL) { | ||
2200 | ERR("malloc udc failed\n"); | ||
2201 | return NULL; | ||
2202 | } | ||
2203 | |||
2204 | pdata = pdev->dev.platform_data; | 2198 | pdata = pdev->dev.platform_data; |
2205 | udc->phy_mode = pdata->phy_mode; | 2199 | udc->phy_mode = pdata->phy_mode; |
2206 | /* max_ep_nr is bidirectional ep number, max_ep doubles the number */ | ||
2207 | udc->max_ep = pdata->max_ep_nr * 2; | ||
2208 | 2200 | ||
2209 | udc->eps = kzalloc(sizeof(struct fsl_ep) * udc->max_ep, GFP_KERNEL); | 2201 | udc->eps = kzalloc(sizeof(struct fsl_ep) * udc->max_ep, GFP_KERNEL); |
2210 | if (!udc->eps) { | 2202 | if (!udc->eps) { |
2211 | ERR("malloc fsl_ep failed\n"); | 2203 | ERR("malloc fsl_ep failed\n"); |
2212 | goto cleanup; | 2204 | return -1; |
2213 | } | 2205 | } |
2214 | 2206 | ||
2215 | /* initialized QHs, take care of alignment */ | 2207 | /* initialized QHs, take care of alignment */ |
@@ -2225,7 +2217,7 @@ static struct fsl_udc *__init struct_udc_setup(struct platform_device *pdev) | |||
2225 | if (!udc->ep_qh) { | 2217 | if (!udc->ep_qh) { |
2226 | ERR("malloc QHs for udc failed\n"); | 2218 | ERR("malloc QHs for udc failed\n"); |
2227 | kfree(udc->eps); | 2219 | kfree(udc->eps); |
2228 | goto cleanup; | 2220 | return -1; |
2229 | } | 2221 | } |
2230 | 2222 | ||
2231 | udc->ep_qh_size = size; | 2223 | udc->ep_qh_size = size; |
@@ -2244,11 +2236,7 @@ static struct fsl_udc *__init struct_udc_setup(struct platform_device *pdev) | |||
2244 | udc->remote_wakeup = 0; /* default to 0 on reset */ | 2236 | udc->remote_wakeup = 0; /* default to 0 on reset */ |
2245 | spin_lock_init(&udc->lock); | 2237 | spin_lock_init(&udc->lock); |
2246 | 2238 | ||
2247 | return udc; | 2239 | return 0; |
2248 | |||
2249 | cleanup: | ||
2250 | kfree(udc); | ||
2251 | return NULL; | ||
2252 | } | 2240 | } |
2253 | 2241 | ||
2254 | /*---------------------------------------------------------------- | 2242 | /*---------------------------------------------------------------- |
@@ -2287,35 +2275,37 @@ static int __init struct_ep_setup(struct fsl_udc *udc, unsigned char index, | |||
2287 | } | 2275 | } |
2288 | 2276 | ||
2289 | /* Driver probe function | 2277 | /* Driver probe function |
2290 | * all intialize operations implemented here except enabling usb_intr reg | 2278 | * all intialization operations implemented here except enabling usb_intr reg |
2279 | * board setup should have been done in the platform code | ||
2291 | */ | 2280 | */ |
2292 | static int __init fsl_udc_probe(struct platform_device *pdev) | 2281 | static int __init fsl_udc_probe(struct platform_device *pdev) |
2293 | { | 2282 | { |
2294 | struct resource *res; | 2283 | struct resource *res; |
2295 | int ret = -ENODEV; | 2284 | int ret = -ENODEV; |
2296 | unsigned int i; | 2285 | unsigned int i; |
2286 | u32 dccparams; | ||
2297 | 2287 | ||
2298 | if (strcmp(pdev->name, driver_name)) { | 2288 | if (strcmp(pdev->name, driver_name)) { |
2299 | VDBG("Wrong device\n"); | 2289 | VDBG("Wrong device\n"); |
2300 | return -ENODEV; | 2290 | return -ENODEV; |
2301 | } | 2291 | } |
2302 | 2292 | ||
2303 | /* board setup should have been done in the platform code */ | 2293 | udc_controller = kzalloc(sizeof(struct fsl_udc), GFP_KERNEL); |
2304 | 2294 | if (udc_controller == NULL) { | |
2305 | /* Initialize the udc structure including QH member and other member */ | 2295 | ERR("malloc udc failed\n"); |
2306 | udc_controller = struct_udc_setup(pdev); | ||
2307 | if (!udc_controller) { | ||
2308 | VDBG("udc_controller is NULL \n"); | ||
2309 | return -ENOMEM; | 2296 | return -ENOMEM; |
2310 | } | 2297 | } |
2311 | 2298 | ||
2312 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 2299 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
2313 | if (!res) | 2300 | if (!res) { |
2301 | kfree(udc_controller); | ||
2314 | return -ENXIO; | 2302 | return -ENXIO; |
2303 | } | ||
2315 | 2304 | ||
2316 | if (!request_mem_region(res->start, res->end - res->start + 1, | 2305 | if (!request_mem_region(res->start, res->end - res->start + 1, |
2317 | driver_name)) { | 2306 | driver_name)) { |
2318 | ERR("request mem region for %s failed \n", pdev->name); | 2307 | ERR("request mem region for %s failed \n", pdev->name); |
2308 | kfree(udc_controller); | ||
2319 | return -EBUSY; | 2309 | return -EBUSY; |
2320 | } | 2310 | } |
2321 | 2311 | ||
@@ -2328,6 +2318,17 @@ static int __init fsl_udc_probe(struct platform_device *pdev) | |||
2328 | usb_sys_regs = (struct usb_sys_interface *) | 2318 | usb_sys_regs = (struct usb_sys_interface *) |
2329 | ((u32)dr_regs + USB_DR_SYS_OFFSET); | 2319 | ((u32)dr_regs + USB_DR_SYS_OFFSET); |
2330 | 2320 | ||
2321 | /* Read Device Controller Capability Parameters register */ | ||
2322 | dccparams = fsl_readl(&dr_regs->dccparams); | ||
2323 | if (!(dccparams & DCCPARAMS_DC)) { | ||
2324 | ERR("This SOC doesn't support device role\n"); | ||
2325 | ret = -ENODEV; | ||
2326 | goto err2; | ||
2327 | } | ||
2328 | /* Get max device endpoints */ | ||
2329 | /* DEN is bidirectional ep number, max_ep doubles the number */ | ||
2330 | udc_controller->max_ep = (dccparams & DCCPARAMS_DEN_MASK) * 2; | ||
2331 | |||
2331 | udc_controller->irq = platform_get_irq(pdev, 0); | 2332 | udc_controller->irq = platform_get_irq(pdev, 0); |
2332 | if (!udc_controller->irq) { | 2333 | if (!udc_controller->irq) { |
2333 | ret = -ENODEV; | 2334 | ret = -ENODEV; |
@@ -2342,6 +2343,13 @@ static int __init fsl_udc_probe(struct platform_device *pdev) | |||
2342 | goto err2; | 2343 | goto err2; |
2343 | } | 2344 | } |
2344 | 2345 | ||
2346 | /* Initialize the udc structure including QH member and other member */ | ||
2347 | if (struct_udc_setup(udc_controller, pdev)) { | ||
2348 | ERR("Can't initialize udc data structure\n"); | ||
2349 | ret = -ENOMEM; | ||
2350 | goto err3; | ||
2351 | } | ||
2352 | |||
2345 | /* initialize usb hw reg except for regs for EP, | 2353 | /* initialize usb hw reg except for regs for EP, |
2346 | * leave usbintr reg untouched */ | 2354 | * leave usbintr reg untouched */ |
2347 | dr_controller_setup(udc_controller); | 2355 | dr_controller_setup(udc_controller); |
@@ -2403,6 +2411,7 @@ err2: | |||
2403 | iounmap(dr_regs); | 2411 | iounmap(dr_regs); |
2404 | err1: | 2412 | err1: |
2405 | release_mem_region(res->start, res->end - res->start + 1); | 2413 | release_mem_region(res->start, res->end - res->start + 1); |
2414 | kfree(udc_controller); | ||
2406 | return ret; | 2415 | return ret; |
2407 | } | 2416 | } |
2408 | 2417 | ||
diff --git a/drivers/usb/gadget/fsl_usb2_udc.h b/drivers/usb/gadget/fsl_usb2_udc.h index c6291e046507..832ab82b4882 100644 --- a/drivers/usb/gadget/fsl_usb2_udc.h +++ b/drivers/usb/gadget/fsl_usb2_udc.h | |||
@@ -101,6 +101,10 @@ struct usb_sys_interface { | |||
101 | #define WAIT_FOR_OUT_STATUS 3 | 101 | #define WAIT_FOR_OUT_STATUS 3 |
102 | #define DATA_STATE_RECV 4 | 102 | #define DATA_STATE_RECV 4 |
103 | 103 | ||
104 | /* Device Controller Capability Parameter register */ | ||
105 | #define DCCPARAMS_DC 0x00000080 | ||
106 | #define DCCPARAMS_DEN_MASK 0x0000001f | ||
107 | |||
104 | /* Frame Index Register Bit Masks */ | 108 | /* Frame Index Register Bit Masks */ |
105 | #define USB_FRINDEX_MASKS 0x3fff | 109 | #define USB_FRINDEX_MASKS 0x3fff |
106 | /* USB CMD Register Bit Masks */ | 110 | /* USB CMD Register Bit Masks */ |