diff options
author | Gregory Nutt <gnutt@nuttx.org> | 2013-08-20 18:06:04 -0600 |
---|---|---|
committer | Gregory Nutt <gnutt@nuttx.org> | 2013-08-20 18:06:04 -0600 |
commit | e8a979e5632ddb781c2da654c9f41990226ff83f (patch) | |
tree | eb6e574bbbd5927416ee815bff666a93d7d7fbd0 | |
parent | fd16856ca77944914b893473fbc577a7740993c8 (diff) | |
download | nuttx-e8a979e5632ddb781c2da654c9f41990226ff83f.tar.gz nuttx-e8a979e5632ddb781c2da654c9f41990226ff83f.tar.bz2 nuttx-e8a979e5632ddb781c2da654c9f41990226ff83f.zip |
SAMA5 EHCI: At list-oriented cache operations
-rwxr-xr-x | nuttx/arch/arm/src/sama5/sam_ehci.c | 98 |
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 */ |