[PATCH 15/25] langwell: USB Client driver memory handling

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: JiebingLi <jiebing.li@xxxxxxxxx>

SRAM Memory handling for USB client function

Signed-off-by: JiebingLi <jiebing.li@xxxxxxxxx>
Signed-off-by: Alan Cox <alan@xxxxxxxxxxxxxxx>
---

 drivers/usb/gadget/langwell_udc.c |  113 +++++++++++++++++++++++++++++++++++--
 drivers/usb/gadget/langwell_udc.h |    8 ++-
 2 files changed, 115 insertions(+), 6 deletions(-)


diff --git a/drivers/usb/gadget/langwell_udc.c b/drivers/usb/gadget/langwell_udc.c
index 30acd86..3b3e5ba 100644
--- a/drivers/usb/gadget/langwell_udc.c
+++ b/drivers/usb/gadget/langwell_udc.c
@@ -2992,6 +2992,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 */
 static void langwell_udc_remove(struct pci_dev *pdev)
 {
@@ -3004,19 +3048,25 @@ static void langwell_udc_remove(struct pci_dev *pdev)
 
 	dev->done = &done;
 
-	/* free memory allocated in probe */
+#ifndef	OTG_TRANSCEIVER
+	/* 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);
+#endif
+
 	if (dev->status_req) {
 		kfree(dev->status_req->req.buf);
 		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);
 
 	/* diable IRQ handler */
@@ -3144,7 +3194,15 @@ static int langwell_udc_probe(struct pci_dev *pdev,
 		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
+	/* enable SRAM caching if detected */
+	if (dev->has_sram && !dev->got_sram)
+		sram_init(dev);
+
 	dev_info(&dev->pdev->dev,
 			"irq %d, io mem: 0x%08lx, len: 0x%08lx, pci mem 0x%p\n",
 			pdev->irq, resource, len, base);
@@ -3339,6 +3397,18 @@ static int langwell_udc_suspend(struct pci_dev *pdev, pm_message_t state)
 	/* save PCI state */
 	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 */
 	pci_set_power_state(pdev, PCI_D3hot);
 
@@ -3355,6 +3425,7 @@ static int langwell_udc_suspend(struct pci_dev *pdev, pm_message_t state)
 static int langwell_udc_resume(struct pci_dev *pdev)
 {
 	struct langwell_udc	*dev = the_controller;
+	size_t			size;
 
 	dev_dbg(&dev->pdev->dev, "---> %s()\n", __func__);
 
@@ -3365,6 +3436,38 @@ static int langwell_udc_resume(struct pci_dev *pdev)
 	/* set device D0 power state */
 	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 */
 	pci_restore_state(pdev);
 
diff --git a/drivers/usb/gadget/langwell_udc.h b/drivers/usb/gadget/langwell_udc.h
index 3d3206e..fa5563d 100644
--- a/drivers/usb/gadget/langwell_udc.h
+++ b/drivers/usb/gadget/langwell_udc.h
@@ -199,7 +199,9 @@ struct langwell_udc {
 				vbus_active:1,
 				suspended: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 */
 	struct pci_dev		*pdev;
@@ -225,6 +227,10 @@ struct langwell_udc {
 	/* make sure release() is done */
 	struct completion	*done;
 
+	/* for private SRAM caching */
+	unsigned int		sram_addr;
+	unsigned int		sram_size;
+
 	/* device status data for get_status request */
 	u16			dev_status;
 };

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux