diff options
author | JiebingLi <jiebing.li@intel.com> | 2010-08-05 09:18:29 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2010-10-22 13:21:19 -0400 |
commit | 912c93d1606f60932de3e2f31db3722a9f069ed9 (patch) | |
tree | 24f25c940fcdce6f9d889241397881c970977274 /drivers/usb/gadget/langwell_udc.c | |
parent | 3211cbc20b406799423385cf62e1f1879b1ca8cc (diff) |
USB: langwell: USB Client driver memory handling
SRAM Memory handling for USB client function
Signed-off-by: JiebingLi <jiebing.li@intel.com>
Signed-off-by: Alan Cox <alan@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb/gadget/langwell_udc.c')
-rw-r--r-- | drivers/usb/gadget/langwell_udc.c | 113 |
1 files changed, 108 insertions, 5 deletions
diff --git a/drivers/usb/gadget/langwell_udc.c b/drivers/usb/gadget/langwell_udc.c index 4b134abb1dbe..ccc9c070a30d 100644 --- a/drivers/usb/gadget/langwell_udc.c +++ b/drivers/usb/gadget/langwell_udc.c | |||
@@ -2988,6 +2988,50 @@ static void gadget_release(struct device *_dev) | |||
2988 | } | 2988 | } |
2989 | 2989 | ||
2990 | 2990 | ||
2991 | /* enable SRAM caching if SRAM detected */ | ||
2992 | static void sram_init(struct langwell_udc *dev) | ||
2993 | { | ||
2994 | struct pci_dev *pdev = dev->pdev; | ||
2995 | |||
2996 | dev_dbg(&dev->pdev->dev, "---> %s()\n", __func__); | ||
2997 | |||
2998 | dev->sram_addr = pci_resource_start(pdev, 1); | ||
2999 | dev->sram_size = pci_resource_len(pdev, 1); | ||
3000 | dev_info(&dev->pdev->dev, "Found private SRAM at %x size:%x\n", | ||
3001 | dev->sram_addr, dev->sram_size); | ||
3002 | dev->got_sram = 1; | ||
3003 | |||
3004 | if (pci_request_region(pdev, 1, kobject_name(&pdev->dev.kobj))) { | ||
3005 | dev_warn(&dev->pdev->dev, "SRAM request failed\n"); | ||
3006 | dev->got_sram = 0; | ||
3007 | } else if (!dma_declare_coherent_memory(&pdev->dev, dev->sram_addr, | ||
3008 | dev->sram_addr, dev->sram_size, DMA_MEMORY_MAP)) { | ||
3009 | dev_warn(&dev->pdev->dev, "SRAM DMA declare failed\n"); | ||
3010 | pci_release_region(pdev, 1); | ||
3011 | dev->got_sram = 0; | ||
3012 | } | ||
3013 | |||
3014 | dev_dbg(&dev->pdev->dev, "<--- %s()\n", __func__); | ||
3015 | } | ||
3016 | |||
3017 | |||
3018 | /* release SRAM caching */ | ||
3019 | static void sram_deinit(struct langwell_udc *dev) | ||
3020 | { | ||
3021 | struct pci_dev *pdev = dev->pdev; | ||
3022 | |||
3023 | dev_dbg(&dev->pdev->dev, "---> %s()\n", __func__); | ||
3024 | |||
3025 | dma_release_declared_memory(&pdev->dev); | ||
3026 | pci_release_region(pdev, 1); | ||
3027 | |||
3028 | dev->got_sram = 0; | ||
3029 | |||
3030 | dev_info(&dev->pdev->dev, "release SRAM caching\n"); | ||
3031 | dev_dbg(&dev->pdev->dev, "<--- %s()\n", __func__); | ||
3032 | } | ||
3033 | |||
3034 | |||
2991 | /* tear down the binding between this driver and the pci device */ | 3035 | /* tear down the binding between this driver and the pci device */ |
2992 | static void langwell_udc_remove(struct pci_dev *pdev) | 3036 | static void langwell_udc_remove(struct pci_dev *pdev) |
2993 | { | 3037 | { |
@@ -3000,19 +3044,25 @@ static void langwell_udc_remove(struct pci_dev *pdev) | |||
3000 | 3044 | ||
3001 | dev->done = &done; | 3045 | dev->done = &done; |
3002 | 3046 | ||
3003 | /* free memory allocated in probe */ | 3047 | #ifndef OTG_TRANSCEIVER |
3048 | /* free dTD dma_pool and dQH */ | ||
3004 | if (dev->dtd_pool) | 3049 | if (dev->dtd_pool) |
3005 | dma_pool_destroy(dev->dtd_pool); | 3050 | dma_pool_destroy(dev->dtd_pool); |
3006 | 3051 | ||
3052 | if (dev->ep_dqh) | ||
3053 | dma_free_coherent(&pdev->dev, dev->ep_dqh_size, | ||
3054 | dev->ep_dqh, dev->ep_dqh_dma); | ||
3055 | |||
3056 | /* release SRAM caching */ | ||
3057 | if (dev->has_sram && dev->got_sram) | ||
3058 | sram_deinit(dev); | ||
3059 | #endif | ||
3060 | |||
3007 | if (dev->status_req) { | 3061 | if (dev->status_req) { |
3008 | kfree(dev->status_req->req.buf); | 3062 | kfree(dev->status_req->req.buf); |
3009 | kfree(dev->status_req); | 3063 | kfree(dev->status_req); |
3010 | } | 3064 | } |
3011 | 3065 | ||
3012 | if (dev->ep_dqh) | ||
3013 | dma_free_coherent(&pdev->dev, dev->ep_dqh_size, | ||
3014 | dev->ep_dqh, dev->ep_dqh_dma); | ||
3015 | |||
3016 | kfree(dev->ep); | 3066 | kfree(dev->ep); |
3017 | 3067 | ||
3018 | /* diable IRQ handler */ | 3068 | /* diable IRQ handler */ |
@@ -3140,7 +3190,15 @@ static int langwell_udc_probe(struct pci_dev *pdev, | |||
3140 | goto error; | 3190 | goto error; |
3141 | } | 3191 | } |
3142 | 3192 | ||
3193 | dev->has_sram = 1; | ||
3194 | dev->got_sram = 0; | ||
3195 | dev_vdbg(&dev->pdev->dev, "dev->has_sram: %d\n", dev->has_sram); | ||
3196 | |||
3143 | #ifndef OTG_TRANSCEIVER | 3197 | #ifndef OTG_TRANSCEIVER |
3198 | /* enable SRAM caching if detected */ | ||
3199 | if (dev->has_sram && !dev->got_sram) | ||
3200 | sram_init(dev); | ||
3201 | |||
3144 | dev_info(&dev->pdev->dev, | 3202 | dev_info(&dev->pdev->dev, |
3145 | "irq %d, io mem: 0x%08lx, len: 0x%08lx, pci mem 0x%p\n", | 3203 | "irq %d, io mem: 0x%08lx, len: 0x%08lx, pci mem 0x%p\n", |
3146 | pdev->irq, resource, len, base); | 3204 | pdev->irq, resource, len, base); |
@@ -3335,6 +3393,18 @@ static int langwell_udc_suspend(struct pci_dev *pdev, pm_message_t state) | |||
3335 | /* save PCI state */ | 3393 | /* save PCI state */ |
3336 | pci_save_state(pdev); | 3394 | pci_save_state(pdev); |
3337 | 3395 | ||
3396 | /* free dTD dma_pool and dQH */ | ||
3397 | if (dev->dtd_pool) | ||
3398 | dma_pool_destroy(dev->dtd_pool); | ||
3399 | |||
3400 | if (dev->ep_dqh) | ||
3401 | dma_free_coherent(&pdev->dev, dev->ep_dqh_size, | ||
3402 | dev->ep_dqh, dev->ep_dqh_dma); | ||
3403 | |||
3404 | /* release SRAM caching */ | ||
3405 | if (dev->has_sram && dev->got_sram) | ||
3406 | sram_deinit(dev); | ||
3407 | |||
3338 | /* set device power state */ | 3408 | /* set device power state */ |
3339 | pci_set_power_state(pdev, PCI_D3hot); | 3409 | pci_set_power_state(pdev, PCI_D3hot); |
3340 | 3410 | ||
@@ -3351,6 +3421,7 @@ static int langwell_udc_suspend(struct pci_dev *pdev, pm_message_t state) | |||
3351 | static int langwell_udc_resume(struct pci_dev *pdev) | 3421 | static int langwell_udc_resume(struct pci_dev *pdev) |
3352 | { | 3422 | { |
3353 | struct langwell_udc *dev = the_controller; | 3423 | struct langwell_udc *dev = the_controller; |
3424 | size_t size; | ||
3354 | 3425 | ||
3355 | dev_dbg(&dev->pdev->dev, "---> %s()\n", __func__); | 3426 | dev_dbg(&dev->pdev->dev, "---> %s()\n", __func__); |
3356 | 3427 | ||
@@ -3361,6 +3432,38 @@ static int langwell_udc_resume(struct pci_dev *pdev) | |||
3361 | /* set device D0 power state */ | 3432 | /* set device D0 power state */ |
3362 | pci_set_power_state(pdev, PCI_D0); | 3433 | pci_set_power_state(pdev, PCI_D0); |
3363 | 3434 | ||
3435 | /* enable SRAM caching if detected */ | ||
3436 | if (dev->has_sram && !dev->got_sram) | ||
3437 | sram_init(dev); | ||
3438 | |||
3439 | /* allocate device dQH memory */ | ||
3440 | size = dev->ep_max * sizeof(struct langwell_dqh); | ||
3441 | dev_vdbg(&dev->pdev->dev, "orig size = %d\n", size); | ||
3442 | if (size < DQH_ALIGNMENT) | ||
3443 | size = DQH_ALIGNMENT; | ||
3444 | else if ((size % DQH_ALIGNMENT) != 0) { | ||
3445 | size += DQH_ALIGNMENT + 1; | ||
3446 | size &= ~(DQH_ALIGNMENT - 1); | ||
3447 | } | ||
3448 | dev->ep_dqh = dma_alloc_coherent(&pdev->dev, size, | ||
3449 | &dev->ep_dqh_dma, GFP_KERNEL); | ||
3450 | if (!dev->ep_dqh) { | ||
3451 | dev_err(&dev->pdev->dev, "allocate dQH memory failed\n"); | ||
3452 | return -ENOMEM; | ||
3453 | } | ||
3454 | dev->ep_dqh_size = size; | ||
3455 | dev_vdbg(&dev->pdev->dev, "ep_dqh_size = %d\n", dev->ep_dqh_size); | ||
3456 | |||
3457 | /* create dTD dma_pool resource */ | ||
3458 | dev->dtd_pool = dma_pool_create("langwell_dtd", | ||
3459 | &dev->pdev->dev, | ||
3460 | sizeof(struct langwell_dtd), | ||
3461 | DTD_ALIGNMENT, | ||
3462 | DMA_BOUNDARY); | ||
3463 | |||
3464 | if (!dev->dtd_pool) | ||
3465 | return -ENOMEM; | ||
3466 | |||
3364 | /* restore PCI state */ | 3467 | /* restore PCI state */ |
3365 | pci_restore_state(pdev); | 3468 | pci_restore_state(pdev); |
3366 | 3469 | ||