05d02b79bd69530a00e0a4cd15dc36d74246cea4
[oweals/openwrt.git] /
1 From 4b15965fc7456d84f1ad25e1263cf6ddbb60681a Mon Sep 17 00:00:00 2001
2 From: Dave Stevenson <dave.stevenson@raspberrypi.org>
3 Date: Wed, 30 Jan 2019 17:47:51 +0000
4 Subject: [PATCH 337/782] usb: dwc_otg: Use dma allocation for mphi dummy_send
5  buffer
6
7 The FIQ driver used a kzalloc'ed buffer for dummy_send,
8 passing a kernel virtual address to the hardware block.
9 The buffer is only ever used for a dummy read, so it
10 should be harmless, but there is the chance that it will
11 cause exceptions.
12
13 Use a dma allocation so that we have a genuine bus address,
14 and read from that.
15 Free the allocation when done for good measure.
16
17 Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.org>
18 ---
19  drivers/usb/host/dwc_otg/dwc_otg_fiq_fsm.c | 4 ++--
20  drivers/usb/host/dwc_otg/dwc_otg_fiq_fsm.h | 1 +
21  drivers/usb/host/dwc_otg/dwc_otg_hcd.c     | 5 ++++-
22  3 files changed, 7 insertions(+), 3 deletions(-)
23
24 --- a/drivers/usb/host/dwc_otg/dwc_otg_fiq_fsm.c
25 +++ b/drivers/usb/host/dwc_otg/dwc_otg_fiq_fsm.c
26 @@ -1347,7 +1347,7 @@ void notrace dwc_otg_fiq_fsm(struct fiq_
27         /* We got an interrupt, didn't handle it. */
28         if (kick_irq) {
29                 state->mphi_int_count++;
30 -               FIQ_WRITE(state->mphi_regs.outdda, (int) state->dummy_send);
31 +               FIQ_WRITE(state->mphi_regs.outdda, state->dummy_send_dma);
32                 FIQ_WRITE(state->mphi_regs.outddb, (1<<29));
33  
34         }
35 @@ -1408,7 +1408,7 @@ void notrace dwc_otg_fiq_nop(struct fiq_
36                 FIQ_WRITE(state->dwc_regs_base + GINTMSK, gintmsk.d32);
37                 /* Force a clear before another dummy send */
38                 FIQ_WRITE(state->mphi_regs.intstat, (1<<29));
39 -               FIQ_WRITE(state->mphi_regs.outdda, (int) state->dummy_send);
40 +               FIQ_WRITE(state->mphi_regs.outdda, state->dummy_send_dma);
41                 FIQ_WRITE(state->mphi_regs.outddb, (1<<29));
42  
43         }
44 --- a/drivers/usb/host/dwc_otg/dwc_otg_fiq_fsm.h
45 +++ b/drivers/usb/host/dwc_otg/dwc_otg_fiq_fsm.h
46 @@ -352,6 +352,7 @@ struct fiq_state {
47         dma_addr_t dma_base;
48         struct fiq_dma_blob *fiq_dmab;
49         void *dummy_send;
50 +       dma_addr_t dummy_send_dma;
51         gintmsk_data_t gintmsk_saved;
52         haintmsk_data_t haintmsk_saved;
53         int mphi_int_count;
54 --- a/drivers/usb/host/dwc_otg/dwc_otg_hcd.c
55 +++ b/drivers/usb/host/dwc_otg/dwc_otg_hcd.c
56 @@ -929,6 +929,8 @@ static void dwc_otg_hcd_free(dwc_otg_hcd
57         DWC_TIMER_FREE(dwc_otg_hcd->conn_timer);
58         DWC_TASK_FREE(dwc_otg_hcd->reset_tasklet);
59         DWC_TASK_FREE(dwc_otg_hcd->completion_tasklet);
60 +       DWC_DMA_FREE(dev, 16, dwc_otg_hcd->fiq_state->dummy_send,
61 +                    dwc_otg_hcd->fiq_state->dummy_send_dma);
62         DWC_FREE(dwc_otg_hcd->fiq_state);
63  
64  #ifdef DWC_DEV_SRPCAP
65 @@ -1021,7 +1023,8 @@ int dwc_otg_hcd_init(dwc_otg_hcd_t * hcd
66                 for (i = 0; i < num_channels; i++) {
67                         hcd->fiq_state->channel[i].fsm = FIQ_PASSTHROUGH;
68                 }
69 -               hcd->fiq_state->dummy_send = DWC_ALLOC_ATOMIC(16);
70 +               hcd->fiq_state->dummy_send = DWC_DMA_ALLOC_ATOMIC(dev, 16,
71 +                                                        &hcd->fiq_state->dummy_send_dma);
72  
73                 hcd->fiq_stack = DWC_ALLOC(sizeof(struct fiq_stack));
74                 if (!hcd->fiq_stack) {