Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * LocalPlus Bus FIFO driver for the Freescale MPC52xx.
0004  *
0005  * Copyright (C) 2009 Secret Lab Technologies Ltd.
0006  *
0007  * Todo:
0008  * - Add support for multiple requests to be queued.
0009  */
0010 
0011 #include <linux/interrupt.h>
0012 #include <linux/kernel.h>
0013 #include <linux/of.h>
0014 #include <linux/of_address.h>
0015 #include <linux/of_irq.h>
0016 #include <linux/of_platform.h>
0017 #include <linux/spinlock.h>
0018 #include <linux/module.h>
0019 #include <asm/io.h>
0020 #include <asm/mpc52xx.h>
0021 #include <asm/time.h>
0022 
0023 #include <linux/fsl/bestcomm/bestcomm.h>
0024 #include <linux/fsl/bestcomm/bestcomm_priv.h>
0025 #include <linux/fsl/bestcomm/gen_bd.h>
0026 
0027 MODULE_AUTHOR("Grant Likely <grant.likely@secretlab.ca>");
0028 MODULE_DESCRIPTION("MPC5200 LocalPlus FIFO device driver");
0029 MODULE_LICENSE("GPL");
0030 
0031 #define LPBFIFO_REG_PACKET_SIZE     (0x00)
0032 #define LPBFIFO_REG_START_ADDRESS   (0x04)
0033 #define LPBFIFO_REG_CONTROL     (0x08)
0034 #define LPBFIFO_REG_ENABLE      (0x0C)
0035 #define LPBFIFO_REG_BYTES_DONE_STATUS   (0x14)
0036 #define LPBFIFO_REG_FIFO_DATA       (0x40)
0037 #define LPBFIFO_REG_FIFO_STATUS     (0x44)
0038 #define LPBFIFO_REG_FIFO_CONTROL    (0x48)
0039 #define LPBFIFO_REG_FIFO_ALARM      (0x4C)
0040 
0041 struct mpc52xx_lpbfifo {
0042     struct device *dev;
0043     phys_addr_t regs_phys;
0044     void __iomem *regs;
0045     int irq;
0046     spinlock_t lock;
0047 
0048     struct bcom_task *bcom_tx_task;
0049     struct bcom_task *bcom_rx_task;
0050     struct bcom_task *bcom_cur_task;
0051 
0052     /* Current state data */
0053     struct mpc52xx_lpbfifo_request *req;
0054     int dma_irqs_enabled;
0055 };
0056 
0057 /* The MPC5200 has only one fifo, so only need one instance structure */
0058 static struct mpc52xx_lpbfifo lpbfifo;
0059 
0060 /**
0061  * mpc52xx_lpbfifo_kick - Trigger the next block of data to be transferred
0062  */
0063 static void mpc52xx_lpbfifo_kick(struct mpc52xx_lpbfifo_request *req)
0064 {
0065     size_t transfer_size = req->size - req->pos;
0066     struct bcom_bd *bd;
0067     void __iomem *reg;
0068     u32 *data;
0069     int i;
0070     int bit_fields;
0071     int dma = !(req->flags & MPC52XX_LPBFIFO_FLAG_NO_DMA);
0072     int write = req->flags & MPC52XX_LPBFIFO_FLAG_WRITE;
0073     int poll_dma = req->flags & MPC52XX_LPBFIFO_FLAG_POLL_DMA;
0074 
0075     /* Set and clear the reset bits; is good practice in User Manual */
0076     out_be32(lpbfifo.regs + LPBFIFO_REG_ENABLE, 0x01010000);
0077 
0078     /* set master enable bit */
0079     out_be32(lpbfifo.regs + LPBFIFO_REG_ENABLE, 0x00000001);
0080     if (!dma) {
0081         /* While the FIFO can be setup for transfer sizes as large as
0082          * 16M-1, the FIFO itself is only 512 bytes deep and it does
0083          * not generate interrupts for FIFO full events (only transfer
0084          * complete will raise an IRQ).  Therefore when not using
0085          * Bestcomm to drive the FIFO it needs to either be polled, or
0086          * transfers need to constrained to the size of the fifo.
0087          *
0088          * This driver restricts the size of the transfer
0089          */
0090         if (transfer_size > 512)
0091             transfer_size = 512;
0092 
0093         /* Load the FIFO with data */
0094         if (write) {
0095             reg = lpbfifo.regs + LPBFIFO_REG_FIFO_DATA;
0096             data = req->data + req->pos;
0097             for (i = 0; i < transfer_size; i += 4)
0098                 out_be32(reg, *data++);
0099         }
0100 
0101         /* Unmask both error and completion irqs */
0102         out_be32(lpbfifo.regs + LPBFIFO_REG_ENABLE, 0x00000301);
0103     } else {
0104         /* Choose the correct direction
0105          *
0106          * Configure the watermarks so DMA will always complete correctly.
0107          * It may be worth experimenting with the ALARM value to see if
0108          * there is a performance impact.  However, if it is wrong there
0109          * is a risk of DMA not transferring the last chunk of data
0110          */
0111         if (write) {
0112             out_be32(lpbfifo.regs + LPBFIFO_REG_FIFO_ALARM, 0x1e4);
0113             out_8(lpbfifo.regs + LPBFIFO_REG_FIFO_CONTROL, 7);
0114             lpbfifo.bcom_cur_task = lpbfifo.bcom_tx_task;
0115         } else {
0116             out_be32(lpbfifo.regs + LPBFIFO_REG_FIFO_ALARM, 0x1ff);
0117             out_8(lpbfifo.regs + LPBFIFO_REG_FIFO_CONTROL, 0);
0118             lpbfifo.bcom_cur_task = lpbfifo.bcom_rx_task;
0119 
0120             if (poll_dma) {
0121                 if (lpbfifo.dma_irqs_enabled) {
0122                     disable_irq(bcom_get_task_irq(lpbfifo.bcom_rx_task));
0123                     lpbfifo.dma_irqs_enabled = 0;
0124                 }
0125             } else {
0126                 if (!lpbfifo.dma_irqs_enabled) {
0127                     enable_irq(bcom_get_task_irq(lpbfifo.bcom_rx_task));
0128                     lpbfifo.dma_irqs_enabled = 1;
0129                 }
0130             }
0131         }
0132 
0133         bd = bcom_prepare_next_buffer(lpbfifo.bcom_cur_task);
0134         bd->status = transfer_size;
0135         if (!write) {
0136             /*
0137              * In the DMA read case, the DMA doesn't complete,
0138              * possibly due to incorrect watermarks in the ALARM
0139              * and CONTROL regs. For now instead of trying to
0140              * determine the right watermarks that will make this
0141              * work, just increase the number of bytes the FIFO is
0142              * expecting.
0143              *
0144              * When submitting another operation, the FIFO will get
0145              * reset, so the condition of the FIFO waiting for a
0146              * non-existent 4 bytes will get cleared.
0147              */
0148             transfer_size += 4; /* BLECH! */
0149         }
0150         bd->data[0] = req->data_phys + req->pos;
0151         bcom_submit_next_buffer(lpbfifo.bcom_cur_task, NULL);
0152 
0153         /* error irq & master enabled bit */
0154         bit_fields = 0x00000201;
0155 
0156         /* Unmask irqs */
0157         if (write && (!poll_dma))
0158             bit_fields |= 0x00000100; /* completion irq too */
0159         out_be32(lpbfifo.regs + LPBFIFO_REG_ENABLE, bit_fields);
0160     }
0161 
0162     /* Set transfer size, width, chip select and READ mode */
0163     out_be32(lpbfifo.regs + LPBFIFO_REG_START_ADDRESS,
0164          req->offset + req->pos);
0165     out_be32(lpbfifo.regs + LPBFIFO_REG_PACKET_SIZE, transfer_size);
0166 
0167     bit_fields = req->cs << 24 | 0x000008;
0168     if (!write)
0169         bit_fields |= 0x010000; /* read mode */
0170     out_be32(lpbfifo.regs + LPBFIFO_REG_CONTROL, bit_fields);
0171 
0172     /* Kick it off */
0173     if (!lpbfifo.req->defer_xfer_start)
0174         out_8(lpbfifo.regs + LPBFIFO_REG_PACKET_SIZE, 0x01);
0175     if (dma)
0176         bcom_enable(lpbfifo.bcom_cur_task);
0177 }
0178 
0179 /**
0180  * mpc52xx_lpbfifo_irq - IRQ handler for LPB FIFO
0181  *
0182  * On transmit, the dma completion irq triggers before the fifo completion
0183  * triggers.  Handle the dma completion here instead of the LPB FIFO Bestcomm
0184  * task completion irq because everything is not really done until the LPB FIFO
0185  * completion irq triggers.
0186  *
0187  * In other words:
0188  * For DMA, on receive, the "Fat Lady" is the bestcom completion irq. on
0189  * transmit, the fifo completion irq is the "Fat Lady". The opera (or in this
0190  * case the DMA/FIFO operation) is not finished until the "Fat Lady" sings.
0191  *
0192  * Reasons for entering this routine:
0193  * 1) PIO mode rx and tx completion irq
0194  * 2) DMA interrupt mode tx completion irq
0195  * 3) DMA polled mode tx
0196  *
0197  * Exit conditions:
0198  * 1) Transfer aborted
0199  * 2) FIFO complete without DMA; more data to do
0200  * 3) FIFO complete without DMA; all data transferred
0201  * 4) FIFO complete using DMA
0202  *
0203  * Condition 1 can occur regardless of whether or not DMA is used.
0204  * It requires executing the callback to report the error and exiting
0205  * immediately.
0206  *
0207  * Condition 2 requires programming the FIFO with the next block of data
0208  *
0209  * Condition 3 requires executing the callback to report completion
0210  *
0211  * Condition 4 means the same as 3, except that we also retrieve the bcom
0212  * buffer so DMA doesn't get clogged up.
0213  *
0214  * To make things trickier, the spinlock must be dropped before
0215  * executing the callback, otherwise we could end up with a deadlock
0216  * or nested spinlock condition.  The out path is non-trivial, so
0217  * extra fiddling is done to make sure all paths lead to the same
0218  * outbound code.
0219  */
0220 static irqreturn_t mpc52xx_lpbfifo_irq(int irq, void *dev_id)
0221 {
0222     struct mpc52xx_lpbfifo_request *req;
0223     u32 status = in_8(lpbfifo.regs + LPBFIFO_REG_BYTES_DONE_STATUS);
0224     void __iomem *reg;
0225     u32 *data;
0226     int count, i;
0227     int do_callback = 0;
0228     u32 ts;
0229     unsigned long flags;
0230     int dma, write, poll_dma;
0231 
0232     spin_lock_irqsave(&lpbfifo.lock, flags);
0233     ts = mftb();
0234 
0235     req = lpbfifo.req;
0236     if (!req) {
0237         spin_unlock_irqrestore(&lpbfifo.lock, flags);
0238         pr_err("bogus LPBFIFO IRQ\n");
0239         return IRQ_HANDLED;
0240     }
0241 
0242     dma = !(req->flags & MPC52XX_LPBFIFO_FLAG_NO_DMA);
0243     write = req->flags & MPC52XX_LPBFIFO_FLAG_WRITE;
0244     poll_dma = req->flags & MPC52XX_LPBFIFO_FLAG_POLL_DMA;
0245 
0246     if (dma && !write) {
0247         spin_unlock_irqrestore(&lpbfifo.lock, flags);
0248         pr_err("bogus LPBFIFO IRQ (dma and not writing)\n");
0249         return IRQ_HANDLED;
0250     }
0251 
0252     if ((status & 0x01) == 0) {
0253         goto out;
0254     }
0255 
0256     /* check abort bit */
0257     if (status & 0x10) {
0258         out_be32(lpbfifo.regs + LPBFIFO_REG_ENABLE, 0x01010000);
0259         do_callback = 1;
0260         goto out;
0261     }
0262 
0263     /* Read result from hardware */
0264     count = in_be32(lpbfifo.regs + LPBFIFO_REG_BYTES_DONE_STATUS);
0265     count &= 0x00ffffff;
0266 
0267     if (!dma && !write) {
0268         /* copy the data out of the FIFO */
0269         reg = lpbfifo.regs + LPBFIFO_REG_FIFO_DATA;
0270         data = req->data + req->pos;
0271         for (i = 0; i < count; i += 4)
0272             *data++ = in_be32(reg);
0273     }
0274 
0275     /* Update transfer position and count */
0276     req->pos += count;
0277 
0278     /* Decide what to do next */
0279     if (req->size - req->pos)
0280         mpc52xx_lpbfifo_kick(req); /* more work to do */
0281     else
0282         do_callback = 1;
0283 
0284  out:
0285     /* Clear the IRQ */
0286     out_8(lpbfifo.regs + LPBFIFO_REG_BYTES_DONE_STATUS, 0x01);
0287 
0288     if (dma && (status & 0x11)) {
0289         /*
0290          * Count the DMA as complete only when the FIFO completion
0291          * status or abort bits are set.
0292          *
0293          * (status & 0x01) should always be the case except sometimes
0294          * when using polled DMA.
0295          *
0296          * (status & 0x10) {transfer aborted}: This case needs more
0297          * testing.
0298          */
0299         bcom_retrieve_buffer(lpbfifo.bcom_cur_task, &status, NULL);
0300     }
0301     req->last_byte = ((u8 *)req->data)[req->size - 1];
0302 
0303     /* When the do_callback flag is set; it means the transfer is finished
0304      * so set the FIFO as idle */
0305     if (do_callback)
0306         lpbfifo.req = NULL;
0307 
0308     if (irq != 0) /* don't increment on polled case */
0309         req->irq_count++;
0310 
0311     req->irq_ticks += mftb() - ts;
0312     spin_unlock_irqrestore(&lpbfifo.lock, flags);
0313 
0314     /* Spinlock is released; it is now safe to call the callback */
0315     if (do_callback && req->callback)
0316         req->callback(req);
0317 
0318     return IRQ_HANDLED;
0319 }
0320 
0321 /**
0322  * mpc52xx_lpbfifo_bcom_irq - IRQ handler for LPB FIFO Bestcomm task
0323  *
0324  * Only used when receiving data.
0325  */
0326 static irqreturn_t mpc52xx_lpbfifo_bcom_irq(int irq, void *dev_id)
0327 {
0328     struct mpc52xx_lpbfifo_request *req;
0329     unsigned long flags;
0330     u32 status;
0331     u32 ts;
0332 
0333     spin_lock_irqsave(&lpbfifo.lock, flags);
0334     ts = mftb();
0335 
0336     req = lpbfifo.req;
0337     if (!req || (req->flags & MPC52XX_LPBFIFO_FLAG_NO_DMA)) {
0338         spin_unlock_irqrestore(&lpbfifo.lock, flags);
0339         return IRQ_HANDLED;
0340     }
0341 
0342     if (irq != 0) /* don't increment on polled case */
0343         req->irq_count++;
0344 
0345     if (!bcom_buffer_done(lpbfifo.bcom_cur_task)) {
0346         spin_unlock_irqrestore(&lpbfifo.lock, flags);
0347 
0348         req->buffer_not_done_cnt++;
0349         if ((req->buffer_not_done_cnt % 1000) == 0)
0350             pr_err("transfer stalled\n");
0351 
0352         return IRQ_HANDLED;
0353     }
0354 
0355     bcom_retrieve_buffer(lpbfifo.bcom_cur_task, &status, NULL);
0356 
0357     req->last_byte = ((u8 *)req->data)[req->size - 1];
0358 
0359     req->pos = status & 0x00ffffff;
0360 
0361     /* Mark the FIFO as idle */
0362     lpbfifo.req = NULL;
0363 
0364     /* Release the lock before calling out to the callback. */
0365     req->irq_ticks += mftb() - ts;
0366     spin_unlock_irqrestore(&lpbfifo.lock, flags);
0367 
0368     if (req->callback)
0369         req->callback(req);
0370 
0371     return IRQ_HANDLED;
0372 }
0373 
0374 /**
0375  * mpc52xx_lpbfifo_bcom_poll - Poll for DMA completion
0376  */
0377 void mpc52xx_lpbfifo_poll(void)
0378 {
0379     struct mpc52xx_lpbfifo_request *req = lpbfifo.req;
0380     int dma = !(req->flags & MPC52XX_LPBFIFO_FLAG_NO_DMA);
0381     int write = req->flags & MPC52XX_LPBFIFO_FLAG_WRITE;
0382 
0383     /*
0384      * For more information, see comments on the "Fat Lady" 
0385      */
0386     if (dma && write)
0387         mpc52xx_lpbfifo_irq(0, NULL);
0388     else 
0389         mpc52xx_lpbfifo_bcom_irq(0, NULL);
0390 }
0391 EXPORT_SYMBOL(mpc52xx_lpbfifo_poll);
0392 
0393 /**
0394  * mpc52xx_lpbfifo_submit - Submit an LPB FIFO transfer request.
0395  * @req: Pointer to request structure
0396  */
0397 int mpc52xx_lpbfifo_submit(struct mpc52xx_lpbfifo_request *req)
0398 {
0399     unsigned long flags;
0400 
0401     if (!lpbfifo.regs)
0402         return -ENODEV;
0403 
0404     spin_lock_irqsave(&lpbfifo.lock, flags);
0405 
0406     /* If the req pointer is already set, then a transfer is in progress */
0407     if (lpbfifo.req) {
0408         spin_unlock_irqrestore(&lpbfifo.lock, flags);
0409         return -EBUSY;
0410     }
0411 
0412     /* Setup the transfer */
0413     lpbfifo.req = req;
0414     req->irq_count = 0;
0415     req->irq_ticks = 0;
0416     req->buffer_not_done_cnt = 0;
0417     req->pos = 0;
0418 
0419     mpc52xx_lpbfifo_kick(req);
0420     spin_unlock_irqrestore(&lpbfifo.lock, flags);
0421     return 0;
0422 }
0423 EXPORT_SYMBOL(mpc52xx_lpbfifo_submit);
0424 
0425 int mpc52xx_lpbfifo_start_xfer(struct mpc52xx_lpbfifo_request *req)
0426 {
0427     unsigned long flags;
0428 
0429     if (!lpbfifo.regs)
0430         return -ENODEV;
0431 
0432     spin_lock_irqsave(&lpbfifo.lock, flags);
0433 
0434     /*
0435      * If the req pointer is already set and a transfer was
0436      * started on submit, then this transfer is in progress
0437      */
0438     if (lpbfifo.req && !lpbfifo.req->defer_xfer_start) {
0439         spin_unlock_irqrestore(&lpbfifo.lock, flags);
0440         return -EBUSY;
0441     }
0442 
0443     /*
0444      * If the req was previously submitted but not
0445      * started, start it now
0446      */
0447     if (lpbfifo.req && lpbfifo.req == req &&
0448         lpbfifo.req->defer_xfer_start) {
0449         out_8(lpbfifo.regs + LPBFIFO_REG_PACKET_SIZE, 0x01);
0450     }
0451 
0452     spin_unlock_irqrestore(&lpbfifo.lock, flags);
0453     return 0;
0454 }
0455 EXPORT_SYMBOL(mpc52xx_lpbfifo_start_xfer);
0456 
0457 void mpc52xx_lpbfifo_abort(struct mpc52xx_lpbfifo_request *req)
0458 {
0459     unsigned long flags;
0460 
0461     spin_lock_irqsave(&lpbfifo.lock, flags);
0462     if (lpbfifo.req == req) {
0463         /* Put it into reset and clear the state */
0464         bcom_gen_bd_rx_reset(lpbfifo.bcom_rx_task);
0465         bcom_gen_bd_tx_reset(lpbfifo.bcom_tx_task);
0466         out_be32(lpbfifo.regs + LPBFIFO_REG_ENABLE, 0x01010000);
0467         lpbfifo.req = NULL;
0468     }
0469     spin_unlock_irqrestore(&lpbfifo.lock, flags);
0470 }
0471 EXPORT_SYMBOL(mpc52xx_lpbfifo_abort);
0472 
0473 static int mpc52xx_lpbfifo_probe(struct platform_device *op)
0474 {
0475     struct resource res;
0476     int rc = -ENOMEM;
0477 
0478     if (lpbfifo.dev != NULL)
0479         return -ENOSPC;
0480 
0481     lpbfifo.irq = irq_of_parse_and_map(op->dev.of_node, 0);
0482     if (!lpbfifo.irq)
0483         return -ENODEV;
0484 
0485     if (of_address_to_resource(op->dev.of_node, 0, &res))
0486         return -ENODEV;
0487     lpbfifo.regs_phys = res.start;
0488     lpbfifo.regs = of_iomap(op->dev.of_node, 0);
0489     if (!lpbfifo.regs)
0490         return -ENOMEM;
0491 
0492     spin_lock_init(&lpbfifo.lock);
0493 
0494     /* Put FIFO into reset */
0495     out_be32(lpbfifo.regs + LPBFIFO_REG_ENABLE, 0x01010000);
0496 
0497     /* Register the interrupt handler */
0498     rc = request_irq(lpbfifo.irq, mpc52xx_lpbfifo_irq, 0,
0499              "mpc52xx-lpbfifo", &lpbfifo);
0500     if (rc)
0501         goto err_irq;
0502 
0503     /* Request the Bestcomm receive (fifo --> memory) task and IRQ */
0504     lpbfifo.bcom_rx_task =
0505         bcom_gen_bd_rx_init(2, res.start + LPBFIFO_REG_FIFO_DATA,
0506                     BCOM_INITIATOR_SCLPC, BCOM_IPR_SCLPC,
0507                     16*1024*1024);
0508     if (!lpbfifo.bcom_rx_task)
0509         goto err_bcom_rx;
0510 
0511     rc = request_irq(bcom_get_task_irq(lpbfifo.bcom_rx_task),
0512              mpc52xx_lpbfifo_bcom_irq, 0,
0513              "mpc52xx-lpbfifo-rx", &lpbfifo);
0514     if (rc)
0515         goto err_bcom_rx_irq;
0516 
0517     lpbfifo.dma_irqs_enabled = 1;
0518 
0519     /* Request the Bestcomm transmit (memory --> fifo) task and IRQ */
0520     lpbfifo.bcom_tx_task =
0521         bcom_gen_bd_tx_init(2, res.start + LPBFIFO_REG_FIFO_DATA,
0522                     BCOM_INITIATOR_SCLPC, BCOM_IPR_SCLPC);
0523     if (!lpbfifo.bcom_tx_task)
0524         goto err_bcom_tx;
0525 
0526     lpbfifo.dev = &op->dev;
0527     return 0;
0528 
0529  err_bcom_tx:
0530     free_irq(bcom_get_task_irq(lpbfifo.bcom_rx_task), &lpbfifo);
0531  err_bcom_rx_irq:
0532     bcom_gen_bd_rx_release(lpbfifo.bcom_rx_task);
0533  err_bcom_rx:
0534  err_irq:
0535     iounmap(lpbfifo.regs);
0536     lpbfifo.regs = NULL;
0537 
0538     dev_err(&op->dev, "mpc52xx_lpbfifo_probe() failed\n");
0539     return -ENODEV;
0540 }
0541 
0542 
0543 static int mpc52xx_lpbfifo_remove(struct platform_device *op)
0544 {
0545     if (lpbfifo.dev != &op->dev)
0546         return 0;
0547 
0548     /* Put FIFO in reset */
0549     out_be32(lpbfifo.regs + LPBFIFO_REG_ENABLE, 0x01010000);
0550 
0551     /* Release the bestcomm transmit task */
0552     free_irq(bcom_get_task_irq(lpbfifo.bcom_tx_task), &lpbfifo);
0553     bcom_gen_bd_tx_release(lpbfifo.bcom_tx_task);
0554     
0555     /* Release the bestcomm receive task */
0556     free_irq(bcom_get_task_irq(lpbfifo.bcom_rx_task), &lpbfifo);
0557     bcom_gen_bd_rx_release(lpbfifo.bcom_rx_task);
0558 
0559     free_irq(lpbfifo.irq, &lpbfifo);
0560     iounmap(lpbfifo.regs);
0561     lpbfifo.regs = NULL;
0562     lpbfifo.dev = NULL;
0563 
0564     return 0;
0565 }
0566 
0567 static const struct of_device_id mpc52xx_lpbfifo_match[] = {
0568     { .compatible = "fsl,mpc5200-lpbfifo", },
0569     {},
0570 };
0571 MODULE_DEVICE_TABLE(of, mpc52xx_lpbfifo_match);
0572 
0573 static struct platform_driver mpc52xx_lpbfifo_driver = {
0574     .driver = {
0575         .name = "mpc52xx-lpbfifo",
0576         .of_match_table = mpc52xx_lpbfifo_match,
0577     },
0578     .probe = mpc52xx_lpbfifo_probe,
0579     .remove = mpc52xx_lpbfifo_remove,
0580 };
0581 module_platform_driver(mpc52xx_lpbfifo_driver);