aboutsummaryrefslogtreecommitdiffstats
path: root/recipes/kexecboot/linux-kexecboot-2.6.29/musb/0010-musb-sanitize-clearing-TXCSR-DMA-bits-take-2.patch
diff options
context:
space:
mode:
Diffstat (limited to 'recipes/kexecboot/linux-kexecboot-2.6.29/musb/0010-musb-sanitize-clearing-TXCSR-DMA-bits-take-2.patch')
-rw-r--r--recipes/kexecboot/linux-kexecboot-2.6.29/musb/0010-musb-sanitize-clearing-TXCSR-DMA-bits-take-2.patch361
1 files changed, 0 insertions, 361 deletions
diff --git a/recipes/kexecboot/linux-kexecboot-2.6.29/musb/0010-musb-sanitize-clearing-TXCSR-DMA-bits-take-2.patch b/recipes/kexecboot/linux-kexecboot-2.6.29/musb/0010-musb-sanitize-clearing-TXCSR-DMA-bits-take-2.patch
deleted file mode 100644
index bcbe3bbe39..0000000000
--- a/recipes/kexecboot/linux-kexecboot-2.6.29/musb/0010-musb-sanitize-clearing-TXCSR-DMA-bits-take-2.patch
+++ /dev/null
@@ -1,361 +0,0 @@
-From c99f4a68268801a2e2ffbef9766c3ac89e4fb22c Mon Sep 17 00:00:00 2001
-From: Sergei Shtylyov <sshtylyov-hkdhdckH98+B+jHODAdFcQ@public.gmane.org>
-Date: Thu, 26 Mar 2009 18:27:47 -0700
-Subject: [PATCH] musb: sanitize clearing TXCSR DMA bits (take 2)
-
-The MUSB code clears TXCSR_DMAMODE incorrectly in several
-places, either asserting that TXCSR_DMAENAB is clear (when
-sometimes it isn't) or clearing both bits together. Recent
-versions of the programmer's guide require DMAENAB to be
-cleared first, although some older ones didn't.
-
-Fix this and while at it:
-
- - In musb_gadget::txstate(), stop clearing the AUTOSET
- and DMAMODE bits for the CPPI case since they never
- get set anyway (the former bit is reserved on DaVinci);
- but do clear the DMAENAB bit on the DMA error path.
-
- - In musb_host::musb_ep_program(), remove the duplicate
- DMA controller specific code code clearing the TXCSR
- previous state, add the code to clear TXCSR DMA bits
- on the Inventra DMA error path, to replace such code
- (executed late) on the PIO path.
-
- - In musbhsdma::dma_channel_abort()/dma_controller_irq(),
- add/use the 'offset' variable to avoid MUSB_EP_OFFSET()
- invocations on every RXCSR/TXCSR access.
-
-[dbrownell-Rn4VEauK+AKRv+LV9MX5uipxlwaOVQ5f@public.gmane.org: don't introduce CamelCase,
-shrink diff]
-
-Signed-off-by: Sergei Shtylyov <sshtylyov-hkdhdckH98+B+jHODAdFcQ@public.gmane.org>
-Signed-off-by: David Brownell <dbrownell-Rn4VEauK+AKRv+LV9MX5uipxlwaOVQ5f@public.gmane.org>
----
- drivers/usb/musb/musb_gadget.c | 33 +++++++++++------
- drivers/usb/musb/musb_host.c | 79 ++++++++++++++++------------------------
- drivers/usb/musb/musbhsdma.c | 59 ++++++++++++++++++------------
- 3 files changed, 90 insertions(+), 81 deletions(-)
-
-diff --git a/drivers/usb/musb/musb_gadget.c b/drivers/usb/musb/musb_gadget.c
-index c7ebd08..f79440c 100644
---- a/drivers/usb/musb/musb_gadget.c
-+++ b/drivers/usb/musb/musb_gadget.c
-@@ -165,9 +165,15 @@ static void nuke(struct musb_ep *ep, const int status)
- if (is_dma_capable() && ep->dma) {
- struct dma_controller *c = ep->musb->dma_controller;
- int value;
-+
- if (ep->is_in) {
-+ /*
-+ * The programming guide says that we must not clear
-+ * the DMAMODE bit before DMAENAB, so we only
-+ * clear it in the second write...
-+ */
- musb_writew(epio, MUSB_TXCSR,
-- 0 | MUSB_TXCSR_FLUSHFIFO);
-+ MUSB_TXCSR_DMAMODE | MUSB_TXCSR_FLUSHFIFO);
- musb_writew(epio, MUSB_TXCSR,
- 0 | MUSB_TXCSR_FLUSHFIFO);
- } else {
-@@ -230,7 +236,7 @@ static inline int max_ep_writesize(struct musb *musb, struct musb_ep *ep)
- | IN token(s) are recd from Host.
- | -> DMA interrupt on completion
- | calls TxAvail.
-- | -> stop DMA, ~DmaEenab,
-+ | -> stop DMA, ~DMAENAB,
- | -> set TxPktRdy for last short pkt or zlp
- | -> Complete Request
- | -> Continue next request (call txstate)
-@@ -315,9 +321,17 @@ static void txstate(struct musb *musb, struct musb_request *req)
- request->dma, request_size);
- if (use_dma) {
- if (musb_ep->dma->desired_mode == 0) {
-- /* ASSERT: DMAENAB is clear */
-- csr &= ~(MUSB_TXCSR_AUTOSET |
-- MUSB_TXCSR_DMAMODE);
-+ /*
-+ * We must not clear the DMAMODE bit
-+ * before the DMAENAB bit -- and the
-+ * latter doesn't always get cleared
-+ * before we get here...
-+ */
-+ csr &= ~(MUSB_TXCSR_AUTOSET
-+ | MUSB_TXCSR_DMAENAB);
-+ musb_writew(epio, MUSB_TXCSR, csr
-+ | MUSB_TXCSR_P_WZC_BITS);
-+ csr &= ~MUSB_TXCSR_DMAMODE;
- csr |= (MUSB_TXCSR_DMAENAB |
- MUSB_TXCSR_MODE);
- /* against programming guide */
-@@ -334,10 +348,7 @@ static void txstate(struct musb *musb, struct musb_request *req)
-
- #elif defined(CONFIG_USB_TI_CPPI_DMA)
- /* program endpoint CSR first, then setup DMA */
-- csr &= ~(MUSB_TXCSR_AUTOSET
-- | MUSB_TXCSR_DMAMODE
-- | MUSB_TXCSR_P_UNDERRUN
-- | MUSB_TXCSR_TXPKTRDY);
-+ csr &= ~(MUSB_TXCSR_P_UNDERRUN | MUSB_TXCSR_TXPKTRDY);
- csr |= MUSB_TXCSR_MODE | MUSB_TXCSR_DMAENAB;
- musb_writew(epio, MUSB_TXCSR,
- (MUSB_TXCSR_P_WZC_BITS & ~MUSB_TXCSR_P_UNDERRUN)
-@@ -364,8 +375,8 @@ static void txstate(struct musb *musb, struct musb_request *req)
- if (!use_dma) {
- c->channel_release(musb_ep->dma);
- musb_ep->dma = NULL;
-- /* ASSERT: DMAENAB clear */
-- csr &= ~(MUSB_TXCSR_DMAMODE | MUSB_TXCSR_MODE);
-+ csr &= ~MUSB_TXCSR_DMAENAB;
-+ musb_writew(epio, MUSB_TXCSR, csr);
- /* invariant: prequest->buf is non-null */
- }
- #elif defined(CONFIG_USB_TUSB_OMAP_DMA)
-diff --git a/drivers/usb/musb/musb_host.c b/drivers/usb/musb/musb_host.c
-index a5d75aa..6591282 100644
---- a/drivers/usb/musb/musb_host.c
-+++ b/drivers/usb/musb/musb_host.c
-@@ -590,10 +590,17 @@ musb_rx_reinit(struct musb *musb, struct musb_qh *qh, struct musb_hw_ep *ep)
- csr = musb_readw(ep->regs, MUSB_TXCSR);
- if (csr & MUSB_TXCSR_MODE) {
- musb_h_tx_flush_fifo(ep);
-+ csr = musb_readw(ep->regs, MUSB_TXCSR);
- musb_writew(ep->regs, MUSB_TXCSR,
-- MUSB_TXCSR_FRCDATATOG);
-+ csr | MUSB_TXCSR_FRCDATATOG);
- }
-- /* clear mode (and everything else) to enable Rx */
-+
-+ /*
-+ * Clear the MODE bit (and everything else) to enable Rx.
-+ * NOTE: we mustn't clear the DMAMODE bit before DMAENAB.
-+ */
-+ if (csr & MUSB_TXCSR_DMAMODE)
-+ musb_writew(ep->regs, MUSB_TXCSR, MUSB_TXCSR_DMAMODE);
- musb_writew(ep->regs, MUSB_TXCSR, 0);
-
- /* scrub all previous state, clearing toggle */
-@@ -690,12 +697,17 @@ static void musb_ep_program(struct musb *musb, u8 epnum,
-
- /* general endpoint setup */
- if (epnum) {
-- /* ASSERT: TXCSR_DMAENAB was already cleared */
--
- /* flush all old state, set default */
- musb_h_tx_flush_fifo(hw_ep);
-+
-+ /*
-+ * We must not clear the DMAMODE bit before or in
-+ * the same cycle with the DMAENAB bit, so we clear
-+ * the latter first...
-+ */
- csr &= ~(MUSB_TXCSR_H_NAKTIMEOUT
-- | MUSB_TXCSR_DMAMODE
-+ | MUSB_TXCSR_AUTOSET
-+ | MUSB_TXCSR_DMAENAB
- | MUSB_TXCSR_FRCDATATOG
- | MUSB_TXCSR_H_RXSTALL
- | MUSB_TXCSR_H_ERROR
-@@ -703,16 +715,15 @@ static void musb_ep_program(struct musb *musb, u8 epnum,
- );
- csr |= MUSB_TXCSR_MODE;
-
-- if (usb_gettoggle(urb->dev,
-- qh->epnum, 1))
-+ if (usb_gettoggle(urb->dev, qh->epnum, 1))
- csr |= MUSB_TXCSR_H_WR_DATATOGGLE
- | MUSB_TXCSR_H_DATATOGGLE;
- else
- csr |= MUSB_TXCSR_CLRDATATOG;
-
-- /* twice in case of double packet buffering */
- musb_writew(epio, MUSB_TXCSR, csr);
- /* REVISIT may need to clear FLUSHFIFO ... */
-+ csr &= ~MUSB_TXCSR_DMAMODE;
- musb_writew(epio, MUSB_TXCSR, csr);
- csr = musb_readw(epio, MUSB_TXCSR);
- } else {
-@@ -755,34 +766,19 @@ static void musb_ep_program(struct musb *musb, u8 epnum,
-
- #ifdef CONFIG_USB_INVENTRA_DMA
- if (dma_channel) {
--
-- /* clear previous state */
-- csr = musb_readw(epio, MUSB_TXCSR);
-- csr &= ~(MUSB_TXCSR_AUTOSET
-- | MUSB_TXCSR_DMAMODE
-- | MUSB_TXCSR_DMAENAB);
-- csr |= MUSB_TXCSR_MODE;
-- musb_writew(epio, MUSB_TXCSR,
-- csr | MUSB_TXCSR_MODE);
--
- qh->segsize = min(len, dma_channel->max_len);
--
- if (qh->segsize <= packet_sz)
- dma_channel->desired_mode = 0;
- else
- dma_channel->desired_mode = 1;
-
--
- if (dma_channel->desired_mode == 0) {
-- csr &= ~(MUSB_TXCSR_AUTOSET
-- | MUSB_TXCSR_DMAMODE);
-+ /* Against the programming guide */
- csr |= (MUSB_TXCSR_DMAENAB);
-- /* against programming guide */
- } else
- csr |= (MUSB_TXCSR_AUTOSET
- | MUSB_TXCSR_DMAENAB
- | MUSB_TXCSR_DMAMODE);
--
- musb_writew(epio, MUSB_TXCSR, csr);
-
- dma_ok = dma_controller->channel_program(
-@@ -799,6 +795,17 @@ static void musb_ep_program(struct musb *musb, u8 epnum,
- else
- hw_ep->rx_channel = NULL;
- dma_channel = NULL;
-+
-+ /*
-+ * The programming guide says that we must
-+ * clear the DMAENAB bit before DMAMODE...
-+ */
-+ csr = musb_readw(epio, MUSB_TXCSR);
-+ csr &= ~(MUSB_TXCSR_DMAENAB
-+ | MUSB_TXCSR_AUTOSET);
-+ musb_writew(epio, MUSB_TXCSR, csr);
-+ csr &= ~MUSB_TXCSR_DMAMODE;
-+ musb_writew(epio, MUSB_TXCSR, csr);
- }
- }
- #endif
-@@ -806,18 +813,7 @@ static void musb_ep_program(struct musb *musb, u8 epnum,
- /* candidate for DMA */
- if ((is_cppi_enabled() || tusb_dma_omap()) && dma_channel) {
-
-- /* program endpoint CSRs first, then setup DMA.
-- * assume CPPI setup succeeds.
-- * defer enabling dma.
-- */
-- csr = musb_readw(epio, MUSB_TXCSR);
-- csr &= ~(MUSB_TXCSR_AUTOSET
-- | MUSB_TXCSR_DMAMODE
-- | MUSB_TXCSR_DMAENAB);
-- csr |= MUSB_TXCSR_MODE;
-- musb_writew(epio, MUSB_TXCSR,
-- csr | MUSB_TXCSR_MODE);
--
-+ /* Defer enabling DMA */
- dma_channel->actual_len = 0L;
- qh->segsize = len;
-
-@@ -846,20 +842,9 @@ static void musb_ep_program(struct musb *musb, u8 epnum,
- }
-
- if (load_count) {
-- /* ASSERT: TXCSR_DMAENAB was already cleared */
--
- /* PIO to load FIFO */
- qh->segsize = load_count;
- musb_write_fifo(hw_ep, load_count, buf);
-- csr = musb_readw(epio, MUSB_TXCSR);
-- csr &= ~(MUSB_TXCSR_DMAENAB
-- | MUSB_TXCSR_DMAMODE
-- | MUSB_TXCSR_AUTOSET);
-- /* write CSR */
-- csr |= MUSB_TXCSR_MODE;
--
-- if (epnum)
-- musb_writew(epio, MUSB_TXCSR, csr);
- }
-
- /* re-enable interrupt */
-diff --git a/drivers/usb/musb/musbhsdma.c b/drivers/usb/musb/musbhsdma.c
-index 8662e9e..40709c3 100644
---- a/drivers/usb/musb/musbhsdma.c
-+++ b/drivers/usb/musb/musbhsdma.c
-@@ -195,30 +195,32 @@ static int dma_channel_abort(struct dma_channel *channel)
- void __iomem *mbase = musb_channel->controller->base;
-
- u8 bchannel = musb_channel->idx;
-+ int offset;
- u16 csr;
-
- if (channel->status == MUSB_DMA_STATUS_BUSY) {
- if (musb_channel->transmit) {
--
-- csr = musb_readw(mbase,
-- MUSB_EP_OFFSET(musb_channel->epnum,
-- MUSB_TXCSR));
-- csr &= ~(MUSB_TXCSR_AUTOSET |
-- MUSB_TXCSR_DMAENAB |
-- MUSB_TXCSR_DMAMODE);
-- musb_writew(mbase,
-- MUSB_EP_OFFSET(musb_channel->epnum, MUSB_TXCSR),
-- csr);
-+ offset = MUSB_EP_OFFSET(musb_channel->epnum,
-+ MUSB_TXCSR);
-+
-+ /*
-+ * The programming guide says that we must clear
-+ * the DMAENAB bit before the DMAMODE bit...
-+ */
-+ csr = musb_readw(mbase, offset);
-+ csr &= ~(MUSB_TXCSR_AUTOSET | MUSB_TXCSR_DMAENAB);
-+ musb_writew(mbase, offset, csr);
-+ csr &= ~MUSB_TXCSR_DMAMODE;
-+ musb_writew(mbase, offset, csr);
- } else {
-- csr = musb_readw(mbase,
-- MUSB_EP_OFFSET(musb_channel->epnum,
-- MUSB_RXCSR));
-+ offset = MUSB_EP_OFFSET(musb_channel->epnum,
-+ MUSB_RXCSR);
-+
-+ csr = musb_readw(mbase, offset);
- csr &= ~(MUSB_RXCSR_AUTOCLEAR |
- MUSB_RXCSR_DMAENAB |
- MUSB_RXCSR_DMAMODE);
-- musb_writew(mbase,
-- MUSB_EP_OFFSET(musb_channel->epnum, MUSB_RXCSR),
-- csr);
-+ musb_writew(mbase, offset, csr);
- }
-
- musb_writew(mbase,
-@@ -296,14 +298,25 @@ static irqreturn_t dma_controller_irq(int irq, void *private_data)
- && ((channel->desired_mode == 0)
- || (channel->actual_len &
- (musb_channel->max_packet_sz - 1)))
-- ) {
-+ ) {
-+ u8 epnum = musb_channel->epnum;
-+ int offset = MUSB_EP_OFFSET(epnum,
-+ MUSB_TXCSR);
-+ u16 txcsr;
-+
-+ /*
-+ * The programming guide says that we
-+ * must clear DMAENAB before DMAMODE.
-+ */
-+ musb_ep_select(mbase, epnum);
-+ txcsr = musb_readw(mbase, offset);
-+ txcsr &= ~(MUSB_TXCSR_DMAENAB
-+ | MUSB_TXCSR_AUTOSET);
-+ musb_writew(mbase, offset, txcsr);
- /* Send out the packet */
-- musb_ep_select(mbase,
-- musb_channel->epnum);
-- musb_writew(mbase, MUSB_EP_OFFSET(
-- musb_channel->epnum,
-- MUSB_TXCSR),
-- MUSB_TXCSR_TXPKTRDY);
-+ txcsr &= ~MUSB_TXCSR_DMAMODE;
-+ txcsr |= MUSB_TXCSR_TXPKTRDY;
-+ musb_writew(mbase, offset, txcsr);
- } else {
- musb_dma_completion(
- musb,
---
-1.6.0.4
-