13 #include <linux/kernel.h>
17 #include <linux/module.h>
31 #define LPBFIFO_REG_PACKET_SIZE (0x00)
32 #define LPBFIFO_REG_START_ADDRESS (0x04)
33 #define LPBFIFO_REG_CONTROL (0x08)
34 #define LPBFIFO_REG_ENABLE (0x0C)
35 #define LPBFIFO_REG_BYTES_DONE_STATUS (0x14)
36 #define LPBFIFO_REG_FIFO_DATA (0x40)
37 #define LPBFIFO_REG_FIFO_STATUS (0x44)
38 #define LPBFIFO_REG_FIFO_CONTROL (0x48)
39 #define LPBFIFO_REG_FIFO_ALARM (0x4C)
90 if (transfer_size > 512)
114 lpbfifo.bcom_cur_task = lpbfifo.bcom_tx_task;
118 lpbfifo.bcom_cur_task = lpbfifo.bcom_rx_task;
121 if (lpbfifo.dma_irqs_enabled) {
122 disable_irq(bcom_get_task_irq(lpbfifo.bcom_rx_task));
123 lpbfifo.dma_irqs_enabled = 0;
126 if (!lpbfifo.dma_irqs_enabled) {
127 enable_irq(bcom_get_task_irq(lpbfifo.bcom_rx_task));
128 lpbfifo.dma_irqs_enabled = 1;
133 bd = bcom_prepare_next_buffer(lpbfifo.bcom_cur_task);
151 bcom_submit_next_buffer(lpbfifo.bcom_cur_task,
NULL);
154 bit_fields = 0x00000201;
157 if (write && (!poll_dma))
158 bit_fields |= 0x00000100;
167 bit_fields = req->
cs << 24 | 0x000008;
169 bit_fields |= 0x010000;
173 if (!lpbfifo.req->defer_xfer_start)
237 spin_unlock_irqrestore(&lpbfifo.lock, flags);
238 pr_err(
"bogus LPBFIFO IRQ\n");
247 spin_unlock_irqrestore(&lpbfifo.lock, flags);
248 pr_err(
"bogus LPBFIFO IRQ (dma and not writting)\n");
252 if ((status & 0x01) == 0) {
267 if (!dma && !write) {
271 for (i = 0; i <
count; i += 4)
280 mpc52xx_lpbfifo_kick(req);
288 if (dma && (status & 0x11)) {
299 bcom_retrieve_buffer(lpbfifo.bcom_cur_task, &status,
NULL);
312 spin_unlock_irqrestore(&lpbfifo.lock, flags);
326 static irqreturn_t mpc52xx_lpbfifo_bcom_irq(
int irq,
void *dev_id)
338 spin_unlock_irqrestore(&lpbfifo.lock, flags);
345 if (!bcom_buffer_done(lpbfifo.bcom_cur_task)) {
346 spin_unlock_irqrestore(&lpbfifo.lock, flags);
350 pr_err(
"transfer stalled\n");
355 bcom_retrieve_buffer(lpbfifo.bcom_cur_task, &status,
NULL);
359 req->
pos = status & 0x00ffffff;
366 spin_unlock_irqrestore(&lpbfifo.lock, flags);
387 mpc52xx_lpbfifo_irq(0,
NULL);
389 mpc52xx_lpbfifo_bcom_irq(0,
NULL);
408 spin_unlock_irqrestore(&lpbfifo.lock, flags);
419 mpc52xx_lpbfifo_kick(req);
420 spin_unlock_irqrestore(&lpbfifo.lock, flags);
438 if (lpbfifo.req && !lpbfifo.req->defer_xfer_start) {
439 spin_unlock_irqrestore(&lpbfifo.lock, flags);
447 if (lpbfifo.req && lpbfifo.req == req &&
448 lpbfifo.req->defer_xfer_start) {
452 spin_unlock_irqrestore(&lpbfifo.lock, flags);
462 if (lpbfifo.req == req) {
469 spin_unlock_irqrestore(&lpbfifo.lock, flags);
478 if (lpbfifo.dev !=
NULL)
487 lpbfifo.regs_phys =
res.start;
498 rc =
request_irq(lpbfifo.irq, mpc52xx_lpbfifo_irq, 0,
499 "mpc52xx-lpbfifo", &lpbfifo);
504 lpbfifo.bcom_rx_task =
508 if (!lpbfifo.bcom_rx_task)
511 rc =
request_irq(bcom_get_task_irq(lpbfifo.bcom_rx_task),
512 mpc52xx_lpbfifo_bcom_irq, 0,
513 "mpc52xx-lpbfifo-rx", &lpbfifo);
515 goto err_bcom_rx_irq;
517 lpbfifo.dma_irqs_enabled = 1;
520 lpbfifo.bcom_tx_task =
523 if (!lpbfifo.bcom_tx_task)
526 lpbfifo.dev = &op->
dev;
530 free_irq(bcom_get_task_irq(lpbfifo.bcom_rx_task), &lpbfifo);
538 dev_err(&op->
dev,
"mpc52xx_lpbfifo_probe() failed\n");
545 if (lpbfifo.dev != &op->
dev)
552 free_irq(bcom_get_task_irq(lpbfifo.bcom_tx_task), &lpbfifo);
556 free_irq(bcom_get_task_irq(lpbfifo.bcom_rx_task), &lpbfifo);
568 { .compatible =
"fsl,mpc5200-lpbfifo", },
574 .name =
"mpc52xx-lpbfifo",
576 .of_match_table = mpc52xx_lpbfifo_match,
578 .probe = mpc52xx_lpbfifo_probe,
585 static int __init mpc52xx_lpbfifo_init(
void)
591 static void __exit mpc52xx_lpbfifo_exit(
void)