summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGregory Nutt <gnutt@nuttx.org>2013-08-20 18:06:04 -0600
committerGregory Nutt <gnutt@nuttx.org>2013-08-20 18:06:04 -0600
commite8a979e5632ddb781c2da654c9f41990226ff83f (patch)
treeeb6e574bbbd5927416ee815bff666a93d7d7fbd0
parentfd16856ca77944914b893473fbc577a7740993c8 (diff)
downloadnuttx-e8a979e5632ddb781c2da654c9f41990226ff83f.tar.gz
nuttx-e8a979e5632ddb781c2da654c9f41990226ff83f.tar.bz2
nuttx-e8a979e5632ddb781c2da654c9f41990226ff83f.zip
SAMA5 EHCI: At list-oriented cache operations
-rwxr-xr-xnuttx/arch/arm/src/sama5/sam_ehci.c98
1 files changed, 96 insertions, 2 deletions
diff --git a/nuttx/arch/arm/src/sama5/sam_ehci.c b/nuttx/arch/arm/src/sama5/sam_ehci.c
index a2fc82b82..e4bd5113a 100755
--- a/nuttx/arch/arm/src/sama5/sam_ehci.c
+++ b/nuttx/arch/arm/src/sama5/sam_ehci.c
@@ -54,6 +54,8 @@
#include <nuttx/usb/ehci.h>
#include "up_arch.h"
+#include "cache.h"
+
#include "sam_periphclks.h"
#include "sam_memories.h"
#include "sam_usbhost.h"
@@ -240,6 +242,13 @@ static int sam_qtd_foreach(struct sam_qh_s *qh, foreach_qtd_t handler,
static int sam_qtd_discard(struct sam_qtd_s *qtd, uint32_t **bp, void *arg);
static int sam_qh_discard(struct sam_qh_s *qh);
+/* Cache Operations ************************************************************/
+
+static int sam_qtd_invalidate(struct sam_qtd_s *qtd, uint32_t **bp, void *arg);
+static int sam_qh_invalidate(struct sam_qh_s *qh);
+static int sam_qtd_flush(struct sam_qtd_s *qtd, uint32_t **bp, void *arg);
+static int sam_qh_flush(struct sam_qh_s *qh);
+
/* Interrupt Handling **********************************************************/
static int sam_ehci_interrupt(int irq, FAR void *context);
@@ -890,10 +899,10 @@ static int sam_qh_discard(struct sam_qh_s *qh)
/* Free all of the qTD's attached to the QH */
- ret = sam_gtd_foreach(qh, sam_qtd_discard, NULL);
+ ret = sam_qtd_foreach(qh, sam_qtd_discard, NULL);
if (ret < 0)
{
- udbg("ERROR: sam_gtd_foreach failed: %d\n", ret);
+ udbg("ERROR: sam_qtd_foreach failed: %d\n", ret);
}
/* Then free the QH itself */
@@ -903,6 +912,90 @@ static int sam_qh_discard(struct sam_qh_s *qh)
}
/*******************************************************************************
+ * Cache Operations
+ *******************************************************************************/
+
+/*******************************************************************************
+ * Name: sam_qtd_invalidate
+ *
+ * Description:
+ * This is a callback from sam_qtd_foreach. It simply invalidates D-cache for
+ * address range of the qTD entry.
+ *
+ *******************************************************************************/
+
+static int sam_qtd_invalidate(struct sam_qtd_s *qtd, uint32_t **bp, void *arg)
+{
+ /* Invalidate the D-Cache, i.e., force reloading of the D-Cache from memory
+ * memory over the specified address range.
+ */
+
+ cp15_invalidate_dcache((uintptr_t)&qtd->hw,
+ (uintptr_t)&qtd->hw + sizeof(struct ehci_qtd_s));
+ return OK;
+}
+
+/*******************************************************************************
+ * Name: sam_qh_invalidate
+ *
+ * Description:
+ * Invalidate the Queue Head and all qTD entries in the queue.
+ *
+ *******************************************************************************/
+
+static int sam_qh_invalidate(struct sam_qh_s *qh)
+{
+ /* Invalidate the QH first so that we reload the qTD list head */
+
+ cp15_invalidate_dcache((uintptr_t)&qh->hw,
+ (uintptr_t)&qh->hw + sizeof(struct ehci_qh_s));
+
+ /* Then invalidate all of the qTD entries in the queue */
+
+ return sam_qtd_foreach(qh, NULL, NULL);
+}
+
+/*******************************************************************************
+ * Name: sam_qtd_flush
+ *
+ * Description:
+ * This is a callback from sam_qtd_foreach. It simply flushes D-cache for
+ * address range of the qTD entry.
+ *
+ *******************************************************************************/
+
+static int sam_qtd_flush(struct sam_qtd_s *qtd, uint32_t **bp, void *arg)
+{
+ /* Flush the D-Cache, i.e., make the contents of the memory match the contents
+ * of the D-Cache in the specified address range.
+ */
+
+ cp15_coherent_dcache((uintptr_t)&qtd->hw,
+ (uintptr_t)&qtd->hw + sizeof(struct ehci_qtd_s));
+ return OK;
+}
+
+/*******************************************************************************
+ * Name: sam_qh_flush
+ *
+ * Description:
+ * Invalidate the Queue Head and all qTD entries in the queue.
+ *
+ *******************************************************************************/
+
+static int sam_qh_flush(struct sam_qh_s *qh)
+{
+ /* Flush the QH first */
+
+ cp15_invalidate_dcache((uintptr_t)&qh->hw,
+ (uintptr_t)&qh->hw + sizeof(struct ehci_qh_s));
+
+ /* Then flush all of the qTD entries in the queue */
+
+ return sam_qtd_foreach(qh, NULL, NULL);
+}
+
+/*******************************************************************************
* EHCI Interrupt Handling
*******************************************************************************/
@@ -1214,6 +1307,7 @@ static int sam_epfree(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep)
sam_takesem(&g_ehci.exclsem);
#warning Missing logic
+ ret = -ENOSYS;
/* And free the container */