Root/
1 | /* |
2 | * SCSI low-level driver for the 53c94 SCSI bus adaptor found |
3 | * on Power Macintosh computers, controlling the external SCSI chain. |
4 | * We assume the 53c94 is connected to a DBDMA (descriptor-based DMA) |
5 | * controller. |
6 | * |
7 | * Paul Mackerras, August 1996. |
8 | * Copyright (C) 1996 Paul Mackerras. |
9 | */ |
10 | #include <linux/kernel.h> |
11 | #include <linux/delay.h> |
12 | #include <linux/types.h> |
13 | #include <linux/string.h> |
14 | #include <linux/slab.h> |
15 | #include <linux/blkdev.h> |
16 | #include <linux/proc_fs.h> |
17 | #include <linux/stat.h> |
18 | #include <linux/spinlock.h> |
19 | #include <linux/interrupt.h> |
20 | #include <asm/dbdma.h> |
21 | #include <asm/io.h> |
22 | #include <asm/pgtable.h> |
23 | #include <asm/prom.h> |
24 | #include <asm/system.h> |
25 | #include <asm/pci-bridge.h> |
26 | #include <asm/macio.h> |
27 | |
28 | #include <scsi/scsi.h> |
29 | #include <scsi/scsi_cmnd.h> |
30 | #include <scsi/scsi_device.h> |
31 | #include <scsi/scsi_host.h> |
32 | |
33 | #include "mac53c94.h" |
34 | |
35 | enum fsc_phase { |
36 | idle, |
37 | selecting, |
38 | dataing, |
39 | completing, |
40 | busfreeing, |
41 | }; |
42 | |
43 | struct fsc_state { |
44 | struct mac53c94_regs __iomem *regs; |
45 | int intr; |
46 | struct dbdma_regs __iomem *dma; |
47 | int dmaintr; |
48 | int clk_freq; |
49 | struct Scsi_Host *host; |
50 | struct scsi_cmnd *request_q; |
51 | struct scsi_cmnd *request_qtail; |
52 | struct scsi_cmnd *current_req; /* req we're currently working on */ |
53 | enum fsc_phase phase; /* what we're currently trying to do */ |
54 | struct dbdma_cmd *dma_cmds; /* space for dbdma commands, aligned */ |
55 | void *dma_cmd_space; |
56 | struct pci_dev *pdev; |
57 | dma_addr_t dma_addr; |
58 | struct macio_dev *mdev; |
59 | }; |
60 | |
61 | static void mac53c94_init(struct fsc_state *); |
62 | static void mac53c94_start(struct fsc_state *); |
63 | static void mac53c94_interrupt(int, void *); |
64 | static irqreturn_t do_mac53c94_interrupt(int, void *); |
65 | static void cmd_done(struct fsc_state *, int result); |
66 | static void set_dma_cmds(struct fsc_state *, struct scsi_cmnd *); |
67 | |
68 | |
69 | static int mac53c94_queue(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *)) |
70 | { |
71 | struct fsc_state *state; |
72 | |
73 | #if 0 |
74 | if (cmd->sc_data_direction == DMA_TO_DEVICE) { |
75 | int i; |
76 | printk(KERN_DEBUG "mac53c94_queue %p: command is", cmd); |
77 | for (i = 0; i < cmd->cmd_len; ++i) |
78 | printk(KERN_CONT " %.2x", cmd->cmnd[i]); |
79 | printk(KERN_CONT "\n"); |
80 | printk(KERN_DEBUG "use_sg=%d request_bufflen=%d request_buffer=%p\n", |
81 | scsi_sg_count(cmd), scsi_bufflen(cmd), scsi_sglist(cmd)); |
82 | } |
83 | #endif |
84 | |
85 | cmd->scsi_done = done; |
86 | cmd->host_scribble = NULL; |
87 | |
88 | state = (struct fsc_state *) cmd->device->host->hostdata; |
89 | |
90 | if (state->request_q == NULL) |
91 | state->request_q = cmd; |
92 | else |
93 | state->request_qtail->host_scribble = (void *) cmd; |
94 | state->request_qtail = cmd; |
95 | |
96 | if (state->phase == idle) |
97 | mac53c94_start(state); |
98 | |
99 | return 0; |
100 | } |
101 | |
102 | static int mac53c94_host_reset(struct scsi_cmnd *cmd) |
103 | { |
104 | struct fsc_state *state = (struct fsc_state *) cmd->device->host->hostdata; |
105 | struct mac53c94_regs __iomem *regs = state->regs; |
106 | struct dbdma_regs __iomem *dma = state->dma; |
107 | unsigned long flags; |
108 | |
109 | spin_lock_irqsave(cmd->device->host->host_lock, flags); |
110 | |
111 | writel((RUN|PAUSE|FLUSH|WAKE) << 16, &dma->control); |
112 | writeb(CMD_SCSI_RESET, ®s->command); /* assert RST */ |
113 | udelay(100); /* leave it on for a while (>= 25us) */ |
114 | writeb(CMD_RESET, ®s->command); |
115 | udelay(20); |
116 | mac53c94_init(state); |
117 | writeb(CMD_NOP, ®s->command); |
118 | |
119 | spin_unlock_irqrestore(cmd->device->host->host_lock, flags); |
120 | return SUCCESS; |
121 | } |
122 | |
123 | static void mac53c94_init(struct fsc_state *state) |
124 | { |
125 | struct mac53c94_regs __iomem *regs = state->regs; |
126 | struct dbdma_regs __iomem *dma = state->dma; |
127 | int x; |
128 | |
129 | writeb(state->host->this_id | CF1_PAR_ENABLE, ®s->config1); |
130 | writeb(TIMO_VAL(250), ®s->sel_timeout); /* 250ms */ |
131 | writeb(CLKF_VAL(state->clk_freq), ®s->clk_factor); |
132 | writeb(CF2_FEATURE_EN, ®s->config2); |
133 | writeb(0, ®s->config3); |
134 | writeb(0, ®s->sync_period); |
135 | writeb(0, ®s->sync_offset); |
136 | x = readb(®s->interrupt); |
137 | writel((RUN|PAUSE|FLUSH|WAKE) << 16, &dma->control); |
138 | } |
139 | |
140 | /* |
141 | * Start the next command for a 53C94. |
142 | * Should be called with interrupts disabled. |
143 | */ |
144 | static void mac53c94_start(struct fsc_state *state) |
145 | { |
146 | struct scsi_cmnd *cmd; |
147 | struct mac53c94_regs __iomem *regs = state->regs; |
148 | int i; |
149 | |
150 | if (state->phase != idle || state->current_req != NULL) |
151 | panic("inappropriate mac53c94_start (state=%p)", state); |
152 | if (state->request_q == NULL) |
153 | return; |
154 | state->current_req = cmd = state->request_q; |
155 | state->request_q = (struct scsi_cmnd *) cmd->host_scribble; |
156 | |
157 | /* Off we go */ |
158 | writeb(0, ®s->count_lo); |
159 | writeb(0, ®s->count_mid); |
160 | writeb(0, ®s->count_hi); |
161 | writeb(CMD_NOP + CMD_DMA_MODE, ®s->command); |
162 | udelay(1); |
163 | writeb(CMD_FLUSH, ®s->command); |
164 | udelay(1); |
165 | writeb(cmd->device->id, ®s->dest_id); |
166 | writeb(0, ®s->sync_period); |
167 | writeb(0, ®s->sync_offset); |
168 | |
169 | /* load the command into the FIFO */ |
170 | for (i = 0; i < cmd->cmd_len; ++i) |
171 | writeb(cmd->cmnd[i], ®s->fifo); |
172 | |
173 | /* do select without ATN XXX */ |
174 | writeb(CMD_SELECT, ®s->command); |
175 | state->phase = selecting; |
176 | |
177 | set_dma_cmds(state, cmd); |
178 | } |
179 | |
180 | static irqreturn_t do_mac53c94_interrupt(int irq, void *dev_id) |
181 | { |
182 | unsigned long flags; |
183 | struct Scsi_Host *dev = ((struct fsc_state *) dev_id)->current_req->device->host; |
184 | |
185 | spin_lock_irqsave(dev->host_lock, flags); |
186 | mac53c94_interrupt(irq, dev_id); |
187 | spin_unlock_irqrestore(dev->host_lock, flags); |
188 | return IRQ_HANDLED; |
189 | } |
190 | |
191 | static void mac53c94_interrupt(int irq, void *dev_id) |
192 | { |
193 | struct fsc_state *state = (struct fsc_state *) dev_id; |
194 | struct mac53c94_regs __iomem *regs = state->regs; |
195 | struct dbdma_regs __iomem *dma = state->dma; |
196 | struct scsi_cmnd *cmd = state->current_req; |
197 | int nb, stat, seq, intr; |
198 | static int mac53c94_errors; |
199 | |
200 | /* |
201 | * Apparently, reading the interrupt register unlatches |
202 | * the status and sequence step registers. |
203 | */ |
204 | seq = readb(®s->seqstep); |
205 | stat = readb(®s->status); |
206 | intr = readb(®s->interrupt); |
207 | |
208 | #if 0 |
209 | printk(KERN_DEBUG "mac53c94_intr, intr=%x stat=%x seq=%x phase=%d\n", |
210 | intr, stat, seq, state->phase); |
211 | #endif |
212 | |
213 | if (intr & INTR_RESET) { |
214 | /* SCSI bus was reset */ |
215 | printk(KERN_INFO "external SCSI bus reset detected\n"); |
216 | writeb(CMD_NOP, ®s->command); |
217 | writel(RUN << 16, &dma->control); /* stop dma */ |
218 | cmd_done(state, DID_RESET << 16); |
219 | return; |
220 | } |
221 | if (intr & INTR_ILL_CMD) { |
222 | printk(KERN_ERR "53c94: invalid cmd, intr=%x stat=%x seq=%x phase=%d\n", |
223 | intr, stat, seq, state->phase); |
224 | cmd_done(state, DID_ERROR << 16); |
225 | return; |
226 | } |
227 | if (stat & STAT_ERROR) { |
228 | #if 0 |
229 | /* XXX these seem to be harmless? */ |
230 | printk("53c94: bad error, intr=%x stat=%x seq=%x phase=%d\n", |
231 | intr, stat, seq, state->phase); |
232 | #endif |
233 | ++mac53c94_errors; |
234 | writeb(CMD_NOP + CMD_DMA_MODE, ®s->command); |
235 | } |
236 | if (cmd == 0) { |
237 | printk(KERN_DEBUG "53c94: interrupt with no command active?\n"); |
238 | return; |
239 | } |
240 | if (stat & STAT_PARITY) { |
241 | printk(KERN_ERR "mac53c94: parity error\n"); |
242 | cmd_done(state, DID_PARITY << 16); |
243 | return; |
244 | } |
245 | switch (state->phase) { |
246 | case selecting: |
247 | if (intr & INTR_DISCONNECT) { |
248 | /* selection timed out */ |
249 | cmd_done(state, DID_BAD_TARGET << 16); |
250 | return; |
251 | } |
252 | if (intr != INTR_BUS_SERV + INTR_DONE) { |
253 | printk(KERN_DEBUG "got intr %x during selection\n", intr); |
254 | cmd_done(state, DID_ERROR << 16); |
255 | return; |
256 | } |
257 | if ((seq & SS_MASK) != SS_DONE) { |
258 | printk(KERN_DEBUG "seq step %x after command\n", seq); |
259 | cmd_done(state, DID_ERROR << 16); |
260 | return; |
261 | } |
262 | writeb(CMD_NOP, ®s->command); |
263 | /* set DMA controller going if any data to transfer */ |
264 | if ((stat & (STAT_MSG|STAT_CD)) == 0 |
265 | && (scsi_sg_count(cmd) > 0 || scsi_bufflen(cmd))) { |
266 | nb = cmd->SCp.this_residual; |
267 | if (nb > 0xfff0) |
268 | nb = 0xfff0; |
269 | cmd->SCp.this_residual -= nb; |
270 | writeb(nb, ®s->count_lo); |
271 | writeb(nb >> 8, ®s->count_mid); |
272 | writeb(CMD_DMA_MODE + CMD_NOP, ®s->command); |
273 | writel(virt_to_phys(state->dma_cmds), &dma->cmdptr); |
274 | writel((RUN << 16) | RUN, &dma->control); |
275 | writeb(CMD_DMA_MODE + CMD_XFER_DATA, ®s->command); |
276 | state->phase = dataing; |
277 | break; |
278 | } else if ((stat & STAT_PHASE) == STAT_CD + STAT_IO) { |
279 | /* up to status phase already */ |
280 | writeb(CMD_I_COMPLETE, ®s->command); |
281 | state->phase = completing; |
282 | } else { |
283 | printk(KERN_DEBUG "in unexpected phase %x after cmd\n", |
284 | stat & STAT_PHASE); |
285 | cmd_done(state, DID_ERROR << 16); |
286 | return; |
287 | } |
288 | break; |
289 | |
290 | case dataing: |
291 | if (intr != INTR_BUS_SERV) { |
292 | printk(KERN_DEBUG "got intr %x before status\n", intr); |
293 | cmd_done(state, DID_ERROR << 16); |
294 | return; |
295 | } |
296 | if (cmd->SCp.this_residual != 0 |
297 | && (stat & (STAT_MSG|STAT_CD)) == 0) { |
298 | /* Set up the count regs to transfer more */ |
299 | nb = cmd->SCp.this_residual; |
300 | if (nb > 0xfff0) |
301 | nb = 0xfff0; |
302 | cmd->SCp.this_residual -= nb; |
303 | writeb(nb, ®s->count_lo); |
304 | writeb(nb >> 8, ®s->count_mid); |
305 | writeb(CMD_DMA_MODE + CMD_NOP, ®s->command); |
306 | writeb(CMD_DMA_MODE + CMD_XFER_DATA, ®s->command); |
307 | break; |
308 | } |
309 | if ((stat & STAT_PHASE) != STAT_CD + STAT_IO) { |
310 | printk(KERN_DEBUG "intr %x before data xfer complete\n", intr); |
311 | } |
312 | writel(RUN << 16, &dma->control); /* stop dma */ |
313 | scsi_dma_unmap(cmd); |
314 | /* should check dma status */ |
315 | writeb(CMD_I_COMPLETE, ®s->command); |
316 | state->phase = completing; |
317 | break; |
318 | case completing: |
319 | if (intr != INTR_DONE) { |
320 | printk(KERN_DEBUG "got intr %x on completion\n", intr); |
321 | cmd_done(state, DID_ERROR << 16); |
322 | return; |
323 | } |
324 | cmd->SCp.Status = readb(®s->fifo); |
325 | cmd->SCp.Message = readb(®s->fifo); |
326 | cmd->result = CMD_ACCEPT_MSG; |
327 | writeb(CMD_ACCEPT_MSG, ®s->command); |
328 | state->phase = busfreeing; |
329 | break; |
330 | case busfreeing: |
331 | if (intr != INTR_DISCONNECT) { |
332 | printk(KERN_DEBUG "got intr %x when expected disconnect\n", intr); |
333 | } |
334 | cmd_done(state, (DID_OK << 16) + (cmd->SCp.Message << 8) |
335 | + cmd->SCp.Status); |
336 | break; |
337 | default: |
338 | printk(KERN_DEBUG "don't know about phase %d\n", state->phase); |
339 | } |
340 | } |
341 | |
342 | static void cmd_done(struct fsc_state *state, int result) |
343 | { |
344 | struct scsi_cmnd *cmd; |
345 | |
346 | cmd = state->current_req; |
347 | if (cmd != 0) { |
348 | cmd->result = result; |
349 | (*cmd->scsi_done)(cmd); |
350 | state->current_req = NULL; |
351 | } |
352 | state->phase = idle; |
353 | mac53c94_start(state); |
354 | } |
355 | |
356 | /* |
357 | * Set up DMA commands for transferring data. |
358 | */ |
359 | static void set_dma_cmds(struct fsc_state *state, struct scsi_cmnd *cmd) |
360 | { |
361 | int i, dma_cmd, total, nseg; |
362 | struct scatterlist *scl; |
363 | struct dbdma_cmd *dcmds; |
364 | dma_addr_t dma_addr; |
365 | u32 dma_len; |
366 | |
367 | nseg = scsi_dma_map(cmd); |
368 | BUG_ON(nseg < 0); |
369 | if (!nseg) |
370 | return; |
371 | |
372 | dma_cmd = cmd->sc_data_direction == DMA_TO_DEVICE ? |
373 | OUTPUT_MORE : INPUT_MORE; |
374 | dcmds = state->dma_cmds; |
375 | total = 0; |
376 | |
377 | scsi_for_each_sg(cmd, scl, nseg, i) { |
378 | dma_addr = sg_dma_address(scl); |
379 | dma_len = sg_dma_len(scl); |
380 | if (dma_len > 0xffff) |
381 | panic("mac53c94: scatterlist element >= 64k"); |
382 | total += dma_len; |
383 | st_le16(&dcmds->req_count, dma_len); |
384 | st_le16(&dcmds->command, dma_cmd); |
385 | st_le32(&dcmds->phy_addr, dma_addr); |
386 | dcmds->xfer_status = 0; |
387 | ++dcmds; |
388 | } |
389 | |
390 | dma_cmd += OUTPUT_LAST - OUTPUT_MORE; |
391 | st_le16(&dcmds[-1].command, dma_cmd); |
392 | st_le16(&dcmds->command, DBDMA_STOP); |
393 | cmd->SCp.this_residual = total; |
394 | } |
395 | |
396 | static struct scsi_host_template mac53c94_template = { |
397 | .proc_name = "53c94", |
398 | .name = "53C94", |
399 | .queuecommand = mac53c94_queue, |
400 | .eh_host_reset_handler = mac53c94_host_reset, |
401 | .can_queue = 1, |
402 | .this_id = 7, |
403 | .sg_tablesize = SG_ALL, |
404 | .cmd_per_lun = 1, |
405 | .use_clustering = DISABLE_CLUSTERING, |
406 | }; |
407 | |
408 | static int mac53c94_probe(struct macio_dev *mdev, const struct of_device_id *match) |
409 | { |
410 | struct device_node *node = macio_get_of_node(mdev); |
411 | struct pci_dev *pdev = macio_get_pci_dev(mdev); |
412 | struct fsc_state *state; |
413 | struct Scsi_Host *host; |
414 | void *dma_cmd_space; |
415 | const unsigned char *clkprop; |
416 | int proplen, rc = -ENODEV; |
417 | |
418 | if (macio_resource_count(mdev) != 2 || macio_irq_count(mdev) != 2) { |
419 | printk(KERN_ERR "mac53c94: expected 2 addrs and intrs" |
420 | " (got %d/%d)\n", |
421 | macio_resource_count(mdev), macio_irq_count(mdev)); |
422 | return -ENODEV; |
423 | } |
424 | |
425 | if (macio_request_resources(mdev, "mac53c94") != 0) { |
426 | printk(KERN_ERR "mac53c94: unable to request memory resources"); |
427 | return -EBUSY; |
428 | } |
429 | |
430 | host = scsi_host_alloc(&mac53c94_template, sizeof(struct fsc_state)); |
431 | if (host == NULL) { |
432 | printk(KERN_ERR "mac53c94: couldn't register host"); |
433 | rc = -ENOMEM; |
434 | goto out_release; |
435 | } |
436 | |
437 | state = (struct fsc_state *) host->hostdata; |
438 | macio_set_drvdata(mdev, state); |
439 | state->host = host; |
440 | state->pdev = pdev; |
441 | state->mdev = mdev; |
442 | |
443 | state->regs = (struct mac53c94_regs __iomem *) |
444 | ioremap(macio_resource_start(mdev, 0), 0x1000); |
445 | state->intr = macio_irq(mdev, 0); |
446 | state->dma = (struct dbdma_regs __iomem *) |
447 | ioremap(macio_resource_start(mdev, 1), 0x1000); |
448 | state->dmaintr = macio_irq(mdev, 1); |
449 | if (state->regs == NULL || state->dma == NULL) { |
450 | printk(KERN_ERR "mac53c94: ioremap failed for %s\n", |
451 | node->full_name); |
452 | goto out_free; |
453 | } |
454 | |
455 | clkprop = of_get_property(node, "clock-frequency", &proplen); |
456 | if (clkprop == NULL || proplen != sizeof(int)) { |
457 | printk(KERN_ERR "%s: can't get clock frequency, " |
458 | "assuming 25MHz\n", node->full_name); |
459 | state->clk_freq = 25000000; |
460 | } else |
461 | state->clk_freq = *(int *)clkprop; |
462 | |
463 | /* Space for dma command list: +1 for stop command, |
464 | * +1 to allow for aligning. |
465 | * XXX FIXME: Use DMA consistent routines |
466 | */ |
467 | dma_cmd_space = kmalloc((host->sg_tablesize + 2) * |
468 | sizeof(struct dbdma_cmd), GFP_KERNEL); |
469 | if (dma_cmd_space == 0) { |
470 | printk(KERN_ERR "mac53c94: couldn't allocate dma " |
471 | "command space for %s\n", node->full_name); |
472 | rc = -ENOMEM; |
473 | goto out_free; |
474 | } |
475 | state->dma_cmds = (struct dbdma_cmd *)DBDMA_ALIGN(dma_cmd_space); |
476 | memset(state->dma_cmds, 0, (host->sg_tablesize + 1) |
477 | * sizeof(struct dbdma_cmd)); |
478 | state->dma_cmd_space = dma_cmd_space; |
479 | |
480 | mac53c94_init(state); |
481 | |
482 | if (request_irq(state->intr, do_mac53c94_interrupt, 0, "53C94",state)) { |
483 | printk(KERN_ERR "mac53C94: can't get irq %d for %s\n", |
484 | state->intr, node->full_name); |
485 | goto out_free_dma; |
486 | } |
487 | |
488 | rc = scsi_add_host(host, &mdev->ofdev.dev); |
489 | if (rc != 0) |
490 | goto out_release_irq; |
491 | |
492 | scsi_scan_host(host); |
493 | return 0; |
494 | |
495 | out_release_irq: |
496 | free_irq(state->intr, state); |
497 | out_free_dma: |
498 | kfree(state->dma_cmd_space); |
499 | out_free: |
500 | if (state->dma != NULL) |
501 | iounmap(state->dma); |
502 | if (state->regs != NULL) |
503 | iounmap(state->regs); |
504 | scsi_host_put(host); |
505 | out_release: |
506 | macio_release_resources(mdev); |
507 | |
508 | return rc; |
509 | } |
510 | |
511 | static int mac53c94_remove(struct macio_dev *mdev) |
512 | { |
513 | struct fsc_state *fp = (struct fsc_state *)macio_get_drvdata(mdev); |
514 | struct Scsi_Host *host = fp->host; |
515 | |
516 | scsi_remove_host(host); |
517 | |
518 | free_irq(fp->intr, fp); |
519 | |
520 | if (fp->regs) |
521 | iounmap(fp->regs); |
522 | if (fp->dma) |
523 | iounmap(fp->dma); |
524 | kfree(fp->dma_cmd_space); |
525 | |
526 | scsi_host_put(host); |
527 | |
528 | macio_release_resources(mdev); |
529 | |
530 | return 0; |
531 | } |
532 | |
533 | |
534 | static struct of_device_id mac53c94_match[] = |
535 | { |
536 | { |
537 | .name = "53c94", |
538 | }, |
539 | {}, |
540 | }; |
541 | MODULE_DEVICE_TABLE (of, mac53c94_match); |
542 | |
543 | static struct macio_driver mac53c94_driver = |
544 | { |
545 | .name = "mac53c94", |
546 | .match_table = mac53c94_match, |
547 | .probe = mac53c94_probe, |
548 | .remove = mac53c94_remove, |
549 | }; |
550 | |
551 | |
552 | static int __init init_mac53c94(void) |
553 | { |
554 | return macio_register_driver(&mac53c94_driver); |
555 | } |
556 | |
557 | static void __exit exit_mac53c94(void) |
558 | { |
559 | return macio_unregister_driver(&mac53c94_driver); |
560 | } |
561 | |
562 | module_init(init_mac53c94); |
563 | module_exit(exit_mac53c94); |
564 | |
565 | MODULE_DESCRIPTION("PowerMac 53c94 SCSI driver"); |
566 | MODULE_AUTHOR("Paul Mackerras <paulus@samba.org>"); |
567 | MODULE_LICENSE("GPL"); |
568 |
Branches:
ben-wpan
ben-wpan-stefan
javiroman/ks7010
jz-2.6.34
jz-2.6.34-rc5
jz-2.6.34-rc6
jz-2.6.34-rc7
jz-2.6.35
jz-2.6.36
jz-2.6.37
jz-2.6.38
jz-2.6.39
jz-3.0
jz-3.1
jz-3.11
jz-3.12
jz-3.13
jz-3.15
jz-3.16
jz-3.18-dt
jz-3.2
jz-3.3
jz-3.4
jz-3.5
jz-3.6
jz-3.6-rc2-pwm
jz-3.9
jz-3.9-clk
jz-3.9-rc8
jz47xx
jz47xx-2.6.38
master
Tags:
od-2011-09-04
od-2011-09-18
v2.6.34-rc5
v2.6.34-rc6
v2.6.34-rc7
v3.9