Commit 912c93d1 authored by JiebingLi's avatar JiebingLi Committed by Greg Kroah-Hartman

USB: langwell: USB Client driver memory handling

SRAM Memory handling for USB client function
Signed-off-by: default avatarJiebingLi <jiebing.li@intel.com>
Signed-off-by: default avatarAlan Cox <alan@linux.intel.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent 3211cbc2
...@@ -2988,6 +2988,50 @@ static void gadget_release(struct device *_dev) ...@@ -2988,6 +2988,50 @@ static void gadget_release(struct device *_dev)
} }
/* enable SRAM caching if SRAM detected */
static void sram_init(struct langwell_udc *dev)
{
struct pci_dev *pdev = dev->pdev;
dev_dbg(&dev->pdev->dev, "---> %s()\n", __func__);
dev->sram_addr = pci_resource_start(pdev, 1);
dev->sram_size = pci_resource_len(pdev, 1);
dev_info(&dev->pdev->dev, "Found private SRAM at %x size:%x\n",
dev->sram_addr, dev->sram_size);
dev->got_sram = 1;
if (pci_request_region(pdev, 1, kobject_name(&pdev->dev.kobj))) {
dev_warn(&dev->pdev->dev, "SRAM request failed\n");
dev->got_sram = 0;
} else if (!dma_declare_coherent_memory(&pdev->dev, dev->sram_addr,
dev->sram_addr, dev->sram_size, DMA_MEMORY_MAP)) {
dev_warn(&dev->pdev->dev, "SRAM DMA declare failed\n");
pci_release_region(pdev, 1);
dev->got_sram = 0;
}
dev_dbg(&dev->pdev->dev, "<--- %s()\n", __func__);
}
/* release SRAM caching */
static void sram_deinit(struct langwell_udc *dev)
{
struct pci_dev *pdev = dev->pdev;
dev_dbg(&dev->pdev->dev, "---> %s()\n", __func__);
dma_release_declared_memory(&pdev->dev);
pci_release_region(pdev, 1);
dev->got_sram = 0;
dev_info(&dev->pdev->dev, "release SRAM caching\n");
dev_dbg(&dev->pdev->dev, "<--- %s()\n", __func__);
}
/* tear down the binding between this driver and the pci device */ /* tear down the binding between this driver and the pci device */
static void langwell_udc_remove(struct pci_dev *pdev) static void langwell_udc_remove(struct pci_dev *pdev)
{ {
...@@ -3000,19 +3044,25 @@ static void langwell_udc_remove(struct pci_dev *pdev) ...@@ -3000,19 +3044,25 @@ static void langwell_udc_remove(struct pci_dev *pdev)
dev->done = &done; dev->done = &done;
/* free memory allocated in probe */ #ifndef OTG_TRANSCEIVER
/* free dTD dma_pool and dQH */
if (dev->dtd_pool) if (dev->dtd_pool)
dma_pool_destroy(dev->dtd_pool); dma_pool_destroy(dev->dtd_pool);
if (dev->ep_dqh)
dma_free_coherent(&pdev->dev, dev->ep_dqh_size,
dev->ep_dqh, dev->ep_dqh_dma);
/* release SRAM caching */
if (dev->has_sram && dev->got_sram)
sram_deinit(dev);
#endif
if (dev->status_req) { if (dev->status_req) {
kfree(dev->status_req->req.buf); kfree(dev->status_req->req.buf);
kfree(dev->status_req); kfree(dev->status_req);
} }
if (dev->ep_dqh)
dma_free_coherent(&pdev->dev, dev->ep_dqh_size,
dev->ep_dqh, dev->ep_dqh_dma);
kfree(dev->ep); kfree(dev->ep);
/* diable IRQ handler */ /* diable IRQ handler */
...@@ -3140,7 +3190,15 @@ static int langwell_udc_probe(struct pci_dev *pdev, ...@@ -3140,7 +3190,15 @@ static int langwell_udc_probe(struct pci_dev *pdev,
goto error; goto error;
} }
dev->has_sram = 1;
dev->got_sram = 0;
dev_vdbg(&dev->pdev->dev, "dev->has_sram: %d\n", dev->has_sram);
#ifndef OTG_TRANSCEIVER #ifndef OTG_TRANSCEIVER
/* enable SRAM caching if detected */
if (dev->has_sram && !dev->got_sram)
sram_init(dev);
dev_info(&dev->pdev->dev, dev_info(&dev->pdev->dev,
"irq %d, io mem: 0x%08lx, len: 0x%08lx, pci mem 0x%p\n", "irq %d, io mem: 0x%08lx, len: 0x%08lx, pci mem 0x%p\n",
pdev->irq, resource, len, base); pdev->irq, resource, len, base);
...@@ -3335,6 +3393,18 @@ static int langwell_udc_suspend(struct pci_dev *pdev, pm_message_t state) ...@@ -3335,6 +3393,18 @@ static int langwell_udc_suspend(struct pci_dev *pdev, pm_message_t state)
/* save PCI state */ /* save PCI state */
pci_save_state(pdev); pci_save_state(pdev);
/* free dTD dma_pool and dQH */
if (dev->dtd_pool)
dma_pool_destroy(dev->dtd_pool);
if (dev->ep_dqh)
dma_free_coherent(&pdev->dev, dev->ep_dqh_size,
dev->ep_dqh, dev->ep_dqh_dma);
/* release SRAM caching */
if (dev->has_sram && dev->got_sram)
sram_deinit(dev);
/* set device power state */ /* set device power state */
pci_set_power_state(pdev, PCI_D3hot); pci_set_power_state(pdev, PCI_D3hot);
...@@ -3351,6 +3421,7 @@ static int langwell_udc_suspend(struct pci_dev *pdev, pm_message_t state) ...@@ -3351,6 +3421,7 @@ static int langwell_udc_suspend(struct pci_dev *pdev, pm_message_t state)
static int langwell_udc_resume(struct pci_dev *pdev) static int langwell_udc_resume(struct pci_dev *pdev)
{ {
struct langwell_udc *dev = the_controller; struct langwell_udc *dev = the_controller;
size_t size;
dev_dbg(&dev->pdev->dev, "---> %s()\n", __func__); dev_dbg(&dev->pdev->dev, "---> %s()\n", __func__);
...@@ -3361,6 +3432,38 @@ static int langwell_udc_resume(struct pci_dev *pdev) ...@@ -3361,6 +3432,38 @@ static int langwell_udc_resume(struct pci_dev *pdev)
/* set device D0 power state */ /* set device D0 power state */
pci_set_power_state(pdev, PCI_D0); pci_set_power_state(pdev, PCI_D0);
/* enable SRAM caching if detected */
if (dev->has_sram && !dev->got_sram)
sram_init(dev);
/* allocate device dQH memory */
size = dev->ep_max * sizeof(struct langwell_dqh);
dev_vdbg(&dev->pdev->dev, "orig size = %d\n", size);
if (size < DQH_ALIGNMENT)
size = DQH_ALIGNMENT;
else if ((size % DQH_ALIGNMENT) != 0) {
size += DQH_ALIGNMENT + 1;
size &= ~(DQH_ALIGNMENT - 1);
}
dev->ep_dqh = dma_alloc_coherent(&pdev->dev, size,
&dev->ep_dqh_dma, GFP_KERNEL);
if (!dev->ep_dqh) {
dev_err(&dev->pdev->dev, "allocate dQH memory failed\n");
return -ENOMEM;
}
dev->ep_dqh_size = size;
dev_vdbg(&dev->pdev->dev, "ep_dqh_size = %d\n", dev->ep_dqh_size);
/* create dTD dma_pool resource */
dev->dtd_pool = dma_pool_create("langwell_dtd",
&dev->pdev->dev,
sizeof(struct langwell_dtd),
DTD_ALIGNMENT,
DMA_BOUNDARY);
if (!dev->dtd_pool)
return -ENOMEM;
/* restore PCI state */ /* restore PCI state */
pci_restore_state(pdev); pci_restore_state(pdev);
......
...@@ -18,11 +18,7 @@ ...@@ -18,11 +18,7 @@
*/ */
#include <linux/usb/langwell_udc.h> #include <linux/usb/langwell_udc.h>
#if defined(CONFIG_USB_LANGWELL_OTG)
#include <linux/usb/langwell_otg.h> #include <linux/usb/langwell_otg.h>
#endif
/*-------------------------------------------------------------------------*/ /*-------------------------------------------------------------------------*/
...@@ -199,7 +195,9 @@ struct langwell_udc { ...@@ -199,7 +195,9 @@ struct langwell_udc {
vbus_active:1, vbus_active:1,
suspended:1, suspended:1,
stopped:1, stopped:1,
lpm:1; /* LPM capability */ lpm:1, /* LPM capability */
has_sram:1, /* SRAM caching */
got_sram:1;
/* pci state used to access those endpoints */ /* pci state used to access those endpoints */
struct pci_dev *pdev; struct pci_dev *pdev;
...@@ -225,6 +223,10 @@ struct langwell_udc { ...@@ -225,6 +223,10 @@ struct langwell_udc {
/* make sure release() is done */ /* make sure release() is done */
struct completion *done; struct completion *done;
/* for private SRAM caching */
unsigned int sram_addr;
unsigned int sram_size;
/* device status data for get_status request */ /* device status data for get_status request */
u16 dev_status; u16 dev_status;
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment