Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
ebus.c
Go to the documentation of this file.
1 /* ebus.c: EBUS DMA library code.
2  *
3  * Copyright (C) 1997 Eddie C. Dost ([email protected])
4  * Copyright (C) 1999 David S. Miller ([email protected])
5  */
6 
7 #include <linux/export.h>
8 #include <linux/kernel.h>
9 #include <linux/types.h>
10 #include <linux/init.h>
11 #include <linux/interrupt.h>
12 #include <linux/delay.h>
13 
14 #include <asm/ebus_dma.h>
15 #include <asm/io.h>
16 
17 #define EBDMA_CSR 0x00UL /* Control/Status */
18 #define EBDMA_ADDR 0x04UL /* DMA Address */
19 #define EBDMA_COUNT 0x08UL /* DMA Count */
20 
21 #define EBDMA_CSR_INT_PEND 0x00000001
22 #define EBDMA_CSR_ERR_PEND 0x00000002
23 #define EBDMA_CSR_DRAIN 0x00000004
24 #define EBDMA_CSR_INT_EN 0x00000010
25 #define EBDMA_CSR_RESET 0x00000080
26 #define EBDMA_CSR_WRITE 0x00000100
27 #define EBDMA_CSR_EN_DMA 0x00000200
28 #define EBDMA_CSR_CYC_PEND 0x00000400
29 #define EBDMA_CSR_DIAG_RD_DONE 0x00000800
30 #define EBDMA_CSR_DIAG_WR_DONE 0x00001000
31 #define EBDMA_CSR_EN_CNT 0x00002000
32 #define EBDMA_CSR_TC 0x00004000
33 #define EBDMA_CSR_DIS_CSR_DRN 0x00010000
34 #define EBDMA_CSR_BURST_SZ_MASK 0x000c0000
35 #define EBDMA_CSR_BURST_SZ_1 0x00080000
36 #define EBDMA_CSR_BURST_SZ_4 0x00000000
37 #define EBDMA_CSR_BURST_SZ_8 0x00040000
38 #define EBDMA_CSR_BURST_SZ_16 0x000c0000
39 #define EBDMA_CSR_DIAG_EN 0x00100000
40 #define EBDMA_CSR_DIS_ERR_PEND 0x00400000
41 #define EBDMA_CSR_TCI_DIS 0x00800000
42 #define EBDMA_CSR_EN_NEXT 0x01000000
43 #define EBDMA_CSR_DMA_ON 0x02000000
44 #define EBDMA_CSR_A_LOADED 0x04000000
45 #define EBDMA_CSR_NA_LOADED 0x08000000
46 #define EBDMA_CSR_DEV_ID_MASK 0xf0000000
47 
48 #define EBUS_DMA_RESET_TIMEOUT 10000
49 
50 static void __ebus_dma_reset(struct ebus_dma_info *p, int no_drain)
51 {
52  int i;
53  u32 val = 0;
54 
56  udelay(1);
57 
58  if (no_drain)
59  return;
60 
61  for (i = EBUS_DMA_RESET_TIMEOUT; i > 0; i--) {
62  val = readl(p->regs + EBDMA_CSR);
63 
64  if (!(val & (EBDMA_CSR_DRAIN | EBDMA_CSR_CYC_PEND)))
65  break;
66  udelay(10);
67  }
68 }
69 
70 static irqreturn_t ebus_dma_irq(int irq, void *dev_id)
71 {
72  struct ebus_dma_info *p = dev_id;
73  unsigned long flags;
74  u32 csr = 0;
75 
76  spin_lock_irqsave(&p->lock, flags);
77  csr = readl(p->regs + EBDMA_CSR);
78  writel(csr, p->regs + EBDMA_CSR);
79  spin_unlock_irqrestore(&p->lock, flags);
80 
81  if (csr & EBDMA_CSR_ERR_PEND) {
82  printk(KERN_CRIT "ebus_dma(%s): DMA error!\n", p->name);
84  return IRQ_HANDLED;
85  } else if (csr & EBDMA_CSR_INT_PEND) {
86  p->callback(p,
87  (csr & EBDMA_CSR_TC) ?
89  p->client_cookie);
90  return IRQ_HANDLED;
91  }
92 
93  return IRQ_NONE;
94 
95 }
96 
98 {
99  u32 csr;
100 
101  if (!p->regs)
102  return -EINVAL;
105  return -EINVAL;
107  return -EINVAL;
108  if (!strlen(p->name))
109  return -EINVAL;
110 
111  __ebus_dma_reset(p, 1);
112 
114 
116  csr |= EBDMA_CSR_TCI_DIS;
117 
118  writel(csr, p->regs + EBDMA_CSR);
119 
120  return 0;
121 }
123 
124 int ebus_dma_irq_enable(struct ebus_dma_info *p, int on)
125 {
126  unsigned long flags;
127  u32 csr;
128 
129  if (on) {
131  if (request_irq(p->irq, ebus_dma_irq, IRQF_SHARED, p->name, p))
132  return -EBUSY;
133  }
134 
135  spin_lock_irqsave(&p->lock, flags);
136  csr = readl(p->regs + EBDMA_CSR);
137  csr |= EBDMA_CSR_INT_EN;
138  writel(csr, p->regs + EBDMA_CSR);
139  spin_unlock_irqrestore(&p->lock, flags);
140  } else {
141  spin_lock_irqsave(&p->lock, flags);
142  csr = readl(p->regs + EBDMA_CSR);
143  csr &= ~EBDMA_CSR_INT_EN;
144  writel(csr, p->regs + EBDMA_CSR);
145  spin_unlock_irqrestore(&p->lock, flags);
146 
148  free_irq(p->irq, p);
149  }
150  }
151 
152  return 0;
153 }
155 
157 {
158  unsigned long flags;
159  u32 csr;
160  int irq_on = 0;
161 
162  spin_lock_irqsave(&p->lock, flags);
163  csr = readl(p->regs + EBDMA_CSR);
164  if (csr & EBDMA_CSR_INT_EN) {
165  csr &= ~EBDMA_CSR_INT_EN;
166  writel(csr, p->regs + EBDMA_CSR);
167  irq_on = 1;
168  }
169  spin_unlock_irqrestore(&p->lock, flags);
170 
171  if (irq_on)
172  free_irq(p->irq, p);
173 }
175 
176 int ebus_dma_request(struct ebus_dma_info *p, dma_addr_t bus_addr, size_t len)
177 {
178  unsigned long flags;
179  u32 csr;
180  int err;
181 
182  if (len >= (1 << 24))
183  return -EINVAL;
184 
185  spin_lock_irqsave(&p->lock, flags);
186  csr = readl(p->regs + EBDMA_CSR);
187  err = -EINVAL;
188  if (!(csr & EBDMA_CSR_EN_DMA))
189  goto out;
190  err = -EBUSY;
191  if (csr & EBDMA_CSR_NA_LOADED)
192  goto out;
193 
194  writel(len, p->regs + EBDMA_COUNT);
195  writel(bus_addr, p->regs + EBDMA_ADDR);
196  err = 0;
197 
198 out:
199  spin_unlock_irqrestore(&p->lock, flags);
200 
201  return err;
202 }
204 
206 {
207  unsigned long flags;
208  u32 csr;
209 
210  spin_lock_irqsave(&p->lock, flags);
211  __ebus_dma_reset(p, 0);
212 
213  csr = (EBDMA_CSR_INT_EN |
217 
218  if (write)
219  csr |= EBDMA_CSR_WRITE;
221  csr |= EBDMA_CSR_TCI_DIS;
222 
223  writel(csr, p->regs + EBDMA_CSR);
224 
225  spin_unlock_irqrestore(&p->lock, flags);
226 }
228 
229 unsigned int ebus_dma_residue(struct ebus_dma_info *p)
230 {
231  return readl(p->regs + EBDMA_COUNT);
232 }
234 
235 unsigned int ebus_dma_addr(struct ebus_dma_info *p)
236 {
237  return readl(p->regs + EBDMA_ADDR);
238 }
240 
241 void ebus_dma_enable(struct ebus_dma_info *p, int on)
242 {
243  unsigned long flags;
244  u32 orig_csr, csr;
245 
246  spin_lock_irqsave(&p->lock, flags);
247  orig_csr = csr = readl(p->regs + EBDMA_CSR);
248  if (on)
249  csr |= EBDMA_CSR_EN_DMA;
250  else
251  csr &= ~EBDMA_CSR_EN_DMA;
252  if ((orig_csr & EBDMA_CSR_EN_DMA) !=
253  (csr & EBDMA_CSR_EN_DMA))
254  writel(csr, p->regs + EBDMA_CSR);
255  spin_unlock_irqrestore(&p->lock, flags);
256 }