commit: http://blackfin.uclinux.org/git/?p=linux-kernel;a=commitdiff;h=05d5bc8749ac3a8340fba8aa26674a04cc7e3bda branch: http://blackfin.uclinux.org/git/?p=linux-kernel;a=shortlog;h=refs/heads/trunk
Signed-off-by: Scott Jiang <[email protected]> --- drivers/video/bf609-nl8048.c | 122 ++++++++++++++++++++++++++++++------------ 1 files changed, 87 insertions(+), 35 deletions(-) diff --git a/drivers/video/bf609-nl8048.c b/drivers/video/bf609-nl8048.c index 2082779..e72f870 100644 --- a/drivers/video/bf609-nl8048.c +++ b/drivers/video/bf609-nl8048.c @@ -46,6 +46,7 @@ struct bfin_fb_par { struct bfin_eppi3_regs *reg; const unsigned short *per_fs; const unsigned short *per_data; + int user; }; static const unsigned short eppi0_per_fs[] = { @@ -61,6 +62,28 @@ static const unsigned short eppi0_per_data[] = { 0, }; +static const unsigned short eppi1_per_fs[] = { + P_PPI1_CLK, P_PPI1_FS1, P_PPI1_FS2, 0, +}; +static const unsigned short eppi1_per_data[] = { + P_PPI1_D0, P_PPI1_D1, P_PPI1_D2, P_PPI1_D3, + P_PPI1_D4, P_PPI1_D5, P_PPI1_D6, P_PPI1_D7, + P_PPI1_D8, P_PPI1_D9, P_PPI1_D10, P_PPI1_D11, + P_PPI1_D12, P_PPI1_D13, P_PPI1_D14, P_PPI1_D15, + P_PPI1_D16, P_PPI1_D17, 0, +}; + +static const unsigned short eppi2_per_fs[] = { + P_PPI2_CLK, P_PPI2_FS1, P_PPI2_FS2, 0, +}; +static const unsigned short eppi2_per_data[] = { + P_PPI2_D0, P_PPI2_D1, P_PPI2_D2, P_PPI2_D3, + P_PPI2_D4, P_PPI2_D5, P_PPI2_D6, P_PPI2_D7, + P_PPI2_D8, P_PPI2_D9, P_PPI2_D10, P_PPI2_D11, + P_PPI2_D12, P_PPI2_D13, P_PPI2_D14, P_PPI2_D15, + P_PPI2_D16, P_PPI2_D17, 0, +}; + static struct fb_fix_screeninfo bfin_fb_fix __devinitdata = { .id = KBUILD_MODNAME, .type = FB_TYPE_PACKED_PIXELS, @@ -348,34 +371,35 @@ static irqreturn_t eppi_irq_err(int irq, void *dev_id) static int bfin_fb_open(struct fb_info *info, int user) { struct bfin_fb_par *par = info->par; - int usr; int ret; - usr = atomic_read(&info->count); - ret = request_dma(par->dma_ch, "EPPI DMA"); - if (ret) { - dev_err(info->dev, "Can't allocate DMA channel for EPPI\n"); - return ret; - } - - ret = request_irq(par->irq_err, eppi_irq_err, 0, "EPPI ERROR", info); - if (ret) { - dev_err(info->dev, "Can't allocate IRQ for EPPI\n"); - goto err; + if (!par->user) { + ret = request_dma(par->dma_ch, "EPPI DMA"); + if (ret) { + dev_err(info->dev, "Can't allocate DMA channel for EPPI\n"); + return ret; + } + + ret = request_irq(par->irq_err, eppi_irq_err, 0, "EPPI ERROR", info); + if (ret) { + dev_err(info->dev, "Can't allocate IRQ for EPPI\n"); + goto err; + } + + ret = peripheral_request_list(par->per_fs, KBUILD_MODNAME); + if (ret) { + dev_err(info->dev, "Can't request FS pins\n"); + goto err1; + } + + ret = peripheral_request_list(par->per_data, KBUILD_MODNAME); + if (ret) { + dev_err(info->dev, "Can't request DATA pins\n"); + goto err2; + } + start_ppi(info); } - - ret = peripheral_request_list(par->per_fs, KBUILD_MODNAME); - if (ret) { - dev_err(info->dev, "Can't request FS pins\n"); - goto err1; - } - - ret = peripheral_request_list(par->per_data, KBUILD_MODNAME); - if (ret) { - dev_err(info->dev, "Can't request DATA pins\n"); - goto err2; - } - start_ppi(info); + par->user++; return 0; err2: peripheral_free_list(par->per_fs); @@ -391,11 +415,14 @@ static int bfin_fb_release(struct fb_info *info, int user) { struct bfin_fb_par *par = info->par; - stop_ppi(info); - peripheral_free_list(par->per_data); - peripheral_free_list(par->per_fs); - free_irq(par->irq_err, info); - free_dma(par->dma_ch); + par->user--; + if (!par->user) { + stop_ppi(info); + peripheral_free_list(par->per_data); + peripheral_free_list(par->per_fs); + free_irq(par->irq_err, info); + free_dma(par->dma_ch); + } return 0; } @@ -455,11 +482,36 @@ static int __devinit bfin_nl8048_probe(struct platform_device *pdev) if (!info) return -ENOMEM; par = info->par; - par->dma_ch = CH_EPPI0_CH0; - par->irq_err = IRQ_EPPI0_STAT; - par->reg = (struct bfin_eppi3_regs *)EPPI0_STAT; - par->per_fs = eppi0_per_fs; - par->per_data = eppi0_per_data; + + switch (pdev->id) { + case 0: + par->dma_ch = CH_EPPI0_CH0; + par->irq_err = IRQ_EPPI0_STAT; + par->reg = (struct bfin_eppi3_regs *)EPPI0_STAT; + par->per_fs = eppi0_per_fs; + par->per_data = eppi0_per_data; + break; + case 1: + par->dma_ch = CH_EPPI1_CH0; + par->irq_err = IRQ_EPPI1_STAT; + par->reg = (struct bfin_eppi3_regs *)EPPI1_STAT; + par->per_fs = eppi1_per_fs; + par->per_data = eppi1_per_data; + break; + case 2: + par->dma_ch = CH_EPPI2_CH0; + par->irq_err = IRQ_EPPI2_STAT; + par->reg = (struct bfin_eppi3_regs *)EPPI2_STAT; + par->per_fs = eppi2_per_fs; + par->per_data = eppi2_per_data; + break; + default: + dev_err(&pdev->dev, "PPI instance [%d] is out of range\n", + pdev->id); + ret = -ENODEV; + goto err; + } + par->user = 0; info->screen_base = dma_alloc_coherent(NULL, MEM_SIZE, &dma_handle, GFP_KERNEL);
_______________________________________________ Linux-kernel-commits mailing list [email protected] https://blackfin.uclinux.org/mailman/listinfo/linux-kernel-commits
