diff options
Diffstat (limited to 'meta/recipes-kernel/linux/linux-omap-2.6.29/musb/0018-musb-split-out-CPPI-interrupt-handler.patch')
-rw-r--r-- | meta/recipes-kernel/linux/linux-omap-2.6.29/musb/0018-musb-split-out-CPPI-interrupt-handler.patch | 167 |
1 files changed, 167 insertions, 0 deletions
diff --git a/meta/recipes-kernel/linux/linux-omap-2.6.29/musb/0018-musb-split-out-CPPI-interrupt-handler.patch b/meta/recipes-kernel/linux/linux-omap-2.6.29/musb/0018-musb-split-out-CPPI-interrupt-handler.patch new file mode 100644 index 0000000000..bf3d6e7021 --- /dev/null +++ b/meta/recipes-kernel/linux/linux-omap-2.6.29/musb/0018-musb-split-out-CPPI-interrupt-handler.patch | |||
@@ -0,0 +1,167 @@ | |||
1 | From b91b067c531c9322f3719951b07303e790b13475 Mon Sep 17 00:00:00 2001 | ||
2 | From: Sergei Shtylyov <sshtylyov-hkdhdckH98+B+jHODAdFcQ@public.gmane.org> | ||
3 | Date: Fri, 27 Mar 2009 12:59:46 -0700 | ||
4 | Subject: [PATCH] musb: split out CPPI interrupt handler | ||
5 | |||
6 | As DaVinci DM646x has a dedicated CPPI DMA interrupt, replace | ||
7 | cppi_completion() (which has always been kind of layering | ||
8 | violation) by a complete CPPI interrupt handler. | ||
9 | |||
10 | [ dbrownell-Rn4VEauK+AKRv+LV9MX5uipxlwaOVQ5f@public.gmane.org: only cppi_dma.c needs platform | ||
11 | device header, not cppi_dma.h ] | ||
12 | |||
13 | Signed-off-by: Dmitry Krivoschekov <dkrivoschekov-hkdhdckH98+B+jHODAdFcQ@public.gmane.org> | ||
14 | Signed-off-by: Sergei Shtylyov <sshtylyov-hkdhdckH98+B+jHODAdFcQ@public.gmane.org> | ||
15 | Signed-off-by: David Brownell <dbrownell-Rn4VEauK+AKRv+LV9MX5uipxlwaOVQ5f@public.gmane.org> | ||
16 | --- | ||
17 | drivers/usb/musb/cppi_dma.c | 34 +++++++++++++++++++++++++++++++--- | ||
18 | drivers/usb/musb/cppi_dma.h | 6 ++++-- | ||
19 | drivers/usb/musb/davinci.c | 14 ++++---------- | ||
20 | 3 files changed, 39 insertions(+), 15 deletions(-) | ||
21 | |||
22 | diff --git a/drivers/usb/musb/cppi_dma.c b/drivers/usb/musb/cppi_dma.c | ||
23 | index ac7227c..6ff3c67 100644 | ||
24 | --- a/drivers/usb/musb/cppi_dma.c | ||
25 | +++ b/drivers/usb/musb/cppi_dma.c | ||
26 | @@ -6,6 +6,7 @@ | ||
27 | * The TUSB6020, using VLYNQ, has CPPI that looks much like DaVinci. | ||
28 | */ | ||
29 | |||
30 | +#include <linux/platform_device.h> | ||
31 | #include <linux/usb.h> | ||
32 | |||
33 | #include "musb_core.h" | ||
34 | @@ -1145,17 +1146,27 @@ static bool cppi_rx_scan(struct cppi *cppi, unsigned ch) | ||
35 | return completed; | ||
36 | } | ||
37 | |||
38 | -void cppi_completion(struct musb *musb, u32 rx, u32 tx) | ||
39 | +irqreturn_t cppi_interrupt(int irq, void *dev_id) | ||
40 | { | ||
41 | - void __iomem *tibase; | ||
42 | - int i, index; | ||
43 | + struct musb *musb = dev_id; | ||
44 | struct cppi *cppi; | ||
45 | + void __iomem *tibase; | ||
46 | struct musb_hw_ep *hw_ep = NULL; | ||
47 | + u32 rx, tx; | ||
48 | + int i, index; | ||
49 | |||
50 | cppi = container_of(musb->dma_controller, struct cppi, controller); | ||
51 | |||
52 | tibase = musb->ctrl_base; | ||
53 | |||
54 | + tx = musb_readl(tibase, DAVINCI_TXCPPI_MASKED_REG); | ||
55 | + rx = musb_readl(tibase, DAVINCI_RXCPPI_MASKED_REG); | ||
56 | + | ||
57 | + if (!tx && !rx) | ||
58 | + return IRQ_NONE; | ||
59 | + | ||
60 | + DBG(4, "CPPI IRQ Tx%x Rx%x\n", tx, rx); | ||
61 | + | ||
62 | /* process TX channels */ | ||
63 | for (index = 0; tx; tx = tx >> 1, index++) { | ||
64 | struct cppi_channel *tx_ch; | ||
65 | @@ -1293,6 +1304,8 @@ void cppi_completion(struct musb *musb, u32 rx, u32 tx) | ||
66 | |||
67 | /* write to CPPI EOI register to re-enable interrupts */ | ||
68 | musb_writel(tibase, DAVINCI_CPPI_EOI_REG, 0); | ||
69 | + | ||
70 | + return IRQ_HANDLED; | ||
71 | } | ||
72 | |||
73 | /* Instantiate a software object representing a DMA controller. */ | ||
74 | @@ -1300,6 +1313,9 @@ struct dma_controller *__init | ||
75 | dma_controller_create(struct musb *musb, void __iomem *mregs) | ||
76 | { | ||
77 | struct cppi *controller; | ||
78 | + struct device *dev = musb->controller; | ||
79 | + struct platform_device *pdev = to_platform_device(dev); | ||
80 | + int irq = platform_get_irq(pdev, 1); | ||
81 | |||
82 | controller = kzalloc(sizeof *controller, GFP_KERNEL); | ||
83 | if (!controller) | ||
84 | @@ -1330,6 +1346,15 @@ dma_controller_create(struct musb *musb, void __iomem *mregs) | ||
85 | return NULL; | ||
86 | } | ||
87 | |||
88 | + if (irq > 0) { | ||
89 | + if (request_irq(irq, cppi_interrupt, 0, "cppi-dma", musb)) { | ||
90 | + dev_err(dev, "request_irq %d failed!\n", irq); | ||
91 | + dma_controller_destroy(&controller->controller); | ||
92 | + return NULL; | ||
93 | + } | ||
94 | + controller->irq = irq; | ||
95 | + } | ||
96 | + | ||
97 | return &controller->controller; | ||
98 | } | ||
99 | |||
100 | @@ -1342,6 +1367,9 @@ void dma_controller_destroy(struct dma_controller *c) | ||
101 | |||
102 | cppi = container_of(c, struct cppi, controller); | ||
103 | |||
104 | + if (cppi->irq) | ||
105 | + free_irq(cppi->irq, cppi->musb); | ||
106 | + | ||
107 | /* assert: caller stopped the controller first */ | ||
108 | dma_pool_destroy(cppi->pool); | ||
109 | |||
110 | diff --git a/drivers/usb/musb/cppi_dma.h b/drivers/usb/musb/cppi_dma.h | ||
111 | index 729b407..8a39de3 100644 | ||
112 | --- a/drivers/usb/musb/cppi_dma.h | ||
113 | +++ b/drivers/usb/musb/cppi_dma.h | ||
114 | @@ -119,6 +119,8 @@ struct cppi { | ||
115 | void __iomem *mregs; /* Mentor regs */ | ||
116 | void __iomem *tibase; /* TI/CPPI regs */ | ||
117 | |||
118 | + int irq; | ||
119 | + | ||
120 | struct cppi_channel tx[4]; | ||
121 | struct cppi_channel rx[4]; | ||
122 | |||
123 | @@ -127,7 +129,7 @@ struct cppi { | ||
124 | struct list_head tx_complete; | ||
125 | }; | ||
126 | |||
127 | -/* irq handling hook */ | ||
128 | -extern void cppi_completion(struct musb *, u32 rx, u32 tx); | ||
129 | +/* CPPI IRQ handler */ | ||
130 | +extern irqreturn_t cppi_interrupt(int, void *); | ||
131 | |||
132 | #endif /* end of ifndef _CPPI_DMA_H_ */ | ||
133 | diff --git a/drivers/usb/musb/davinci.c b/drivers/usb/musb/davinci.c | ||
134 | index 399c435..9fd74bf 100644 | ||
135 | --- a/drivers/usb/musb/davinci.c | ||
136 | +++ b/drivers/usb/musb/davinci.c | ||
137 | @@ -250,6 +250,7 @@ static irqreturn_t davinci_interrupt(int irq, void *__hci) | ||
138 | irqreturn_t retval = IRQ_NONE; | ||
139 | struct musb *musb = __hci; | ||
140 | void __iomem *tibase = musb->ctrl_base; | ||
141 | + struct cppi *cppi; | ||
142 | u32 tmp; | ||
143 | |||
144 | spin_lock_irqsave(&musb->lock, flags); | ||
145 | @@ -266,16 +267,9 @@ static irqreturn_t davinci_interrupt(int irq, void *__hci) | ||
146 | /* CPPI interrupts share the same IRQ line, but have their own | ||
147 | * mask, state, "vector", and EOI registers. | ||
148 | */ | ||
149 | - if (is_cppi_enabled()) { | ||
150 | - u32 cppi_tx = musb_readl(tibase, DAVINCI_TXCPPI_MASKED_REG); | ||
151 | - u32 cppi_rx = musb_readl(tibase, DAVINCI_RXCPPI_MASKED_REG); | ||
152 | - | ||
153 | - if (cppi_tx || cppi_rx) { | ||
154 | - DBG(4, "CPPI IRQ t%x r%x\n", cppi_tx, cppi_rx); | ||
155 | - cppi_completion(musb, cppi_rx, cppi_tx); | ||
156 | - retval = IRQ_HANDLED; | ||
157 | - } | ||
158 | - } | ||
159 | + cppi = container_of(musb->dma_controller, struct cppi, controller); | ||
160 | + if (is_cppi_enabled() && musb->dma_controller && !cppi->irq) | ||
161 | + retval = cppi_interrupt(irq, __hci); | ||
162 | |||
163 | /* ack and handle non-CPPI interrupts */ | ||
164 | tmp = musb_readl(tibase, DAVINCI_USB_INT_SRC_MASKED_REG); | ||
165 | -- | ||
166 | 1.6.0.4 | ||
167 | |||