On 05/31/2013 03:41 PM, Timur Tabi wrote: > On 05/31/2013 08:37 AM, Michal Simek wrote: >> The same is for Microblaze. Driver shares fb_virt for IO memory >> and for allocated memory. The purpose of this driver wasn't >> to change the driver logic just resolved sparse warnings. >> The other way is also wrong. >> I have compiled this driver with ppc toolchain and it should >> remove sparse warnings for PPC. > > But it's not I/O memory. It's regular memory. __iomem is for > memory-mapped I/O, which is limited to a specific range of memory locations. > > If sometimes you use regular memory for the framebuffer, and other times > you use real I/O memory for the framebuffer, then you should have two > different pointers. I agree with you and if you like I can change it. But there will be at least one retype because dma_alloc_coherent returns void * but struct fb_info expects that pointer is __iomem (char __iomem *screen_base). Patch is below. Thanks, Michal diff --git a/drivers/video/xilinxfb.c b/drivers/video/xilinxfb.c index f3d4a69..885f294 100644 --- a/drivers/video/xilinxfb.c +++ b/drivers/video/xilinxfb.c @@ -132,8 +132,8 @@ struct xilinxfb_drvdata { unsigned int dcr_len; #endif void *fb_virt; /* virt. address of the frame buffer */ + void __iomem *fb_virt_io; /* virt. address of the frame buffer */ dma_addr_t fb_phys; /* phys. address of the frame buffer */ - int fb_alloced; /* Flag, was the fb memory alloced? */ u8 flags; /* features of the driver */ @@ -270,24 +270,36 @@ static int xilinxfb_assign(struct platform_device *pdev, /* Allocate the framebuffer memory */ if (pdata->fb_phys) { drvdata->fb_phys = pdata->fb_phys; - drvdata->fb_virt = ioremap(pdata->fb_phys, fbsize); + drvdata->fb_virt_io = ioremap(pdata->fb_phys, fbsize); + + if (!drvdata->fb_virt_io) { + dev_err(dev, "Could not allocate frame buffer memory\n"); + rc = -ENOMEM; + if (drvdata->flags & BUS_ACCESS_FLAG) + goto err_fbmem; + else + goto err_region; + } + + /* Clear (turn to black) the framebuffer */ + memset_io(drvdata->fb_virt_io, 0, fbsize); } else { - drvdata->fb_alloced = 1; drvdata->fb_virt = dma_alloc_coherent(dev, PAGE_ALIGN(fbsize), &drvdata->fb_phys, GFP_KERNEL); - } - if (!drvdata->fb_virt) { - dev_err(dev, "Could not allocate frame buffer memory\n"); - rc = -ENOMEM; - if (drvdata->flags & BUS_ACCESS_FLAG) - goto err_fbmem; - else - goto err_region; + if (!drvdata->fb_virt_io) { + dev_err(dev, "Could not allocate frame buffer memory\n"); + rc = -ENOMEM; + if (drvdata->flags & BUS_ACCESS_FLAG) + goto err_fbmem; + else + goto err_region; + memset(drvdata->fb_virt, 0, fbsize); } - /* Clear (turn to black) the framebuffer */ - memset_io((void __iomem *)drvdata->fb_virt, 0, fbsize); + /* Tell the hardware where the frame buffer is */ xilinx_fb_out32(drvdata, REG_FB_ADDR, drvdata->fb_phys); @@ -307,7 +319,11 @@ static int xilinxfb_assign(struct platform_device *pdev, /* Fill struct fb_info */ drvdata->info.device = dev; - drvdata->info.screen_base = (void __iomem *)drvdata->fb_virt; + if (drvdata->fb_virt) + drvdata->info.screen_base = (__force void __iomem *) + drvdata->fb_virt; + else + drvdata->info.screen_base = drvdata->fb_virt_io; drvdata->info.fbops = &xilinxfb_ops; drvdata->info.fix = xilinx_fb_fix; drvdata->info.fix.smem_start = drvdata->fb_phys; @@ -341,8 +357,8 @@ static int xilinxfb_assign(struct platform_device *pdev, if (drvdata->flags & BUS_ACCESS_FLAG) { /* Put a banner in the log (for DEBUG) */ - dev_dbg(dev, "regs: phys=%x, virt=%p\n", drvdata->regs_phys, - drvdata->regs); + dev_dbg(dev, "regs: phys=%x, virt=%p\n", + (u32)drvdata->regs_phys, drvdata->regs); } /* Put a banner in the log (for DEBUG) */ dev_dbg(dev, "fb: phys=%llx, virt=%p, size=%x\n", @@ -354,11 +370,11 @@ err_regfb: fb_dealloc_cmap(&drvdata->info.cmap); err_cmap: - if (drvdata->fb_alloced) + if (drvdata->fb_virt) dma_free_coherent(dev, PAGE_ALIGN(fbsize), drvdata->fb_virt, drvdata->fb_phys); else - iounmap(drvdata->fb_virt); + iounmap(drvdata->fb_virt_io); /* Turn off the display */ xilinx_fb_out32(drvdata, REG_CTRL, 0); @@ -386,11 +402,11 @@ static int xilinxfb_release(struct device *dev) fb_dealloc_cmap(&drvdata->info.cmap); - if (drvdata->fb_alloced) + if (drvdata->fb_virt) dma_free_coherent(dev, PAGE_ALIGN(drvdata->info.fix.smem_len), drvdata->fb_virt, drvdata->fb_phys); else - iounmap(drvdata->fb_virt); + iounmap(drvdata->fb_virt_io); /* Turn off the display */ xilinx_fb_out32(drvdata, REG_CTRL, 0); -- Michal Simek, Ing. (M.Eng), OpenPGP -> KeyID: FE3D1F91 w: www.monstr.eu p: +42-0-721842854 Maintainer of Linux kernel - Microblaze cpu - http://www.monstr.eu/fdt/ Maintainer of Linux kernel - Xilinx Zynq ARM architecture Microblaze U-BOOT custodian and responsible for u-boot arm zynq platform
Attachment:
signature.asc
Description: OpenPGP digital signature