From f1edfc420ac7beb90b27bf822036cbbfa32483f1 Mon Sep 17 00:00:00 2001 From: Jaya Kumar Date: Sun, 22 Jun 2008 04:27:25 +0100 Subject: [ARM] 5115/1: pxafb: fix ifdef for command line option handling This bug was found and fixed by Lothar Wassmann. Previously, the use of ifndef CONFIG_MODULES made it such that pxafb command line option parsing was dependent on whether the kernel was built with module support. The ifndef should be MODULE so that parsing is dependent only on whether the driver is built-in or not. Signed-off-by: Jaya Kumar Acked-by: Krzysztof Helt Acked-by: Eric Miao Signed-off-by: Russell King --- drivers/video/pxafb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/video') diff --git a/drivers/video/pxafb.c b/drivers/video/pxafb.c index 7dcda187d9b..eb23d192333 100644 --- a/drivers/video/pxafb.c +++ b/drivers/video/pxafb.c @@ -1588,7 +1588,7 @@ static int __init pxafb_parse_options(struct device *dev, char *options) static char g_options[256] __devinitdata = ""; -#ifndef CONFIG_MODULES +#ifndef MODULE static int __devinit pxafb_setup_options(void) { char *options = NULL; -- cgit v1.2.3 From ee98476bbc565f8fe42e198602e647288b6a258d Mon Sep 17 00:00:00 2001 From: Jaya Kumar Date: Sun, 22 Jun 2008 04:27:26 +0100 Subject: [ARM] 5116/1: pxafb: cleanup and fix order of failure handling This issue was found by Krzysztof Helt and Eric Miao. pxafb had issues in the order with which it cleaned up if errors occurred during a probe. This patch reorders the failure handling sequence and also frees the cmap and clk. Signed-off-by: Jaya Kumar Acked-by: Krzysztof Helt Acked-by: Eric Miao Signed-off-by: Russell King --- drivers/video/pxafb.c | 34 ++++++++++++++++++++++++---------- 1 file changed, 24 insertions(+), 10 deletions(-) (limited to 'drivers/video') diff --git a/drivers/video/pxafb.c b/drivers/video/pxafb.c index eb23d192333..796e0d1d5b1 100644 --- a/drivers/video/pxafb.c +++ b/drivers/video/pxafb.c @@ -1685,14 +1685,14 @@ static int __init pxafb_probe(struct platform_device *dev) if (r == NULL) { dev_err(&dev->dev, "no I/O memory resource defined\n"); ret = -ENODEV; - goto failed; + goto failed_fbi; } r = request_mem_region(r->start, r->end - r->start + 1, dev->name); if (r == NULL) { dev_err(&dev->dev, "failed to request I/O memory\n"); ret = -EBUSY; - goto failed; + goto failed_fbi; } fbi->mmio_base = ioremap(r->start, r->end - r->start + 1); @@ -1735,8 +1735,17 @@ static int __init pxafb_probe(struct platform_device *dev) * This makes sure that our colour bitfield * descriptors are correctly initialised. */ - pxafb_check_var(&fbi->fb.var, &fbi->fb); - pxafb_set_par(&fbi->fb); + ret = pxafb_check_var(&fbi->fb.var, &fbi->fb); + if (ret) { + dev_err(&dev->dev, "failed to get suitable mode\n"); + goto failed_free_irq; + } + + ret = pxafb_set_par(&fbi->fb); + if (ret) { + dev_err(&dev->dev, "Failed to set parameters\n"); + goto failed_free_irq; + } platform_set_drvdata(dev, fbi); @@ -1744,7 +1753,7 @@ static int __init pxafb_probe(struct platform_device *dev) if (ret < 0) { dev_err(&dev->dev, "Failed to register framebuffer device: %d\n", ret); - goto failed_free_irq; + goto failed_free_cmap; } #ifdef CONFIG_CPU_FREQ @@ -1763,18 +1772,23 @@ static int __init pxafb_probe(struct platform_device *dev) return 0; +failed_free_cmap: + if (fbi->fb.cmap.len) + fb_dealloc_cmap(&fbi->fb.cmap); failed_free_irq: free_irq(irq, fbi); -failed_free_res: - release_mem_region(r->start, r->end - r->start + 1); -failed_free_io: - iounmap(fbi->mmio_base); failed_free_mem: dma_free_writecombine(&dev->dev, fbi->map_size, fbi->map_cpu, fbi->map_dma); -failed: +failed_free_io: + iounmap(fbi->mmio_base); +failed_free_res: + release_mem_region(r->start, r->end - r->start + 1); +failed_fbi: + clk_put(fbi->clk); platform_set_drvdata(dev, NULL); kfree(fbi); +failed: return ret; } -- cgit v1.2.3 From 9e6c29768fc05d32ba1342b9348957b24bc476c2 Mon Sep 17 00:00:00 2001 From: Jaya Kumar Date: Sun, 22 Jun 2008 04:27:27 +0100 Subject: [ARM] 5117/1: pxafb: fix __devinit/exit annotations This patch fixes pxafb's init/exit annotations. It uses __devinit/exit for probe functions and __init for init functions. g_options is left as __devinitdata since it is used by both. Signed-off-by: Jaya Kumar Acked-by: Krzysztof Helt Acked-by: Eric Miao Signed-off-by: Russell King --- drivers/video/pxafb.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'drivers/video') diff --git a/drivers/video/pxafb.c b/drivers/video/pxafb.c index 796e0d1d5b1..fafe7db20d6 100644 --- a/drivers/video/pxafb.c +++ b/drivers/video/pxafb.c @@ -1246,7 +1246,7 @@ static int pxafb_resume(struct platform_device *dev) * cache. Once this area is remapped, all virtual memory * access to the video memory should occur at the new region. */ -static int __init pxafb_map_video_memory(struct pxafb_info *fbi) +static int __devinit pxafb_map_video_memory(struct pxafb_info *fbi) { /* * We reserve one page for the palette, plus the size @@ -1348,7 +1348,7 @@ decode_mode: pxafb_decode_mode_info(fbi, inf->modes, inf->num_modes); } -static struct pxafb_info * __init pxafb_init_fbinfo(struct device *dev) +static struct pxafb_info * __devinit pxafb_init_fbinfo(struct device *dev) { struct pxafb_info *fbi; void *addr; @@ -1410,7 +1410,7 @@ static struct pxafb_info * __init pxafb_init_fbinfo(struct device *dev) } #ifdef CONFIG_FB_PXA_PARAMETERS -static int __init parse_opt_mode(struct device *dev, const char *this_opt) +static int __devinit parse_opt_mode(struct device *dev, const char *this_opt) { struct pxafb_mach_info *inf = dev->platform_data; @@ -1469,7 +1469,7 @@ done: return 0; } -static int __init parse_opt(struct device *dev, char *this_opt) +static int __devinit parse_opt(struct device *dev, char *this_opt) { struct pxafb_mach_info *inf = dev->platform_data; struct pxafb_mode_info *mode = &inf->modes[0]; @@ -1567,7 +1567,7 @@ static int __init parse_opt(struct device *dev, char *this_opt) return 0; } -static int __init pxafb_parse_options(struct device *dev, char *options) +static int __devinit pxafb_parse_options(struct device *dev, char *options) { char *this_opt; int ret; @@ -1589,7 +1589,7 @@ static int __init pxafb_parse_options(struct device *dev, char *options) static char g_options[256] __devinitdata = ""; #ifndef MODULE -static int __devinit pxafb_setup_options(void) +static int __init pxafb_setup_options(void) { char *options = NULL; @@ -1613,7 +1613,7 @@ MODULE_PARM_DESC(options, "LCD parameters (see Documentation/fb/pxafb.txt)"); #define pxafb_setup_options() (0) #endif -static int __init pxafb_probe(struct platform_device *dev) +static int __devinit pxafb_probe(struct platform_device *dev) { struct pxafb_info *fbi; struct pxafb_mach_info *inf; @@ -1801,7 +1801,7 @@ static struct platform_driver pxafb_driver = { }, }; -static int __devinit pxafb_init(void) +static int __init pxafb_init(void) { if (pxafb_setup_options()) return -EINVAL; -- cgit v1.2.3 From 05946bce839b4fed5442dbfab77060fb75e051f3 Mon Sep 17 00:00:00 2001 From: Anton Vorontsov Date: Fri, 4 Jul 2008 09:59:38 -0700 Subject: fsl_diu_fb: fix build with CONFIG_PM=y, plus fix some warnings This patch fixes following build error when CONFIG_PM is set. CC drivers/video/fsl-diu-fb.o drivers/video/fsl-diu-fb.c: In function 'fsl_diu_suspend': drivers/video/fsl-diu-fb.c:1327: error: 'ofdev' undeclared (first use in this function) drivers/video/fsl-diu-fb.c:1327: error: (Each undeclared identifier is reported only once drivers/video/fsl-diu-fb.c:1327: error: for each function it appears in.) drivers/video/fsl-diu-fb.c: In function 'fsl_diu_resume': drivers/video/fsl-diu-fb.c:1337: error: 'ofdev' undeclared (first use in this function) While I'm at it, also fix this warning: drivers/video/fsl-diu-fb.c: In function 'fsl_diu_alloc': drivers/video/fsl-diu-fb.c:314: warning: format '%lx' expects type 'long unsigned int', but argument 3 has type 'phys_addr_t' And these section mismatches: ..from the function fsl_diu_remove() to the function .exit.text:uninstall_fb() ..from the function fsl_diu_remove() to the function .exit.text:uninstall_fb() ..from the function install_fb() to the variable .devinit.data:fsl_diu_mode_db ..from the function install_fb() to the variable .devinit.data:fsl_diu_mode_db ..from the function fsl_diu_probe() to the function .exit.text:uninstall_fb() ..from the function fsl_diu_probe() to the function .exit.text:uninstall_fb() Also, some sparse fixes: make two functions static, and use NULL where appropriate. There are still a lot of sparse warnings, mainly wrt absence of __iomem annotations, but some will require ugly __force stuff. I'll leave them for now, since proper fix would be not that trivial as few one-liners below. Signed-off-by: Anton Vorontsov Cc: Timur Tabi Cc: Antonino Daplas Cc: York Sun Cc: Krzysztof Helt Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/video/fsl-diu-fb.c | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) (limited to 'drivers/video') diff --git a/drivers/video/fsl-diu-fb.c b/drivers/video/fsl-diu-fb.c index 0a2785361ca..712dabc6269 100644 --- a/drivers/video/fsl-diu-fb.c +++ b/drivers/video/fsl-diu-fb.c @@ -286,7 +286,7 @@ static struct diu_pool pool; * rheap and make the furture large allocation fail. */ -void *fsl_diu_alloc(unsigned long size, phys_addr_t *phys) +static void *fsl_diu_alloc(unsigned long size, phys_addr_t *phys) { void *virt; @@ -311,12 +311,12 @@ void *fsl_diu_alloc(unsigned long size, phys_addr_t *phys) memset(virt, 0, size); } - pr_debug("rh virt=%p phys=%lx\n", virt, *phys); + pr_debug("rh virt=%p phys=%llx\n", virt, (unsigned long long)*phys); return virt; } -void fsl_diu_free(void *p, unsigned long size) +static void fsl_diu_free(void *p, unsigned long size) { pr_debug("p=%p size=%lu\n", p, size); @@ -770,7 +770,7 @@ static int map_video_memory(struct fb_info *info) info->fix.smem_len = info->fix.line_length * info->var.yres_virtual; pr_debug("MAP_VIDEO_MEMORY: smem_len = %d\n", info->fix.smem_len); info->screen_base = fsl_diu_alloc(info->fix.smem_len, &phys); - if (info->screen_base == 0) { + if (info->screen_base == NULL) { printk(KERN_ERR "Unable to allocate fb memory\n"); return -ENOMEM; } @@ -788,7 +788,7 @@ static int map_video_memory(struct fb_info *info) static void unmap_video_memory(struct fb_info *info) { fsl_diu_free(info->screen_base, info->fix.smem_len); - info->screen_base = 0; + info->screen_base = NULL; info->fix.smem_start = 0; info->fix.smem_len = 0; } @@ -1158,7 +1158,7 @@ static int init_fbinfo(struct fb_info *info) return 0; } -static int install_fb(struct fb_info *info) +static int __devinit install_fb(struct fb_info *info) { int rc; struct mfb_info *mfbi = info->par; @@ -1233,7 +1233,7 @@ static int install_fb(struct fb_info *info) return 0; } -static void __exit uninstall_fb(struct fb_info *info) +static void uninstall_fb(struct fb_info *info) { struct mfb_info *mfbi = info->par; @@ -1287,7 +1287,7 @@ static int request_irq_local(int irq) /* Read to clear the status */ status = in_be32(&hw->int_status); - ret = request_irq(irq, fsl_diu_isr, 0, "diu", 0); + ret = request_irq(irq, fsl_diu_isr, 0, "diu", NULL); if (ret) pr_info("Request diu IRQ failed.\n"); else { @@ -1312,7 +1312,7 @@ static void free_irq_local(int irq) /* Disable all LCDC interrupt */ out_be32(&hw->int_mask, 0x1f); - free_irq(irq, 0); + free_irq(irq, NULL); } #ifdef CONFIG_PM @@ -1324,7 +1324,7 @@ static int fsl_diu_suspend(struct of_device *ofdev, pm_message_t state) { struct fsl_diu_data *machine_data; - machine_data = dev_get_drvdata(&ofdev->dev); + machine_data = dev_get_drvdata(&dev->dev); disable_lcdc(machine_data->fsl_diu_info[0]); return 0; @@ -1334,7 +1334,7 @@ static int fsl_diu_resume(struct of_device *ofdev) { struct fsl_diu_data *machine_data; - machine_data = dev_get_drvdata(&ofdev->dev); + machine_data = dev_get_drvdata(&dev->dev); enable_lcdc(machine_data->fsl_diu_info[0]); return 0; @@ -1353,7 +1353,8 @@ static int allocate_buf(struct diu_addr *buf, u32 size, u32 bytes_align) dma_addr_t paddr = 0; ssize = size + bytes_align; - buf->vaddr = dma_alloc_coherent(0, ssize, &paddr, GFP_DMA | __GFP_ZERO); + buf->vaddr = dma_alloc_coherent(NULL, ssize, &paddr, GFP_DMA | + __GFP_ZERO); if (!buf->vaddr) return -ENOMEM; @@ -1371,7 +1372,7 @@ static int allocate_buf(struct diu_addr *buf, u32 size, u32 bytes_align) static void free_buf(struct diu_addr *buf, u32 size, u32 bytes_align) { - dma_free_coherent(0, size + bytes_align, + dma_free_coherent(NULL, size + bytes_align, buf->vaddr, (buf->paddr - buf->offset)); return; } @@ -1411,7 +1412,7 @@ static ssize_t show_monitor(struct device *device, return diu_ops.show_monitor_port(machine_data->monitor_port, buf); } -static int fsl_diu_probe(struct of_device *ofdev, +static int __devinit fsl_diu_probe(struct of_device *ofdev, const struct of_device_id *match) { struct device_node *np = ofdev->node; -- cgit v1.2.3 From e5dd3cbd81aad69bdf773ab63c06fbaabc2b767a Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Fri, 4 Jul 2008 09:59:52 -0700 Subject: w100fb: do not depend on SHARPSL Apart from Sharp SL-Cxx series, there are a few other devices that have ATI Imageon chips, among them HP iPAQ hx4700. Signed-off-by: Philipp Zabel Acked-by: Ian Molton Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/video/Kconfig | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers/video') diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig index 002b61b4f0f..e0c5f96b273 100644 --- a/drivers/video/Kconfig +++ b/drivers/video/Kconfig @@ -1825,12 +1825,13 @@ config FB_FSL_DIU config FB_W100 tristate "W100 frame buffer support" - depends on FB && PXA_SHARPSL + depends on FB && ARCH_PXA select FB_CFB_FILLRECT select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT ---help--- Frame buffer driver for the w100 as found on the Sharp SL-Cxx series. + It can also drive the w3220 chip found on iPAQ hx4700. This driver is also available as a module ( = code which can be inserted and removed from the running kernel whenever you want). The -- cgit v1.2.3 From 27c8d95f8c9ff83e4e4d8a90523d891427964c79 Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Fri, 4 Jul 2008 09:59:53 -0700 Subject: w100fb: add 80 MHz modeline This is needed for HTC Blueangel (w3200). At 96MHz its screen flickers. Signed-off-by: Philipp Zabel Acked-by: Ian Molton Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/video/w100fb.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/video') diff --git a/drivers/video/w100fb.c b/drivers/video/w100fb.c index 30469bf906e..d0674f1e3f1 100644 --- a/drivers/video/w100fb.c +++ b/drivers/video/w100fb.c @@ -1003,6 +1003,7 @@ static struct w100_pll_info xtal_14318000[] = { static struct w100_pll_info xtal_16000000[] = { /*freq M N_int N_fac tfgoal lock_time */ { 72, 1, 8, 0, 0xe0, 48}, /* tfgoal guessed */ + { 80, 1, 9, 0, 0xe0, 13}, /* tfgoal guessed */ { 95, 1, 10, 7, 0xe0, 38}, /* tfgoal guessed */ { 96, 1, 11, 0, 0xe0, 36}, /* tfgoal guessed */ { 0, 0, 0, 0, 0, 0}, -- cgit v1.2.3 From 48948a3e237ff47823d414704aeb8604a4c61ad0 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 8 Jul 2008 18:41:17 +0200 Subject: Fix broken fix for fsl-diu-db On 2.6.26-rc9, the commit 05946bce839b4fed5442dbfab77060fb75e051f3 ("fsl_diu_fb: fix build with CONFIG_PM=y, plus fix some warnings") breaks its previous fix f969c5672b16b857e5231ad3c78f08d8ef3305aa ("fsl-diu-db: compile fix") This patch reverts the broken part. Signed-off-by: Takashi Iwai Acked-by: Anton Vorontsov Signed-off-by: Linus Torvalds --- drivers/video/fsl-diu-fb.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/video') diff --git a/drivers/video/fsl-diu-fb.c b/drivers/video/fsl-diu-fb.c index 712dabc6269..09d7e22c6fe 100644 --- a/drivers/video/fsl-diu-fb.c +++ b/drivers/video/fsl-diu-fb.c @@ -1324,7 +1324,7 @@ static int fsl_diu_suspend(struct of_device *ofdev, pm_message_t state) { struct fsl_diu_data *machine_data; - machine_data = dev_get_drvdata(&dev->dev); + machine_data = dev_get_drvdata(&ofdev->dev); disable_lcdc(machine_data->fsl_diu_info[0]); return 0; @@ -1334,7 +1334,7 @@ static int fsl_diu_resume(struct of_device *ofdev) { struct fsl_diu_data *machine_data; - machine_data = dev_get_drvdata(&dev->dev); + machine_data = dev_get_drvdata(&ofdev->dev); enable_lcdc(machine_data->fsl_diu_info[0]); return 0; -- cgit v1.2.3 From f31ad92f34913043cf008d6e479e92dfbaf02df1 Mon Sep 17 00:00:00 2001 From: Jaya Kumar Date: Sat, 12 Jul 2008 13:47:51 -0700 Subject: fbdev: bugfix for multiprocess defio This patch is a bugfix for how defio handles multiple processes manipulating the same framebuffer. Thanks to Bernard Blackham for identifying this bug. It occurs when two applications mmap the same framebuffer and concurrently write to the same page. Normally, this doesn't occur since only a single process mmaps the framebuffer. The symptom of the bug is that the mapping applications will hang. The cause is that defio incorrectly tries to add the same page twice to the pagelist. The solution I have is to walk the pagelist and check for a duplicate before adding. Since I needed to walk the pagelist, I now also keep the pagelist in sorted order. Signed-off-by: Jaya Kumar Cc: Bernard Blackham Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/video/fb_defio.c | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) (limited to 'drivers/video') diff --git a/drivers/video/fb_defio.c b/drivers/video/fb_defio.c index 24843fdd539..59df132cc37 100644 --- a/drivers/video/fb_defio.c +++ b/drivers/video/fb_defio.c @@ -74,6 +74,7 @@ static int fb_deferred_io_mkwrite(struct vm_area_struct *vma, { struct fb_info *info = vma->vm_private_data; struct fb_deferred_io *fbdefio = info->fbdefio; + struct page *cur; /* this is a callback we get when userspace first tries to write to the page. we schedule a workqueue. that workqueue @@ -83,7 +84,24 @@ static int fb_deferred_io_mkwrite(struct vm_area_struct *vma, /* protect against the workqueue changing the page list */ mutex_lock(&fbdefio->lock); - list_add(&page->lru, &fbdefio->pagelist); + + /* we loop through the pagelist before adding in order + to keep the pagelist sorted */ + list_for_each_entry(cur, &fbdefio->pagelist, lru) { + /* this check is to catch the case where a new + process could start writing to the same page + through a new pte. this new access can cause the + mkwrite even when the original ps's pte is marked + writable */ + if (unlikely(cur == page)) + goto page_already_added; + else if (cur->index > page->index) + break; + } + + list_add_tail(&page->lru, &cur->lru); + +page_already_added: mutex_unlock(&fbdefio->lock); /* come back after delay to process the deferred IO */ -- cgit v1.2.3