diff options
author | Terry Lv <r65388@freescale.com> | 2011-05-18 19:02:58 +0800 |
---|---|---|
committer | Lily Zhang <r58066@freescale.com> | 2011-05-19 11:12:00 +0800 |
commit | 860689b3ea9023c02c690d04c9e431d81214fb05 (patch) | |
tree | 1a2fc5497b21fbc370ddca1ad5b2e031bb84d6aa | |
parent | 845634d76c3425741e0aa4598274659e9dee892a (diff) |
ENGR00141131-2: MX53_ARD: MLB can't support 1024fs data transfer
MLB can't support 1024fs data transfer.
Need to enable MLBCLK_IN_INV in IOMUXC.IOMUXC_GPR0.
Signed-off-by: Terry Lv <r65388@freescale.com>
-rw-r--r-- | drivers/mxc/mlb/mxc_mlb.c | 105 | ||||
-rw-r--r-- | include/linux/fsl_devices.h | 8 |
2 files changed, 72 insertions, 41 deletions
diff --git a/drivers/mxc/mlb/mxc_mlb.c b/drivers/mxc/mlb/mxc_mlb.c index f7d5eb395e4d..1ee4a4147d93 100644 --- a/drivers/mxc/mlb/mxc_mlb.c +++ b/drivers/mxc/mlb/mxc_mlb.c @@ -212,14 +212,12 @@ static struct mlb_dev_info mlb_devinfo[MLB_MINOR_DEVICES] = { static struct regulator *reg_nvcc; /* NVCC_MLB regulator */ static struct clk *mlb_clk; -static struct cdev mxc_mlb_dev; /* chareset device */ static dev_t dev; static struct class *mlb_class; /* device class */ static struct device *class_dev; static unsigned long mlb_base; /* mlb module base address */ static unsigned int irq; static unsigned long iram_base; -static __iomem void *iram_addr; /*! * Initial the MLB module device @@ -467,6 +465,11 @@ static irqreturn_t mlb_isr(int irq, void *dev_id) static int mxc_mlb_open(struct inode *inode, struct file *filp) { int minor; + struct mxc_mlb_platform_data *plat_data; + + plat_data = container_of(inode->i_cdev, struct mxc_mlb_platform_data, + cdev); + filp->private_data = plat_data; minor = MINOR(inode->i_rdev); @@ -507,6 +510,7 @@ static int mxc_mlb_ioctl(struct inode *inode, struct file *filp, void __user *argp = (void __user *)arg; unsigned long flags, event; int minor; + struct mxc_mlb_platform_data *plat_data = filp->private_data; minor = MINOR(inode->i_rdev); @@ -567,6 +571,9 @@ static int mxc_mlb_ioctl(struct inode *inode, struct file *filp, return -EFAULT; } + if (plat_data->fps_sel) + plat_data->fps_sel(fps); + /* check fps value */ if (fps != 256 && fps != 512 && fps != 1024) { pr_debug("mxc_mlb: invalid fps argument\n"); @@ -799,6 +806,10 @@ static int __devinit mxc_mlb_probe(struct platform_device *pdev) void __iomem *base, *bufaddr; unsigned long phyaddr; + plat_data = (struct mxc_mlb_platform_data *)pdev->dev.platform_data; + plat_data->dev = &pdev->dev; + + /* malloc the Rx ring buffer firstly */ for (i = 0; i < MLB_MINOR_DEVICES; i++) { char *buf; @@ -812,8 +823,8 @@ static int __devinit mxc_mlb_probe(struct platform_device *pdev) buf = kmalloc(bufsize * RX_RING_NODES, GFP_KERNEL); if (buf == NULL) { ret = -ENOMEM; - dev_err(&pdev->dev, "can not alloc rx buffers\n"); - goto err4; + dev_err(plat_data->dev, "can not alloc rx buffers\n"); + goto err3; } for (j = 0; j < RX_RING_NODES; j++) { mlb_devinfo[i].rx_bufs[j].data = buf; @@ -829,23 +840,23 @@ static int __devinit mxc_mlb_probe(struct platform_device *pdev) mlb_major = MAJOR(dev); if (ret < 0) { - dev_err(&pdev->dev, "can't get major %d\n", mlb_major); - goto err3; + dev_err(plat_data->dev, "can't get major %d\n", mlb_major); + goto err2; } - cdev_init(&mxc_mlb_dev, &mxc_mlb_fops); - mxc_mlb_dev.owner = THIS_MODULE; + cdev_init(&plat_data->cdev, &mxc_mlb_fops); + plat_data->cdev.owner = THIS_MODULE; - ret = cdev_add(&mxc_mlb_dev, dev, MLB_MINOR_DEVICES); + ret = cdev_add(&plat_data->cdev, dev, MLB_MINOR_DEVICES); if (ret) { - dev_err(&pdev->dev, "can't add cdev\n"); + dev_err(plat_data->dev, "can't add cdev\n"); goto err2; } /* create class and device for udev information */ mlb_class = class_create(THIS_MODULE, "mlb"); if (IS_ERR(mlb_class)) { - dev_err(&pdev->dev, "failed to create mlb class\n"); + dev_err(plat_data->dev, "failed to create mlb class\n"); ret = -ENOMEM; goto err2; } @@ -855,7 +866,7 @@ static int __devinit mxc_mlb_probe(struct platform_device *pdev) class_dev = device_create(mlb_class, NULL, MKDEV(mlb_major, i), NULL, mlb_devinfo[i].dev_name); if (IS_ERR(class_dev)) { - dev_err(&pdev->dev, "failed to create mlb %s" + dev_err(plat_data->dev, "failed to create mlb %s" " class device\n", mlb_devinfo[i].dev_name); ret = -ENOMEM; goto err1; @@ -865,14 +876,14 @@ static int __devinit mxc_mlb_probe(struct platform_device *pdev) /* get irq line */ res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); if (res == NULL) { - dev_err(&pdev->dev, "No mlb irq line provided\n"); + dev_err(plat_data->dev, "No mlb irq line provided\n"); goto err1; } irq = res->start; /* request irq */ if (request_irq(irq, mlb_isr, 0, "mlb", NULL)) { - dev_err(&pdev->dev, "failed to request irq\n"); + dev_err(plat_data->dev, "failed to request irq\n"); ret = -EBUSY; goto err1; } @@ -880,16 +891,16 @@ static int __devinit mxc_mlb_probe(struct platform_device *pdev) /* ioremap from phy mlb to kernel space */ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (res == NULL) { - dev_err(&pdev->dev, "No mlb base address provided\n"); + dev_err(plat_data->dev, "No mlb base address provided\n"); goto err0; } base = ioremap(res->start, res->end - res->start); - dev_dbg(&pdev->dev, "mapped mlb base address: 0x%08x\n", + dev_dbg(plat_data->dev, "mapped mlb base address: 0x%08x\n", (unsigned int)base); if (base == NULL) { - dev_err(&pdev->dev, "failed to do ioremap with mlb base\n"); + dev_err(plat_data->dev, "failed to do ioremap with mlb base\n"); goto err0; } mlb_base = (unsigned long)base; @@ -910,11 +921,9 @@ static int __devinit mxc_mlb_probe(struct platform_device *pdev) * | minor n rx buf | * ------------------- */ - - plat_data = (struct mxc_mlb_platform_data *)pdev->dev.platform_data; - - bufaddr = iram_addr = iram_alloc(MLB_IRAM_SIZE, &iram_base); - phyaddr = iram_base; + bufaddr = iram_alloc(MLB_IRAM_SIZE, &iram_base); + plat_data->buf_addr = (unsigned long)bufaddr; + plat_data->phy_addr = phyaddr = iram_base; for (i = 0; i < MLB_MINOR_DEVICES; i++) { /* set the virtual and physical buf head address */ @@ -930,9 +939,9 @@ static int __devinit mxc_mlb_probe(struct platform_device *pdev) bufaddr += RX_CHANNEL_BUF_SIZE; phyaddr += RX_CHANNEL_BUF_SIZE; - dev_dbg(&pdev->dev, "phy_head: tx(%lx), rx(%lx)\n", + dev_dbg(plat_data->dev, "phy_head: tx(%lx), rx(%lx)\n", _get_txchan(i).phy_head, _get_rxchan(i).phy_head); - dev_dbg(&pdev->dev, "buf_head: tx(%lx), rx(%lx)\n", + dev_dbg(plat_data->dev, "buf_head: tx(%lx), rx(%lx)\n", _get_txchan(i).buf_head, _get_rxchan(i).buf_head); } @@ -941,7 +950,7 @@ static int __devinit mxc_mlb_probe(struct platform_device *pdev) if (plat_data->reg_nvcc) { /* power on MLB */ - reg_nvcc = regulator_get(&pdev->dev, plat_data->reg_nvcc); + reg_nvcc = regulator_get(plat_data->dev, plat_data->reg_nvcc); if (!IS_ERR(reg_nvcc)) { /* set MAX LDO6 for NVCC to 2.5V */ regulator_set_voltage(reg_nvcc, 2500000, 2500000); @@ -950,8 +959,10 @@ static int __devinit mxc_mlb_probe(struct platform_device *pdev) } /* enable clock */ - mlb_clk = clk_get(&pdev->dev, plat_data->mlb_clk); - clk_enable(mlb_clk); + if (plat_data->mlb_clk) { + mlb_clk = clk_get(plat_data->dev, plat_data->mlb_clk); + clk_enable(mlb_clk); + } /* initial MLB module */ mlb_dev_init(); @@ -959,17 +970,18 @@ static int __devinit mxc_mlb_probe(struct platform_device *pdev) return 0; err0: - free_irq(irq, NULL); + if (irq) { + free_irq(irq, NULL); + irq = 0; + } err1: for (--i; i >= 0; i--) device_destroy(mlb_class, MKDEV(mlb_major, i)); class_destroy(mlb_class); err2: - cdev_del(&mxc_mlb_dev); -err3: unregister_chrdev_region(dev, MLB_MINOR_DEVICES); -err4: +err3: for (i = 0; i < MLB_MINOR_DEVICES; i++) kfree(mlb_devinfo[i].rx_bufs[0].data); @@ -979,26 +991,42 @@ err4: static int __devexit mxc_mlb_remove(struct platform_device *pdev) { int i; + struct mxc_mlb_platform_data *plat_data; + + plat_data = (struct mxc_mlb_platform_data *)pdev->dev.platform_data; mlb_dev_exit(); /* disable mlb clock */ - clk_disable(mlb_clk); - clk_put(mlb_clk); + if (plat_data->mlb_clk) { + clk_disable(mlb_clk); + clk_put(mlb_clk); + } /* disable mlb power */ - regulator_disable(reg_nvcc); - regulator_put(reg_nvcc); + if (plat_data->reg_nvcc) { + regulator_disable(reg_nvcc); + regulator_put(reg_nvcc); + } /* inactive GPIO */ gpio_mlb_inactive(); - iram_free(iram_base, MLB_IRAM_SIZE); + if (iram_base) { + iram_free(iram_base, MLB_IRAM_SIZE); + iram_base = 0; + } /* iounmap */ - iounmap((void *)mlb_base); + if (mlb_base) { + iounmap((void *)mlb_base); + mlb_base = 0; + } - free_irq(irq, NULL); + if (irq) { + free_irq(irq, NULL); + irq = 0; + } /* destroy mlb device class */ for (i = MLB_MINOR_DEVICES - 1; i >= 0; i--) @@ -1006,7 +1034,6 @@ static int __devexit mxc_mlb_remove(struct platform_device *pdev) class_destroy(mlb_class); /* Unregister the two MLB devices */ - cdev_del(&mxc_mlb_dev); unregister_chrdev_region(dev, MLB_MINOR_DEVICES); for (i = 0; i < MLB_MINOR_DEVICES; i++) diff --git a/include/linux/fsl_devices.h b/include/linux/fsl_devices.h index e1a65397f4cf..e9f249c54338 100644 --- a/include/linux/fsl_devices.h +++ b/include/linux/fsl_devices.h @@ -18,6 +18,7 @@ #define _FSL_DEVICE_H_ #include <linux/types.h> +#include <linux/cdev.h> /* * Some conventions on how we handle peripherals on Freescale chips @@ -458,10 +459,13 @@ struct mxc_gps_platform_data { }; struct mxc_mlb_platform_data { - u32 buf_address; - u32 phy_address; + struct device *dev; + u32 buf_addr; + u32 phy_addr; char *reg_nvcc; char *mlb_clk; + void (*fps_sel)(int mlbfs); + struct cdev cdev; }; struct flexcan_platform_data { |